From bfe522304da217296e2a61040f58e35ec5d6f3f2 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 16 Aug 2021 09:51:46 +0200 Subject: New upstream version 1.30.6 --- src/core/dhcp/nm-dhcp-client.c | 7 +++++- src/core/dhcp/nm-dhcp-client.h | 2 +- src/core/dhcp/nm-dhcp-dhcpcd.c | 42 +++++++++++++++++++----------------- src/core/dhcp/nm-dhcp-nettools.c | 29 +++++++++++++------------ src/core/dhcp/nm-dhcp-systemd.c | 46 ++++++++++++++++++++-------------------- src/core/dhcp/nm-dhcp-utils.c | 2 +- 6 files changed, 69 insertions(+), 59 deletions(-) (limited to 'src/core/dhcp') diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index c38c814e..3b0343fd 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -84,6 +84,11 @@ G_DEFINE_ABSTRACT_TYPE(NMDhcpClient, nm_dhcp_client, G_TYPE_OBJECT) /*****************************************************************************/ +/* we use pid=-1 for invalid PIDs. Ensure that pid_t can hold negative values. */ +G_STATIC_ASSERT(!(((pid_t) -1) > 0)); + +/*****************************************************************************/ + pid_t nm_dhcp_client_get_pid(NMDhcpClient *self) { @@ -749,7 +754,7 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release) _LOGI("canceled DHCP transaction"); nm_assert(priv->pid == -1); - nm_dhcp_client_set_state(self, NM_DHCP_STATE_DONE, NULL, NULL); + nm_dhcp_client_set_state(self, NM_DHCP_STATE_TERMINATED, NULL, NULL); } /*****************************************************************************/ diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index 72ab477d..af3406cc 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -51,7 +51,7 @@ typedef enum { NM_DHCP_STATE_BOUND, /* new lease */ NM_DHCP_STATE_EXTENDED, /* lease extended */ NM_DHCP_STATE_TIMEOUT, /* timed out contacting server */ - NM_DHCP_STATE_DONE, /* client quit or stopped */ + NM_DHCP_STATE_DONE, /* client reported it's stopping */ NM_DHCP_STATE_EXPIRE, /* lease expired or NAKed */ NM_DHCP_STATE_FAIL, /* failed for some reason */ NM_DHCP_STATE_TERMINATED, /* client is no longer running */ diff --git a/src/core/dhcp/nm-dhcp-dhcpcd.c b/src/core/dhcp/nm-dhcp-dhcpcd.c index cf9fe5c2..cdb266ed 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcd.c +++ b/src/core/dhcp/nm-dhcp-dhcpcd.c @@ -169,27 +169,29 @@ stop(NMDhcpClient *client, gboolean release) int sig, errsv; pid = nm_dhcp_client_get_pid(client); - sig = release ? SIGALRM : SIGTERM; - _LOGD("sending %s to dhcpcd pid %d", sig == SIGALRM ? "SIGALRM" : "SIGTERM", pid); - - /* dhcpcd-9.x features privilege separation. - * It's not our job to track all these processes so we rely on dhcpcd - * to always cleanup after itself. - * Because it also re-parents itself to PID 1, the process cannot be - * reaped or waited for. - * As such, just send the correct signal. - */ - if (kill(pid, sig) == -1) { - errsv = errno; - _LOGE("failed to kill dhcpcd %d:%s", errsv, strerror(errsv)); - } + if (pid > 1) { + sig = release ? SIGALRM : SIGTERM; + _LOGD("sending %s to dhcpcd pid %d", sig == SIGALRM ? "SIGALRM" : "SIGTERM", pid); + + /* dhcpcd-9.x features privilege separation. + * It's not our job to track all these processes so we rely on dhcpcd + * to always cleanup after itself. + * Because it also re-parents itself to PID 1, the process cannot be + * reaped or waited for. + * As such, just send the correct signal. + */ + if (kill(pid, sig) == -1) { + errsv = errno; + _LOGE("failed to kill dhcpcd %d:%s", errsv, strerror(errsv)); + } - /* When this function exits NM expects the PID to be -1. - * This means we also need to stop watching the pid. - * If we need to know the exit status then we need to refactor NM - * to allow a non -1 to mean we're waiting to exit still. - */ - nm_dhcp_client_stop_watch_child(client, pid); + /* When this function exits NM expects the PID to be -1. + * This means we also need to stop watching the pid. + * If we need to know the exit status then we need to refactor NM + * to allow a non -1 to mean we're waiting to exit still. + */ + nm_dhcp_client_stop_watch_child(client, pid); + } } /*****************************************************************************/ diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 116e1bdb..c8b80ea6 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -342,16 +342,16 @@ lease_parse_routes(NDhcp4ClientLease *lease, const guint8 *l_data; gsize l_data_len; int r; + guint i; - r = _client_lease_query(lease, - NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE, - &l_data, - &l_data_len); - if (r == 0) { - nm_str_buf_reset(sbuf); + for (i = 0; i < 2; i++) { + const guint8 option_code = (i == 0) ? NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE + : NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE; - has_classless = TRUE; + if (_client_lease_query(lease, option_code, &l_data, &l_data_len) != 0) + continue; + nm_str_buf_reset(sbuf); while (lease_option_consume_route(&l_data, &l_data_len, TRUE, &dest, &plen, &gateway)) { _nm_utils_inet4_ntop(dest, dest_str); _nm_utils_inet4_ntop(gateway, gateway_str); @@ -359,6 +359,11 @@ lease_parse_routes(NDhcp4ClientLease *lease, nm_str_buf_append_required_delimiter(sbuf, ' '); nm_str_buf_append_printf(sbuf, "%s/%d %s", dest_str, (int) plen, gateway_str); + if (has_classless) { + /* Ignore private option if the standard one is present */ + continue; + } + if (plen == 0) { /* if there are multiple default routes, we add them with differing * metrics. */ @@ -384,10 +389,8 @@ lease_parse_routes(NDhcp4ClientLease *lease, NULL); } - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE, - nm_str_buf_get_str(sbuf)); + has_classless = TRUE; + nm_dhcp_option_add_option(options, AF_INET, option_code, nm_str_buf_get_str(sbuf)); } r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, &l_data, &l_data_len); @@ -693,8 +696,8 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, v_str = 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_NIS_DOMAIN, v_str); - nm_ip4_config_set_nis_domain(ip4_config, v_str); + nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str ?: ""); + nm_ip4_config_set_nis_domain(ip4_config, v_str ?: ""); } lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index b92a9073..100807aa 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -85,29 +85,29 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, const struct in_addr * addr_list; char addr_str[NM_UTILS_INET_ADDRSTRLEN]; const char * s; - nm_auto_free_gstring GString *str = NULL; - gs_free sd_dhcp_route **routes = NULL; - const char *const * search_domains = NULL; - guint16 mtu; - int i, num; - const void * data; - gsize data_len; - gboolean metered = FALSE; - gboolean has_router_from_classless = FALSE; - gboolean has_classless_route = FALSE; - gboolean has_static_route = FALSE; - const gint32 ts = nm_utils_get_monotonic_timestamp_sec(); - gint64 ts_time = time(NULL); - struct in_addr a_address; - struct in_addr a_netmask; - struct in_addr a_next_server; - struct in_addr server_id; - struct in_addr broadcast; - const struct in_addr * a_router; - guint32 a_plen; - guint32 a_lifetime; - guint32 renewal; - guint32 rebinding; + nm_auto_free_gstring GString *str = NULL; + nm_auto_free sd_dhcp_route **routes = NULL; + const char *const * search_domains = NULL; + guint16 mtu; + int i, num; + const void * data; + gsize data_len; + gboolean metered = FALSE; + gboolean has_router_from_classless = FALSE; + gboolean has_classless_route = FALSE; + gboolean has_static_route = FALSE; + const gint32 ts = nm_utils_get_monotonic_timestamp_sec(); + gint64 ts_time = time(NULL); + struct in_addr a_address; + struct in_addr a_netmask; + struct in_addr a_next_server; + struct in_addr server_id; + struct in_addr broadcast; + const struct in_addr * a_router; + guint32 a_plen; + guint32 a_lifetime; + guint32 renewal; + guint32 rebinding; gs_free nm_sd_dhcp_option *private_options = NULL; nm_assert(lease != NULL); diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 646411e2..63d90641 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -880,7 +880,7 @@ nm_dhcp_lease_data_parse_cstr(const guint8 *data, gsize n_data, gsize *out_new_l n_data--; if (n_data > 0) { - if (memchr(data, n_data, '\0')) { + if (memchr(data, '\0', n_data)) { /* we accept trailing NUL, but none in between. * * https://tools.ietf.org/html/rfc2132#section-2 -- cgit 1.3.0-6-gf8a5 From e74c568b07b50b97873fb4ee1d776dedefbd54d6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 1 Oct 2021 23:05:04 +0200 Subject: New upstream version 1.32.12 --- src/core/dhcp/meson.build | 7 +- src/core/dhcp/nm-dhcp-client.c | 160 ++++++++++++++++++------------- src/core/dhcp/nm-dhcp-client.h | 29 +++--- src/core/dhcp/nm-dhcp-dhclient-utils.c | 13 +-- src/core/dhcp/nm-dhcp-dhclient.c | 56 ++++++----- src/core/dhcp/nm-dhcp-dhcpcanon.c | 5 +- src/core/dhcp/nm-dhcp-dhcpcd.c | 7 +- src/core/dhcp/nm-dhcp-helper.c | 10 +- src/core/dhcp/nm-dhcp-listener.c | 2 +- src/core/dhcp/nm-dhcp-manager.c | 107 +++++++++++---------- src/core/dhcp/nm-dhcp-manager.h | 7 +- src/core/dhcp/nm-dhcp-nettools.c | 61 +++++++++--- src/core/dhcp/nm-dhcp-options.c | 10 +- src/core/dhcp/nm-dhcp-options.h | 3 +- src/core/dhcp/nm-dhcp-systemd.c | 84 ++++++++++------ src/core/dhcp/nm-dhcp-utils.c | 14 +-- src/core/dhcp/tests/test-dhcp-dhclient.c | 4 +- src/core/dhcp/tests/test-dhcp-utils.c | 4 +- 18 files changed, 337 insertions(+), 246 deletions(-) (limited to 'src/core/dhcp') diff --git a/src/core/dhcp/meson.build b/src/core/dhcp/meson.build index 1bb004cd..ddaa32fb 100644 --- a/src/core/dhcp/meson.build +++ b/src/core/dhcp/meson.build @@ -3,10 +3,11 @@ executable( 'nm-dhcp-helper', 'nm-dhcp-helper.c', - dependencies: glib_nm_default_dep, - c_args: [ - '-DG_LOG_DOMAIN="nm-dhcp-helper"', + include_directories: [ + src_inc, + top_inc, ], + dependencies: glib_dep, link_args: ldflags_linker_script_binary, link_depends: linker_script_binary, install: true, diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 3b0343fd..ab8243d0 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -13,15 +13,16 @@ #include #include #include +#include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-random-utils.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-dhcp-utils.h" #include "nm-dhcp-options.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" @@ -33,6 +34,7 @@ static guint signals[LAST_SIGNAL] = {0}; NM_GOBJECT_PROPERTIES_DEFINE(NMDhcpClient, PROP_ADDR_FAMILY, + PROP_ANYCAST_ADDRESS, PROP_FLAGS, PROP_HWADDR, PROP_BROADCAST_HWADDR, @@ -61,6 +63,7 @@ typedef struct _NMDhcpClientPrivate { char * hostname; const char ** reject_servers; char * mud_url; + char * anycast_address; GBytes * vendor_class_identifier; pid_t pid; guint timeout_id; @@ -73,8 +76,7 @@ typedef struct _NMDhcpClientPrivate { guint32 iaid; NMDhcpState state; NMDhcpHostnameFlags hostname_flags; - bool info_only : 1; - bool use_fqdn : 1; + NMDhcpClientFlags client_flags; bool iaid_explicit : 1; } NMDhcpClientPrivate; @@ -281,6 +283,14 @@ nm_dhcp_client_set_client_id_bin(NMDhcpClient *self, _set_client_id(self, b, TRUE); } +const char * +nm_dhcp_client_get_anycast_address(NMDhcpClient *self) +{ + g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE(self)->anycast_address; +} + const char * nm_dhcp_client_get_hostname(NMDhcpClient *self) { @@ -297,20 +307,12 @@ nm_dhcp_client_get_hostname_flags(NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE(self)->hostname_flags; } -gboolean -nm_dhcp_client_get_info_only(NMDhcpClient *self) +NMDhcpClientFlags +nm_dhcp_client_get_client_flags(NMDhcpClient *self) { - g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); + g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), NM_DHCP_CLIENT_FLAGS_NONE); - return NM_DHCP_CLIENT_GET_PRIVATE(self)->info_only; -} - -gboolean -nm_dhcp_client_get_use_fqdn(NMDhcpClient *self) -{ - g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); - - return NM_DHCP_CLIENT_GET_PRIVATE(self)->use_fqdn; + return NM_DHCP_CLIENT_GET_PRIVATE(self)->client_flags; } const char * @@ -339,29 +341,25 @@ nm_dhcp_client_get_reject_servers(NMDhcpClient *self) /*****************************************************************************/ -static const char *state_table[NM_DHCP_STATE_MAX + 1] = { - [NM_DHCP_STATE_UNKNOWN] = "unknown", - [NM_DHCP_STATE_BOUND] = "bound", - [NM_DHCP_STATE_EXTENDED] = "extended", - [NM_DHCP_STATE_TIMEOUT] = "timeout", - [NM_DHCP_STATE_EXPIRE] = "expire", - [NM_DHCP_STATE_DONE] = "done", - [NM_DHCP_STATE_FAIL] = "fail", - [NM_DHCP_STATE_TERMINATED] = "terminated", -}; - -static const char * -state_to_string(NMDhcpState state) -{ - if ((gsize) state < G_N_ELEMENTS(state_table)) - return state_table[state]; - return NULL; -} +NM_UTILS_LOOKUP_STR_DEFINE(nm_dhcp_state_to_string, + NMDhcpState, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_BOUND, "bound"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_DONE, "done"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_EXPIRE, "expire"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_EXTENDED, "extended"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_FAIL, "fail"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_NOOP, "noop"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_TERMINATED, "terminated"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_TIMEOUT, "timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_UNKNOWN, "unknown"), + NM_UTILS_LOOKUP_ITEM_IGNORE(__NM_DHCP_STATE_MAX), ); static NMDhcpState reason_to_state(NMDhcpClient *self, const char *iface, const char *reason) { - if (g_ascii_strcasecmp(reason, "bound") == 0 || g_ascii_strcasecmp(reason, "bound6") == 0) + if (g_ascii_strcasecmp(reason, "bound") == 0 || g_ascii_strcasecmp(reason, "bound6") == 0 + || g_ascii_strcasecmp(reason, "static") == 0) return NM_DHCP_STATE_BOUND; else if (g_ascii_strcasecmp(reason, "renew") == 0 || g_ascii_strcasecmp(reason, "renew6") == 0 || g_ascii_strcasecmp(reason, "reboot") == 0 @@ -493,8 +491,8 @@ nm_dhcp_client_set_state(NMDhcpClient *self, const char *addr = nm_g_hash_table_lookup(options, req_str); _LOGI("state changed %s -> %s%s%s%s", - state_to_string(priv->state), - state_to_string(new_state), + nm_dhcp_state_to_string(priv->state), + nm_dhcp_state_to_string(new_state), NM_PRINT_FMT_QUOTED(addr, ", address=", addr, "", "")); } @@ -519,20 +517,12 @@ daemon_watch_cb(GPid pid, int status, gpointer user_data) { NMDhcpClient * self = NM_DHCP_CLIENT(user_data); NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + gs_free char * desc = NULL; g_return_if_fail(priv->watch_id); priv->watch_id = 0; - if (WIFEXITED(status)) - _LOGI("client pid %d exited with status %d", pid, WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - _LOGI("client pid %d killed by signal %d", pid, WTERMSIG(status)); - else if (WIFSTOPPED(status)) - _LOGI("client pid %d stopped by signal %d", pid, WSTOPSIG(status)); - else if (WIFCONTINUED(status)) - _LOGI("client pid %d resumed (by SIGCONT)", pid); - else - _LOGW("client died abnormally"); + _LOGI("client pid %d %s", pid, (desc = nm_utils_get_process_exit_status_desc(status))); priv->pid = -1; @@ -583,7 +573,6 @@ nm_dhcp_client_stop_watch_child(NMDhcpClient *self, pid_t pid) gboolean nm_dhcp_client_start_ip4(NMDhcpClient *self, GBytes * client_id, - const char * dhcp_anycast_addr, const char * last_ip4_address, GError ** error) { @@ -603,10 +592,7 @@ nm_dhcp_client_start_ip4(NMDhcpClient *self, nm_dhcp_client_set_client_id(self, client_id); - return NM_DHCP_CLIENT_GET_CLASS(self)->ip4_start(self, - dhcp_anycast_addr, - last_ip4_address, - error); + return NM_DHCP_CLIENT_GET_CLASS(self)->ip4_start(self, last_ip4_address, error); } gboolean @@ -643,7 +629,6 @@ gboolean nm_dhcp_client_start_ip6(NMDhcpClient * self, GBytes * client_id, gboolean enforce_duid, - const char * dhcp_anycast_addr, const struct in6_addr * ll_addr, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, @@ -672,8 +657,11 @@ nm_dhcp_client_start_ip6(NMDhcpClient * self, else _LOGI("activation: beginning transaction (timeout in %u seconds)", (guint) priv->timeout); - return NM_DHCP_CLIENT_GET_CLASS(self) - ->ip6_start(self, dhcp_anycast_addr, ll_addr, privacy, needed_prefixes, error); + return NM_DHCP_CLIENT_GET_CLASS(self)->ip6_start(self, + ll_addr, + privacy, + needed_prefixes, + error); } void @@ -903,8 +891,8 @@ nm_dhcp_client_handle_event(gpointer unused, old_state = priv->state; new_state = reason_to_state(self, priv->iface, reason); _LOGD("DHCP state '%s' -> '%s' (reason: '%s')", - state_to_string(old_state), - state_to_string(new_state), + nm_dhcp_state_to_string(old_state), + nm_dhcp_state_to_string(new_state), reason); if (new_state == NM_DHCP_STATE_NOOP) @@ -935,12 +923,12 @@ nm_dhcp_client_handle_event(gpointer unused, priv->route_metric)); } else { prefix = nm_dhcp_utils_ip6_prefix_from_options(str_options); - ip_config = NM_IP_CONFIG_CAST( - nm_dhcp_utils_ip6_config_from_options(nm_dhcp_client_get_multi_idx(self), - priv->ifindex, - priv->iface, - str_options, - priv->info_only)); + ip_config = NM_IP_CONFIG_CAST(nm_dhcp_utils_ip6_config_from_options( + nm_dhcp_client_get_multi_idx(self), + priv->ifindex, + priv->iface, + str_options, + NM_FLAGS_HAS(priv->client_flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY))); } } else g_warn_if_reached(); @@ -1057,11 +1045,8 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps case PROP_FLAGS: /* construct-only */ flags = g_value_get_uint(value); - nm_assert( - (flags & ~((guint)(NM_DHCP_CLIENT_FLAGS_INFO_ONLY | NM_DHCP_CLIENT_FLAGS_USE_FQDN))) - == 0); - priv->info_only = NM_FLAGS_HAS(flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY); - priv->use_fqdn = NM_FLAGS_HAS(flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN); + nm_assert(!NM_FLAGS_ANY(flags, ~((guint) NM_DHCP_CLIENT_FLAGS_ALL))); + priv->client_flags = flags; break; case PROP_MULTI_IDX: /* construct-only */ @@ -1085,6 +1070,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /* construct-only */ priv->hwaddr = g_value_dup_boxed(value); break; + case PROP_ANYCAST_ADDRESS: + /* construct-only */ + priv->anycast_address = g_value_dup_string(value); + break; case PROP_BROADCAST_HWADDR: /* construct-only */ priv->bcast_hwaddr = g_value_dup_boxed(value); @@ -1158,6 +1147,28 @@ nm_dhcp_client_init(NMDhcpClient *self) priv->pid = -1; } +#if NM_MORE_ASSERTS +static void +constructed(GObject *object) +{ + NMDhcpClient * self = NM_DHCP_CLIENT(object); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + + /* certain flags only make sense with certain address family. Assert + * for that. */ + if (NM_IS_IPv4(priv->addr_family)) + nm_assert(!NM_FLAGS_ANY(priv->client_flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY)); + else { + nm_assert(NM_FLAGS_HAS(priv->client_flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN)); + nm_assert(!NM_FLAGS_ANY(priv->client_flags, NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST)); + } + + nm_assert(!priv->anycast_address || nm_utils_hwaddr_valid(priv->anycast_address, ETH_ALEN)); + + G_OBJECT_CLASS(nm_dhcp_client_parent_class)->constructed(object); +} +#endif + static void dispose(GObject *object) { @@ -1177,6 +1188,7 @@ dispose(GObject *object) nm_clear_g_free(&priv->iface); nm_clear_g_free(&priv->hostname); nm_clear_g_free(&priv->uuid); + nm_clear_g_free(&priv->anycast_address); nm_clear_g_free(&priv->mud_url); nm_clear_g_free(&priv->reject_servers); nm_clear_pointer(&priv->client_id, g_bytes_unref); @@ -1196,6 +1208,9 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class) g_type_class_add_private(client_class, sizeof(NMDhcpClientPrivate)); +#if NM_MORE_ASSERTS + object_class->constructed = constructed; +#endif object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; @@ -1248,6 +1263,13 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class) AF_UNSPEC, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ANYCAST_ADDRESS] = + g_param_spec_string(NM_DHCP_CLIENT_ANYCAST_ADDRESS, + "", + "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_UUID] = g_param_spec_string(NM_DHCP_CLIENT_UUID, "", diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index af3406cc..3fe1b34e 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -25,6 +25,7 @@ (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) #define NM_DHCP_CLIENT_ADDR_FAMILY "addr-family" +#define NM_DHCP_CLIENT_ANYCAST_ADDRESS "anycast-address" #define NM_DHCP_CLIENT_FLAGS "flags" #define NM_DHCP_CLIENT_HWADDR "hwaddr" #define NM_DHCP_CLIENT_BROADCAST_HWADDR "broadcast-hwaddr" @@ -60,6 +61,8 @@ typedef enum { NM_DHCP_STATE_MAX = __NM_DHCP_STATE_MAX - 1, } NMDhcpState; +const char *nm_dhcp_state_to_string(NMDhcpState state); + struct _NMDhcpClientPrivate; typedef struct { @@ -68,25 +71,27 @@ typedef struct { CList dhcp_client_lst; } NMDhcpClient; -typedef enum { - NM_DHCP_CLIENT_FLAGS_INFO_ONLY = (1LL << 0), - NM_DHCP_CLIENT_FLAGS_USE_FQDN = (1LL << 1), +typedef enum _nm_packed { + NM_DHCP_CLIENT_FLAGS_NONE = 0, + + NM_DHCP_CLIENT_FLAGS_INFO_ONLY = (1LL << 0), + NM_DHCP_CLIENT_FLAGS_USE_FQDN = (1LL << 1), + NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST = (1LL << 2), + + _NM_DHCP_CLIENT_FLAGS_LAST, + NM_DHCP_CLIENT_FLAGS_ALL = ((_NM_DHCP_CLIENT_FLAGS_LAST - 1) << 1) - 1, } NMDhcpClientFlags; typedef struct { GObjectClass parent; - gboolean (*ip4_start)(NMDhcpClient *self, - const char * anycast_addr, - const char * last_ip4_address, - GError ** error); + gboolean (*ip4_start)(NMDhcpClient *self, const char *last_ip4_address, GError **error); gboolean (*accept)(NMDhcpClient *self, GError **error); gboolean (*decline)(NMDhcpClient *self, const char *error_message, GError **error); gboolean (*ip6_start)(NMDhcpClient * self, - const char * anycast_addr, const struct in6_addr * ll_addr, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, @@ -126,6 +131,8 @@ GBytes *nm_dhcp_client_get_hw_addr(NMDhcpClient *self); GBytes *nm_dhcp_client_get_broadcast_hw_addr(NMDhcpClient *self); +const char *nm_dhcp_client_get_anycast_address(NMDhcpClient *self); + guint32 nm_dhcp_client_get_route_table(NMDhcpClient *self); void nm_dhcp_client_set_route_table(NMDhcpClient *self, guint32 route_table); @@ -148,22 +155,18 @@ const char *const *nm_dhcp_client_get_reject_servers(NMDhcpClient *self); NMDhcpHostnameFlags nm_dhcp_client_get_hostname_flags(NMDhcpClient *self); -gboolean nm_dhcp_client_get_info_only(NMDhcpClient *self); - -gboolean nm_dhcp_client_get_use_fqdn(NMDhcpClient *self); +NMDhcpClientFlags nm_dhcp_client_get_client_flags(NMDhcpClient *self); GBytes *nm_dhcp_client_get_vendor_class_identifier(NMDhcpClient *self); gboolean nm_dhcp_client_start_ip4(NMDhcpClient *self, GBytes * client_id, - const char * dhcp_anycast_addr, const char * last_ip4_address, GError ** error); gboolean nm_dhcp_client_start_ip6(NMDhcpClient * self, GBytes * client_id, gboolean enforce_duid, - const char * dhcp_anycast_addr, const struct in6_addr * ll_addr, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c index ad1e097f..4284a852 100644 --- a/src/core/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c @@ -12,12 +12,12 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-dhcp-utils.h" #include "nm-ip4-config.h" #include "nm-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "NetworkManagerUtils.h" #define TIMEOUT_TAG "timeout " @@ -291,7 +291,7 @@ char * nm_dhcp_dhclient_create_config(const char * interface, int addr_family, GBytes * client_id, - const char * anycast_addr, + const char * anycast_address, const char * hostname, guint32 timeout, gboolean use_fqdn, @@ -308,7 +308,8 @@ nm_dhcp_dhclient_create_config(const char * interface, gboolean reset_reqlist = FALSE; int i; - g_return_val_if_fail(!anycast_addr || nm_utils_hwaddr_valid(anycast_addr, ETH_ALEN), NULL); + g_return_val_if_fail(!anycast_address || nm_utils_hwaddr_valid(anycast_address, ETH_ALEN), + NULL); g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), NULL); g_return_val_if_fail(!reject_servers || addr_family == AF_INET, NULL); nm_assert(!out_new_client_id || !*out_new_client_id); @@ -508,14 +509,14 @@ nm_dhcp_dhclient_create_config(const char * interface, g_string_append_c(new_contents, '\n'); - if (anycast_addr) { + if (anycast_address) { g_string_append_printf(new_contents, "interface \"%s\" {\n" " initial-interval 1; \n" " anycast-mac ethernet %s;\n" "}\n", interface, - anycast_addr); + anycast_address); } return g_string_free(g_steal_pointer(&new_contents), FALSE); diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c index c42a0ba5..4a11250f 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -21,7 +21,7 @@ #include #include - #include "nm-glib-aux/nm-dedup-multi.h" + #include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" #include "nm-dhcp-dhclient-utils.h" @@ -151,7 +151,7 @@ merge_dhclient_config(NMDhcpDhclient * self, const char * iface, const char * conf_file, GBytes * client_id, - const char * anycast_addr, + const char * anycast_address, const char * hostname, guint32 timeout, gboolean use_fqdn, @@ -180,7 +180,7 @@ merge_dhclient_config(NMDhcpDhclient * self, new = nm_dhcp_dhclient_create_config(iface, addr_family, client_id, - anycast_addr, + anycast_address, hostname, timeout, use_fqdn, @@ -280,7 +280,7 @@ create_dhclient_config(NMDhcpDhclient * self, const char * iface, const char * uuid, GBytes * client_id, - const char * dhcp_anycast_addr, + const char * anycast_address, const char * hostname, guint32 timeout, gboolean use_fqdn, @@ -312,7 +312,7 @@ create_dhclient_config(NMDhcpDhclient * self, iface, new, client_id, - dhcp_anycast_addr, + anycast_address, hostname, timeout, use_fqdn, @@ -435,6 +435,12 @@ dhclient_start(NMDhcpClient *client, if (release) g_ptr_array_add(argv, (gpointer) "-r"); + if (!release + && NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)), + NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST)) { + g_ptr_array_add(argv, (gpointer) "-B"); + } + if (addr_family == AF_INET6) { g_ptr_array_add(argv, (gpointer) "-6"); @@ -508,10 +514,7 @@ dhclient_start(NMDhcpClient *client, } static gboolean -ip4_start(NMDhcpClient *client, - const char * dhcp_anycast_addr, - const char * last_ip4_address, - GError ** error) +ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) { NMDhcpDhclient * self = NM_DHCP_DHCLIENT(client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE(self); @@ -520,19 +523,20 @@ ip4_start(NMDhcpClient *client, client_id = nm_dhcp_client_get_client_id(client); - priv->conf_file = create_dhclient_config(self, - AF_INET, - nm_dhcp_client_get_iface(client), - nm_dhcp_client_get_uuid(client), - client_id, - dhcp_anycast_addr, - nm_dhcp_client_get_hostname(client), - nm_dhcp_client_get_timeout(client), - nm_dhcp_client_get_use_fqdn(client), - nm_dhcp_client_get_hostname_flags(client), - nm_dhcp_client_get_mud_url(client), - nm_dhcp_client_get_reject_servers(client), - &new_client_id); + priv->conf_file = create_dhclient_config( + self, + AF_INET, + nm_dhcp_client_get_iface(client), + nm_dhcp_client_get_uuid(client), + client_id, + nm_dhcp_client_get_anycast_address(client), + nm_dhcp_client_get_hostname(client), + nm_dhcp_client_get_timeout(client), + NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client), NM_DHCP_CLIENT_FLAGS_USE_FQDN), + nm_dhcp_client_get_hostname_flags(client), + nm_dhcp_client_get_mud_url(client), + nm_dhcp_client_get_reject_servers(client), + &new_client_id); if (!priv->conf_file) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, @@ -549,7 +553,6 @@ ip4_start(NMDhcpClient *client, static gboolean ip6_start(NMDhcpClient * client, - const char * dhcp_anycast_addr, const struct in6_addr * ll_addr, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, @@ -566,7 +569,7 @@ ip6_start(NMDhcpClient * client, nm_dhcp_client_get_iface(client), nm_dhcp_client_get_uuid(client), NULL, - dhcp_anycast_addr, + nm_dhcp_client_get_anycast_address(client), nm_dhcp_client_get_hostname(client), nm_dhcp_client_get_timeout(client), TRUE, @@ -582,7 +585,10 @@ ip6_start(NMDhcpClient * client, } return dhclient_start(client, - nm_dhcp_client_get_info_only(NM_DHCP_CLIENT(self)) ? "-S" : "-N", + NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)), + NM_DHCP_CLIENT_FLAGS_INFO_ONLY) + ? "-S" + : "-N", FALSE, NULL, needed_prefixes, diff --git a/src/core/dhcp/nm-dhcp-dhcpcanon.c b/src/core/dhcp/nm-dhcp-dhcpcanon.c index 3504a048..f3a52ea9 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcanon.c +++ b/src/core/dhcp/nm-dhcp-dhcpcanon.c @@ -161,10 +161,7 @@ dhcpcanon_start(NMDhcpClient *client, } static gboolean -ip4_start(NMDhcpClient *client, - const char * dhcp_anycast_addr, - const char * last_ip4_address, - GError ** error) +ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) { return dhcpcanon_start(client, NULL, NULL, FALSE, NULL, 0, error); } diff --git a/src/core/dhcp/nm-dhcp-dhcpcd.c b/src/core/dhcp/nm-dhcp-dhcpcd.c index cdb266ed..605fb84d 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcd.c +++ b/src/core/dhcp/nm-dhcp-dhcpcd.c @@ -65,10 +65,7 @@ nm_dhcp_dhcpcd_get_path(void) } static gboolean -ip4_start(NMDhcpClient *client, - const char * dhcp_anycast_addr, - const char * last_ip4_address, - GError ** error) +ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) { NMDhcpDhcpcd * self = NM_DHCP_DHCPCD(client); gs_unref_ptrarray GPtrArray *argv = NULL; @@ -122,7 +119,7 @@ ip4_start(NMDhcpClient *client, hostname = nm_dhcp_client_get_hostname(client); if (hostname) { - if (nm_dhcp_client_get_use_fqdn(client)) { + if (NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client), NM_DHCP_CLIENT_FLAGS_USE_FQDN)) { g_ptr_array_add(argv, (gpointer) "-h"); g_ptr_array_add(argv, (gpointer) hostname); g_ptr_array_add(argv, (gpointer) "-F"); diff --git a/src/core/dhcp/nm-dhcp-helper.c b/src/core/dhcp/nm-dhcp-helper.c index 0f98add1..56d20101 100644 --- a/src/core/dhcp/nm-dhcp-helper.c +++ b/src/core/dhcp/nm-dhcp-helper.c @@ -3,13 +3,13 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#include "nm-glib-aux/nm-default-glib.h" +#include "libnm-glib-aux/nm-default-glib.h" #include #include #include -#include "nm-utils/nm-vpn-plugin-macros.h" +#include "libnm-glib-aux/nm-logging-syslog.h" #include "nm-dhcp-helper-api.h" @@ -92,7 +92,7 @@ build_signal_parameters(void) g_variant_builder_add(&builder, "{sv}", name, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, val, strlen(val), 1)); + nm_g_variant_new_ay((const guint8 *) val, strlen(val))); next:; } @@ -154,7 +154,7 @@ do_connect: error->message, try_count, (long long) (time_end - time_remaining - time_start) / 1000); - interval = NM_CLAMP((gint64)(100L * (1L << NM_MIN(try_count, 31))), 5000, 100000); + interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31))), 5000, 100000); g_usleep(NM_MIN(interval, time_remaining)); g_clear_error(&error); goto do_connect; @@ -199,7 +199,7 @@ do_notify: * do some retry. */ if (remaining_time > 0) { _LOGi("failure to call notify: %s (retry %u)", error->message, try_count); - interval = NM_CLAMP((gint64)(100L * (1L << NM_MIN(try_count, 31))), 5000, 25000); + interval = NM_CLAMP((gint64) (100L * (1L << NM_MIN(try_count, 31))), 5000, 25000); g_usleep(NM_MIN(interval, remaining_time)); g_clear_error(&error); goto do_notify; diff --git a/src/core/dhcp/nm-dhcp-listener.c b/src/core/dhcp/nm-dhcp-listener.c index 1673bbb7..b8bb3c33 100644 --- a/src/core/dhcp/nm-dhcp-listener.c +++ b/src/core/dhcp/nm-dhcp-listener.c @@ -16,7 +16,7 @@ #include "nm-dhcp-helper-api.h" #include "nm-dhcp-client.h" #include "nm-dhcp-manager.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "NetworkManagerUtils.h" diff --git a/src/core/dhcp/nm-dhcp-manager.c b/src/core/dhcp/nm-dhcp-manager.c index bc114ad8..44b8ede2 100644 --- a/src/core/dhcp/nm-dhcp-manager.c +++ b/src/core/dhcp/nm-dhcp-manager.c @@ -16,8 +16,8 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-config.h" #include "NetworkManagerUtils.h" @@ -213,12 +213,11 @@ client_start(NMDhcpManager * self, guint32 iaid, gboolean iaid_explicit, guint32 timeout, - const char * dhcp_anycast_addr, + NMDhcpClientFlags client_flags, + const char * anycast_address, const char * hostname, - gboolean hostname_use_fqdn, NMDhcpHostnameFlags hostname_flags, const char * mud_url, - gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const char * last_ip4_address, guint needed_prefixes, @@ -241,6 +240,7 @@ client_start(NMDhcpManager * self, || g_bytes_get_size(vendor_class_identifier) <= 255, NULL); g_return_val_if_fail(!error || !*error, NULL); + nm_assert(!NM_FLAGS_ANY(client_flags, ~NM_DHCP_CLIENT_FLAGS_ALL)); if (addr_family == AF_INET) { if (!hwaddr || !bcast_hwaddr) { @@ -252,7 +252,7 @@ client_start(NMDhcpManager * self, } hwaddr_len = g_bytes_get_size(hwaddr); - if (hwaddr_len == 0 || hwaddr_len > NM_UTILS_HWADDR_LEN_MAX) { + if (hwaddr_len == 0 || hwaddr_len > _NM_UTILS_HWADDR_LEN_MAX) { nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "invalid MAC address"); g_return_val_if_reached(NULL); } @@ -263,12 +263,14 @@ client_start(NMDhcpManager * self, } if (hostname) { - if ((hostname_use_fqdn && !nm_sd_dns_name_is_valid(hostname)) - || (!hostname_use_fqdn && !nm_sd_hostname_is_valid(hostname, FALSE))) { + gboolean use_fqdn = NM_FLAGS_HAS(client_flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN); + + if ((use_fqdn && !nm_sd_dns_name_is_valid(hostname)) + || (!use_fqdn && !nm_sd_hostname_is_valid(hostname, FALSE))) { nm_log_warn(LOGD_DHCP, "dhcp%c: %s '%s' is invalid, will be ignored", nm_utils_addr_family_to_char(addr_family), - hostname_use_fqdn ? "FQDN" : "hostname", + use_fqdn ? "FQDN" : "hostname", hostname); hostname = NULL; } @@ -334,8 +336,9 @@ client_start(NMDhcpManager * self, NM_DHCP_CLIENT_REJECT_SERVERS, reject_servers, NM_DHCP_CLIENT_FLAGS, - (guint)(0 | (hostname_use_fqdn ? NM_DHCP_CLIENT_FLAGS_USE_FQDN : 0) - | (info_only ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY : 0)), + (guint) client_flags, + NM_DHCP_CLIENT_ANYCAST_ADDRESS, + anycast_address, NULL); nm_assert(client && c_list_is_empty(&client->dhcp_client_lst)); c_list_link_tail(&priv->dhcp_client_lst_head, &client->dhcp_client_lst); @@ -371,16 +374,11 @@ client_start(NMDhcpManager * self, */ if (addr_family == AF_INET) { - success = nm_dhcp_client_start_ip4(client, - dhcp_client_id, - dhcp_anycast_addr, - last_ip4_address, - error); + success = nm_dhcp_client_start_ip4(client, dhcp_client_id, last_ip4_address, error); } else { success = nm_dhcp_client_start_ip6(client, dhcp_client_id, enforce_duid, - dhcp_anycast_addr, ipv6_ll_addr, privacy, needed_prefixes, @@ -406,6 +404,7 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self, const char * uuid, guint32 route_table, guint32 route_metric, + NMDhcpClientFlags client_flags, gboolean send_hostname, const char * dhcp_hostname, const char * dhcp_fqdn, @@ -413,7 +412,7 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self, const char * mud_url, GBytes * dhcp_client_id, guint32 timeout, - const char * dhcp_anycast_addr, + const char * anycast_address, const char * last_ip_address, GBytes * vendor_class_identifier, const char *const * reject_servers, @@ -425,6 +424,10 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self, gboolean use_fqdn = FALSE; char * dot; + /* these flags are set automatically/prohibited, and not free to set to the caller. */ + nm_assert(!NM_FLAGS_ANY(client_flags, + NM_DHCP_CLIENT_FLAGS_USE_FQDN | NM_DHCP_CLIENT_FLAGS_INFO_ONLY)); + g_return_val_if_fail(NM_IS_DHCP_MANAGER(self), NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE(self); @@ -451,34 +454,34 @@ nm_dhcp_manager_start_ip4(NMDhcpManager * self, } } - return client_start(self, - AF_INET, - multi_idx, - iface, - ifindex, - hwaddr, - bcast_hwaddr, - uuid, - route_table, - route_metric, - NULL, - dhcp_client_id, - FALSE, - 0, - FALSE, - timeout, - dhcp_anycast_addr, - hostname, - use_fqdn, - hostname_flags, - mud_url, - FALSE, - 0, - last_ip_address, - 0, - vendor_class_identifier, - reject_servers, - error); + return client_start( + self, + AF_INET, + multi_idx, + iface, + ifindex, + hwaddr, + bcast_hwaddr, + uuid, + route_table, + route_metric, + NULL, + dhcp_client_id, + FALSE, + 0, + FALSE, + timeout, + client_flags | (use_fqdn ? NM_DHCP_CLIENT_FLAGS_USE_FQDN : NM_DHCP_CLIENT_FLAGS_NONE), + anycast_address, + hostname, + hostname_flags, + mud_url, + 0, + last_ip_address, + 0, + vendor_class_identifier, + reject_servers, + error); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -491,6 +494,7 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self, const char * uuid, guint32 route_table, guint32 route_metric, + NMDhcpClientFlags client_flags, gboolean send_hostname, const char * dhcp_hostname, NMDhcpHostnameFlags hostname_flags, @@ -500,8 +504,7 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self, guint32 iaid, gboolean iaid_explicit, guint32 timeout, - const char * dhcp_anycast_addr, - gboolean info_only, + const char * anycast_address, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, GError ** error) @@ -509,6 +512,9 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self, NMDhcpManagerPrivate *priv; const char * hostname = NULL; + /* this flag is set automatically, and not free to set to the caller. */ + nm_assert(!NM_FLAGS_ANY(client_flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN)); + g_return_val_if_fail(NM_IS_DHCP_MANAGER(self), NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE(self); @@ -532,12 +538,11 @@ nm_dhcp_manager_start_ip6(NMDhcpManager * self, iaid, iaid_explicit, timeout, - dhcp_anycast_addr, + client_flags | NM_DHCP_CLIENT_FLAGS_USE_FQDN, + anycast_address, hostname, - TRUE, hostname_flags, mud_url, - info_only, privacy, NULL, needed_prefixes, diff --git a/src/core/dhcp/nm-dhcp-manager.h b/src/core/dhcp/nm-dhcp-manager.h index f7aba8a0..ce160437 100644 --- a/src/core/dhcp/nm-dhcp-manager.h +++ b/src/core/dhcp/nm-dhcp-manager.h @@ -41,6 +41,7 @@ NMDhcpClient *nm_dhcp_manager_start_ip4(NMDhcpManager * manager, const char * uuid, guint32 route_table, guint32 route_metric, + NMDhcpClientFlags client_flags, gboolean send_hostname, const char * dhcp_hostname, const char * dhcp_fqdn, @@ -48,7 +49,7 @@ NMDhcpClient *nm_dhcp_manager_start_ip4(NMDhcpManager * manager, const char * mud_url, GBytes * dhcp_client_id, guint32 timeout, - const char * dhcp_anycast_addr, + const char * anycast_address, const char * last_ip_address, GBytes * vendor_class_identifier, const char *const * reject_servers, @@ -62,6 +63,7 @@ NMDhcpClient *nm_dhcp_manager_start_ip6(NMDhcpManager * manager, const char * uuid, guint32 route_table, guint32 route_metric, + NMDhcpClientFlags client_flags, gboolean send_hostname, const char * dhcp_hostname, NMDhcpHostnameFlags hostname_flags, @@ -71,8 +73,7 @@ NMDhcpClient *nm_dhcp_manager_start_ip6(NMDhcpManager * manager, guint32 iaid, gboolean iaid_explicit, guint32 timeout, - const char * dhcp_anycast_addr, - gboolean info_only, + const char * anycast_address, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, GError ** error); diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index c8b80ea6..4bb6c833 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -13,9 +13,9 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-utils.h" #include "nm-config.h" @@ -23,11 +23,11 @@ #include "nm-dhcp-options.h" #include "nm-core-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" #include "n-dhcp4/src/n-dhcp4.h" -#include "systemd/nm-sd-utils-shared.h" -#include "systemd/nm-sd-utils-dhcp.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" +#include "libnm-systemd-core/nm-sd-utils-dhcp.h" /*****************************************************************************/ @@ -694,12 +694,40 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, /* https://tools.ietf.org/html/rfc2132#section-8.1 */ - v_str = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free); + v_str = nm_utils_buf_utf8safe_escape((char *) l_data, + 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_NIS_DOMAIN, v_str ?: ""); nm_ip4_config_set_nis_domain(ip4_config, v_str ?: ""); } + r = n_dhcp4_client_lease_get_file(lease, &v_str); + if (r == 0) { + gs_free char *to_free = NULL; + + v_str = nm_utils_buf_utf8safe_escape(v_str, + -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 ?: ""); + } + + r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len); + if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + gs_free char *to_free = NULL; + + v_str = nm_utils_buf_utf8safe_escape((char *) l_data, + 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 ?: ""); + } + lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf); lease_parse_address_list(lease, @@ -874,7 +902,7 @@ dhcp4_event_cb(int fd, GIOCondition condition, gpointer user_data) } static gboolean -nettools_create(NMDhcpNettools *self, const char *dhcp_anycast_addr, GError **error) +nettools_create(NMDhcpNettools *self, GError **error) { NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE(self); nm_auto(n_dhcp4_client_config_freep) NDhcp4ClientConfig *config = NULL; @@ -893,6 +921,8 @@ nettools_create(NMDhcpNettools *self, const char *dhcp_anycast_addr, GError **er g_return_val_if_fail(!priv->client, FALSE); + /* TODO: honor nm_dhcp_client_get_anycast_address() */ + hwaddr = nm_dhcp_client_get_hw_addr(NM_DHCP_CLIENT(self)); if (!hwaddr || !(hwaddr_arr = g_bytes_get_data(hwaddr, &hwaddr_len)) || (arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len)) < 0) { @@ -941,9 +971,13 @@ nettools_create(NMDhcpNettools *self, const char *dhcp_anycast_addr, GError **er n_dhcp4_client_config_set_transport(config, transport); n_dhcp4_client_config_set_mac(config, hwaddr_arr, hwaddr_len); n_dhcp4_client_config_set_broadcast_mac(config, bcast_hwaddr_arr, bcast_hwaddr_len); + n_dhcp4_client_config_set_request_broadcast( + config, + NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)), + NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST)); r = n_dhcp4_client_config_set_client_id(config, client_id_arr, - NM_MIN(client_id_len, 1 + _NM_SD_MAX_CLIENT_ID_LEN)); + NM_MIN(client_id_len, 1 + _NM_MAX_CLIENT_ID_LEN)); if (r) { set_error_nettools(error, r, "failed to set client-id"); return FALSE; @@ -1031,10 +1065,7 @@ fqdn_flags_to_wire(NMDhcpHostnameFlags flags) } static gboolean -ip4_start(NMDhcpClient *client, - const char * dhcp_anycast_addr, - const char * last_ip4_address, - GError ** error) +ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) { nm_auto(n_dhcp4_client_probe_config_freep) NDhcp4ClientProbeConfig *config = NULL; NMDhcpNettools * self = NM_DHCP_NETTOOLS(client); @@ -1048,7 +1079,7 @@ ip4_start(NMDhcpClient *client, g_return_val_if_fail(!priv->probe, FALSE); - if (!nettools_create(self, dhcp_anycast_addr, error)) + if (!nettools_create(self, error)) return FALSE; r = n_dhcp4_client_probe_config_new(&config); @@ -1113,7 +1144,7 @@ ip4_start(NMDhcpClient *client, } hostname = nm_dhcp_client_get_hostname(client); if (hostname) { - if (nm_dhcp_client_get_use_fqdn(client)) { + if (NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client), NM_DHCP_CLIENT_FLAGS_USE_FQDN)) { uint8_t buffer[255]; NMDhcpHostnameFlags flags; size_t fqdn_len; diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index 3537cd14..011f23e4 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -7,7 +7,7 @@ #include "nm-dhcp-options.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-str-buf.h" /*****************************************************************************/ @@ -169,6 +169,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = { REQ(NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, "ip_address", FALSE), REQ(NM_DHCP_OPTION_DHCP4_NM_EXPIRY, "expiry", FALSE), REQ(NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, "next_server", FALSE), + REQ(NM_DHCP_OPTION_DHCP4_NM_FILENAME, "filename", FALSE), }; static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options)] = { @@ -184,7 +185,7 @@ static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_ A(98), A(99), A(100), A(101), A(102), A(103), A(104), A(105), A(106), A(107), A(108), A(109), A(110), A(111), A(112), A(113), A(114), A(115), A(116), A(117), A(118), A(119), A(120), A(121), A(122), A(123), A(124), A(125), A(126), A(127), A(128), A(129), A(130), A(131), A(132), A(133), - A(134), A(15), A(135), A(136), A(16), A(137), A(138), A(139), A(140), A(141), + A(134), A(15), A(135), A(136), A(16), A(137), A(138), A(139), A(140), A(141), A(142), #undef A }; @@ -404,7 +405,10 @@ nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options, gs_free char *to_free = NULL; const char * escaped; - escaped = nm_utils_buf_utf8safe_escape((char *) data, n_data, 0, &to_free); + escaped = nm_utils_buf_utf8safe_escape((char *) data, + n_data, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, + &to_free); nm_dhcp_option_add_option(options, addr_family, option, escaped ?: ""); } diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h index 585f1187..8ed2039d 100644 --- a/src/core/dhcp/nm-dhcp-options.h +++ b/src/core/dhcp/nm-dhcp-options.h @@ -153,6 +153,7 @@ typedef enum { NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS = 1024, NM_DHCP_OPTION_DHCP4_NM_EXPIRY = 1025, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER = 1026, + NM_DHCP_OPTION_DHCP4_NM_FILENAME = 1027, /* 'file' DHCP header */ } NMDhcpOptionDhcp4Options; typedef enum { @@ -185,7 +186,7 @@ typedef struct { bool include; } NMDhcpOption; -extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[142]; +extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[143]; extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[16]; static inline const char * diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 100807aa..c789aaee 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -13,18 +13,18 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-std-aux/unaligned.h" #include "nm-utils.h" #include "nm-dhcp-utils.h" #include "nm-dhcp-options.h" #include "nm-core-utils.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" -#include "systemd/nm-sd.h" -#include "systemd/nm-sd-utils-dhcp.h" +#include "libnm-systemd-core/nm-sd.h" +#include "libnm-systemd-core/nm-sd-utils-dhcp.h" /*****************************************************************************/ @@ -153,7 +153,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_EXPIRY, - (guint64)(ts_time + a_lifetime)); + (guint64) (ts_time + a_lifetime)); if (sd_dhcp_lease_get_next_server(lease, &a_next_server) == 0) { _nm_utils_inet4_ntop(a_next_server.s_addr, addr_str); @@ -429,18 +429,33 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, num = nm_sd_dhcp_lease_get_private_options(lease, &private_options); if (num > 0) { for (i = 0; i < num; i++) { - char *option_string; - - option_string = nm_utils_bin2hexstr_full(private_options[i].data, - private_options[i].data_len, - ':', - FALSE, - NULL); - if (!options) { - g_free(option_string); + guint8 code = private_options[i].code; + const guint8 *l_data = private_options[i].data; + gsize l_data_len = private_options[i].data_len; + char * option_string; + + if (code == NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY) { + if (nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) { + nm_dhcp_option_add_option_utf8safe_escape( + options, + AF_INET, + NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, + l_data, + l_data_len); + } continue; } - nm_dhcp_option_take_option(options, AF_INET, private_options[i].code, option_string); + if (code == NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE) { + /* nettools and dhclient parse option 249 (Microsoft Classless Static Route) + * as fallback for routes and ignores them from private options. + * + * The systemd plugin does not, and for consistency with nettools we + * also don't expose it as private option either. */ + continue; + } + + option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL); + nm_dhcp_option_take_option(options, AF_INET, code, option_string); } } NM_SET_OUT(out_options, g_steal_pointer(&options)); @@ -543,10 +558,7 @@ dhcp_event_cb(sd_dhcp_client *client, int event, gpointer user_data) } static gboolean -ip4_start(NMDhcpClient *client, - const char * dhcp_anycast_addr, - const char * last_ip4_address, - GError ** error) +ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) { nm_auto(sd_dhcp_client_unrefp) sd_dhcp_client *sd_client = NULL; NMDhcpSystemd * self = NM_DHCP_SYSTEMD(client); @@ -572,6 +584,8 @@ ip4_start(NMDhcpClient *client, g_return_val_if_fail(!priv->client4, FALSE); g_return_val_if_fail(!priv->client6, FALSE); + /* TODO: honor nm_dhcp_client_get_anycast_address() */ + r = sd_dhcp_client_new(&sd_client, FALSE); if (r < 0) { nm_utils_error_set_errno(error, r, "failed to create dhcp-client: %s"); @@ -632,6 +646,11 @@ ip4_start(NMDhcpClient *client, sd_dhcp_lease_get_address(lease, &last_addr); } + r = sd_dhcp_client_set_request_broadcast(sd_client, + NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client), + NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST)); + nm_assert(r >= 0); + if (last_addr.s_addr) { r = sd_dhcp_client_set_request_address(sd_client, &last_addr); if (r < 0) { @@ -659,7 +678,7 @@ ip4_start(NMDhcpClient *client, r = sd_dhcp_client_set_client_id(sd_client, client_id_arr[0], client_id_arr + 1, - NM_MIN(client_id_len - 1, _NM_SD_MAX_CLIENT_ID_LEN)); + NM_MIN(client_id_len - 1, _NM_MAX_CLIENT_ID_LEN)); if (r < 0) { nm_utils_error_set_errno(error, r, "failed to set IPv4 client-id: %s"); return FALSE; @@ -844,14 +863,16 @@ bound6_handle(NMDhcpSystemd *self) _LOGD("lease available"); - ip6_config = lease_to_ip6_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)), - iface, - nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)), - lease, - nm_dhcp_client_get_info_only(NM_DHCP_CLIENT(self)), - &options, - ts, - &error); + ip6_config = + lease_to_ip6_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)), + iface, + nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)), + lease, + NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)), + NM_DHCP_CLIENT_FLAGS_INFO_ONLY), + &options, + ts, + &error); if (!ip6_config) { _LOGW("%s", error->message); @@ -905,7 +926,6 @@ dhcp6_event_cb(sd_dhcp6_client *client, int event, gpointer user_data) static gboolean ip6_start(NMDhcpClient * client, - const char * dhcp_anycast_addr, const struct in6_addr * ll_addr, NMSettingIP6ConfigPrivacy privacy, guint needed_prefixes, @@ -924,6 +944,8 @@ ip6_start(NMDhcpClient * client, g_return_val_if_fail(!priv->client4, FALSE); g_return_val_if_fail(!priv->client6, FALSE); + /* TODO: honor nm_dhcp_client_get_anycast_address() */ + if (!(duid = nm_dhcp_client_get_client_id(client)) || !(duid_arr = g_bytes_get_data(duid, &duid_len)) || duid_len < 2) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "missing DUID"); @@ -938,7 +960,7 @@ ip6_start(NMDhcpClient * client, _LOGT("dhcp-client6: set %p", sd_client); - if (nm_dhcp_client_get_info_only(client)) { + if (NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client), NM_DHCP_CLIENT_FLAGS_INFO_ONLY)) { sd_dhcp6_client_set_address_request(sd_client, 0); if (needed_prefixes == 0) sd_dhcp6_client_set_information_request(sd_client, 1); diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 63d90641..7fd18b0a 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -8,18 +8,18 @@ #include #include -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-str-buf.h" -#include "systemd/nm-sd-utils-shared.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-str-buf.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "nm-dhcp-utils.h" #include "nm-utils.h" #include "nm-config.h" #include "NetworkManagerUtils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-dhcp-client-logging.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ @@ -989,7 +989,7 @@ lease_option_print_label(NMStrBuf *sbuf, size_t n_label, const uint8_t **datap, break; case '.': case '\\': - nm_str_buf_append_c2(sbuf, '\\', c); + nm_str_buf_append_c(sbuf, '\\', c); break; default: nm_str_buf_append_printf(sbuf, "\\%3d", c); diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index 77626f69..e9a62096 100644 --- a/src/core/dhcp/tests/test-dhcp-dhclient.c +++ b/src/core/dhcp/tests/test-dhcp-dhclient.c @@ -9,14 +9,14 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "NetworkManagerUtils.h" #include "dhcp/nm-dhcp-dhclient-utils.h" #include "dhcp/nm-dhcp-utils.h" #include "nm-utils.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" diff --git a/src/core/dhcp/tests/test-dhcp-utils.c b/src/core/dhcp/tests/test-dhcp-utils.c index 9b54e2cd..4d47e7e2 100644 --- a/src/core/dhcp/tests/test-dhcp-utils.c +++ b/src/core/dhcp/tests/test-dhcp-utils.c @@ -9,12 +9,12 @@ #include #include -#include "nm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-dedup-multi.h" #include "nm-utils.h" #include "dhcp/nm-dhcp-utils.h" #include "dhcp/nm-dhcp-options.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-test-utils-core.h" -- cgit 1.3.0-6-gf8a5 From 88c227d90a6b7b388c5c85d72802a0ca8f05ed5c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 13 Jan 2022 22:30:39 +0100 Subject: New upstream version 1.34.0 --- src/core/dhcp/nm-dhcp-client.c | 112 ++++++++++++++++-------- src/core/dhcp/nm-dhcp-client.h | 34 ++++++-- src/core/dhcp/nm-dhcp-dhclient-utils.c | 10 +-- src/core/dhcp/nm-dhcp-dhclient.c | 60 ++++++------- src/core/dhcp/nm-dhcp-dhcpcanon.c | 47 +++++----- src/core/dhcp/nm-dhcp-dhcpcd.c | 47 +++++----- src/core/dhcp/nm-dhcp-helper.c | 4 +- src/core/dhcp/nm-dhcp-listener.c | 3 +- src/core/dhcp/nm-dhcp-manager.c | 145 ++++++------------------------- src/core/dhcp/nm-dhcp-nettools.c | 14 ++- src/core/dhcp/nm-dhcp-systemd.c | 22 ++--- src/core/dhcp/nm-dhcp-utils.c | 20 ++--- src/core/dhcp/tests/test-dhcp-dhclient.c | 4 +- 13 files changed, 235 insertions(+), 287 deletions(-) (limited to 'src/core/dhcp') diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index ab8243d0..f88c79c0 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -28,7 +28,7 @@ /*****************************************************************************/ -enum { SIGNAL_STATE_CHANGED, SIGNAL_PREFIX_DELEGATED, LAST_SIGNAL }; +enum { SIGNAL_NOTIFY, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; @@ -78,6 +78,7 @@ typedef struct _NMDhcpClientPrivate { NMDhcpHostnameFlags hostname_flags; NMDhcpClientFlags client_flags; bool iaid_explicit : 1; + bool is_stopped : 1; } NMDhcpClientPrivate; G_DEFINE_ABSTRACT_TYPE(NMDhcpClient, nm_dhcp_client, G_TYPE_OBJECT) @@ -91,6 +92,33 @@ G_STATIC_ASSERT(!(((pid_t) -1) > 0)); /*****************************************************************************/ +static void +_emit_notify(NMDhcpClient *self, const NMDhcpClientNotifyData *notify_data) +{ + g_signal_emit(G_OBJECT(self), signals[SIGNAL_NOTIFY], 0, notify_data); +} + +static void +_emit_notify_state_changed(NMDhcpClient *self, + NMDhcpState dhcp_state, + NMIPConfig * ip_config, + GHashTable * options) +{ + const NMDhcpClientNotifyData notify_data = { + .notify_type = NM_DHCP_CLIENT_NOTIFY_TYPE_STATE_CHANGED, + .state_changed = + { + .dhcp_state = dhcp_state, + .ip_config = ip_config, + .options = options, + }, + }; + + _emit_notify(self, ¬ify_data); +} + +/*****************************************************************************/ + pid_t nm_dhcp_client_get_pid(NMDhcpClient *self) { @@ -352,8 +380,7 @@ NM_UTILS_LOOKUP_STR_DEFINE(nm_dhcp_state_to_string, NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_NOOP, "noop"), NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_TERMINATED, "terminated"), NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_TIMEOUT, "timeout"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_UNKNOWN, "unknown"), - NM_UTILS_LOOKUP_ITEM_IGNORE(__NM_DHCP_STATE_MAX), ); + NM_UTILS_LOOKUP_STR_ITEM(NM_DHCP_STATE_UNKNOWN, "unknown"), ); static NMDhcpState reason_to_state(NMDhcpClient *self, const char *iface, const char *reason) @@ -469,7 +496,7 @@ nm_dhcp_client_set_state(NMDhcpClient *self, gs_free const char **keys = NULL; guint i, nkeys; - keys = nm_utils_strdict_get_keys(options, TRUE, &nkeys); + keys = nm_strdict_get_keys(options, TRUE, &nkeys); for (i = 0; i < nkeys; i++) { _LOGD("option %-20s => '%s'", keys[i], (char *) g_hash_table_lookup(options, keys[i])); } @@ -497,7 +524,8 @@ nm_dhcp_client_set_state(NMDhcpClient *self, } priv->state = new_state; - g_signal_emit(G_OBJECT(self), signals[SIGNAL_STATE_CHANGED], 0, new_state, ip_config, options); + + _emit_notify_state_changed(self, new_state, ip_config, options); } static gboolean @@ -607,6 +635,20 @@ nm_dhcp_client_accept(NMDhcpClient *self, GError **error) return TRUE; } +gboolean +nm_dhcp_client_can_accept(NMDhcpClient *self) +{ + gboolean can_accept; + + g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); + + can_accept = !!(NM_DHCP_CLIENT_GET_CLASS(self)->accept); + + nm_assert(can_accept == (!!(NM_DHCP_CLIENT_GET_CLASS(self)->decline))); + + return can_accept; +} + gboolean nm_dhcp_client_decline(NMDhcpClient *self, const char *error_message, GError **error) { @@ -733,6 +775,11 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release) priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + if (priv->is_stopped) + return; + + priv->is_stopped = TRUE; + /* Kill the DHCP client */ old_pid = priv->pid; NM_DHCP_CLIENT_GET_CLASS(self)->stop(self, release); @@ -855,7 +902,15 @@ maybe_add_option(NMDhcpClient *self, GHashTable *hash, const char *key, GVariant void nm_dhcp_client_emit_ipv6_prefix_delegated(NMDhcpClient *self, const NMPlatformIP6Address *prefix) { - g_signal_emit(G_OBJECT(self), signals[SIGNAL_PREFIX_DELEGATED], 0, prefix); + const NMDhcpClientNotifyData notify_data = { + .notify_type = NM_DHCP_CLIENT_NOTIFY_TYPE_PREFIX_DELEGATED, + .prefix_delegated = + { + .prefix = prefix, + }, + }; + + _emit_notify(self, ¬ify_data); } gboolean @@ -1124,7 +1179,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps break; case PROP_REJECT_SERVERS: /* construct-only */ - priv->reject_servers = nm_utils_strv_dup_packed(g_value_get_boxed(value), -1); + priv->reject_servers = nm_strv_dup_packed(g_value_get_boxed(value), -1); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -1142,8 +1197,6 @@ nm_dhcp_client_init(NMDhcpClient *self) priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DHCP_CLIENT, NMDhcpClientPrivate); self->_priv = priv; - c_list_init(&self->dhcp_client_lst); - priv->pid = -1; } @@ -1175,12 +1228,7 @@ dispose(GObject *object) NMDhcpClient * self = NM_DHCP_CLIENT(object); NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); - /* Stopping the client is left up to the controlling device - * explicitly since we may want to quit NetworkManager but not terminate - * the DHCP client. - */ - - nm_assert(c_list_is_empty(&self->dhcp_client_lst)); + nm_dhcp_client_stop(self, FALSE); watch_cleanup(self); timeout_cleanup(self); @@ -1369,27 +1417,15 @@ nm_dhcp_client_class_init(NMDhcpClientClass *client_class) g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); - signals[SIGNAL_STATE_CHANGED] = g_signal_new(NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 3, - G_TYPE_UINT, - G_TYPE_OBJECT, - G_TYPE_HASH_TABLE); - - signals[SIGNAL_PREFIX_DELEGATED] = g_signal_new(NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); + signals[SIGNAL_NOTIFY] = + g_signal_new(NM_DHCP_CLIENT_NOTIFY, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, + G_TYPE_POINTER /* const NMDhcpClientNotifyData *notify_data */); } diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index 3fe1b34e..2e7e0216 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -44,8 +44,7 @@ #define NM_DHCP_CLIENT_VENDOR_CLASS_IDENTIFIER "vendor-class-identifier" #define NM_DHCP_CLIENT_REJECT_SERVERS "reject-servers" -#define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" -#define NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED "prefix-delegated" +#define NM_DHCP_CLIENT_NOTIFY "dhcp-notify" typedef enum { NM_DHCP_STATE_UNKNOWN = 0, @@ -57,10 +56,27 @@ typedef enum { NM_DHCP_STATE_FAIL, /* failed for some reason */ NM_DHCP_STATE_TERMINATED, /* client is no longer running */ NM_DHCP_STATE_NOOP, /* state is a non operation for NetworkManager */ - __NM_DHCP_STATE_MAX, - NM_DHCP_STATE_MAX = __NM_DHCP_STATE_MAX - 1, } NMDhcpState; +typedef enum _nm_packed { + NM_DHCP_CLIENT_NOTIFY_TYPE_STATE_CHANGED, + NM_DHCP_CLIENT_NOTIFY_TYPE_PREFIX_DELEGATED, +} NMDhcpClientNotifyType; + +typedef struct { + NMDhcpClientNotifyType notify_type; + union { + struct { + NMIPConfig *ip_config; + GHashTable *options; + NMDhcpState dhcp_state; + } state_changed; + struct { + const NMPlatformIP6Address *prefix; + } prefix_delegated; + }; +} NMDhcpClientNotifyData; + const char *nm_dhcp_state_to_string(NMDhcpState state); struct _NMDhcpClientPrivate; @@ -68,7 +84,6 @@ struct _NMDhcpClientPrivate; typedef struct { GObject parent; struct _NMDhcpClientPrivate *_priv; - CList dhcp_client_lst; } NMDhcpClient; typedef enum _nm_packed { @@ -173,6 +188,7 @@ gboolean nm_dhcp_client_start_ip6(NMDhcpClient * self, GError ** error); gboolean nm_dhcp_client_accept(NMDhcpClient *self, GError **error); +gboolean nm_dhcp_client_can_accept(NMDhcpClient *self); gboolean nm_dhcp_client_decline(NMDhcpClient *self, const char *error_message, GError **error); @@ -217,11 +233,13 @@ gboolean nm_dhcp_client_server_id_is_rejected(NMDhcpClient *self, gconstpointer *****************************************************************************/ typedef struct { - GType (*get_type)(void); - GType (*get_type_per_addr_family)(int addr_family); + GType (*get_type_4)(void); + GType (*get_type_6)(void); const char *name; const char *(*get_path)(void); - bool experimental : 1; + + /* whether this plugin is an undocumented, internal plugin. */ + bool undocumented : 1; } NMDhcpClientFactory; GType nm_dhcp_nettools_get_type(void); diff --git a/src/core/dhcp/nm-dhcp-dhclient-utils.c b/src/core/dhcp/nm-dhcp-dhclient-utils.c index 4284a852..341ac7b2 100644 --- a/src/core/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/core/dhcp/nm-dhcp-dhclient-utils.c @@ -59,7 +59,7 @@ grab_request_options(GPtrArray *store, const char *line) gsize i; /* Grab each 'request' or 'also request' option and save for later */ - line_v = nm_utils_strsplit_set(line, "\t ,"); + line_v = nm_strsplit_set(line, "\t ,"); for (i = 0; line_v && line_v[i]; i++) { const char *ss = nm_str_skip_leading_spaces(line_v[i]); gsize l; @@ -282,7 +282,7 @@ read_interface(const char *line, char *interface, guint size) if (ptr[0] == '\0' || strlen(ptr) + 1 > size) return FALSE; - snprintf(interface, size, "%s", ptr); + g_snprintf(interface, size, "%s", ptr); return TRUE; } @@ -330,7 +330,7 @@ nm_dhcp_dhclient_create_config(const char * interface, g_string_append_printf(new_contents, _("# Merged from %s\n\n"), orig_path); intf[0] = '\0'; - lines = nm_utils_strsplit_set(orig_contents, "\n\r"); + lines = nm_strsplit_set(orig_contents, "\n\r"); for (line_i = 0; lines && lines[line_i]; line_i++) { const char *line = nm_str_skip_leading_spaces(lines[line_i]); const char *p; @@ -620,7 +620,7 @@ nm_dhcp_dhclient_read_duid(const char *leasefile, GError **error) if (!g_file_get_contents(leasefile, &contents, NULL, error)) return NULL; - contents_v = nm_utils_strsplit_set(contents, "\n\r"); + contents_v = nm_strsplit_set(contents, "\n\r"); for (i = 0; contents_v && contents_v[i]; i++) { const char *p = nm_str_skip_leading_spaces(contents_v[i]); GBytes * duid; @@ -671,7 +671,7 @@ nm_dhcp_dhclient_save_duid(const char *leasefile, GBytes *duid, GError **error) return FALSE; } - lines = nm_utils_strsplit_set_with_empty(contents, "\n\r"); + lines = nm_strsplit_set_with_empty(contents, "\n\r"); } s = g_string_sized_new(len + 50); diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c index 4a11250f..970a51f5 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -14,21 +14,21 @@ #if WITH_DHCLIENT - #include - #include - #include - #include - #include - #include - - #include "libnm-glib-aux/nm-dedup-multi.h" - - #include "nm-utils.h" - #include "nm-dhcp-dhclient-utils.h" - #include "nm-dhcp-manager.h" - #include "NetworkManagerUtils.h" - #include "nm-dhcp-listener.h" - #include "nm-dhcp-client-logging.h" +#include +#include +#include +#include +#include +#include + +#include "libnm-glib-aux/nm-dedup-multi.h" + +#include "nm-utils.h" +#include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-manager.h" +#include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" +#include "nm-dhcp-client-logging.h" /*****************************************************************************/ @@ -41,16 +41,15 @@ _addr_family_to_path_part(int addr_family) /*****************************************************************************/ - #define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type()) - #define NM_DHCP_DHCLIENT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclient)) - #define NM_DHCP_DHCLIENT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) - #define NM_IS_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCLIENT)) - #define NM_IS_DHCP_DHCLIENT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCLIENT)) - #define NM_DHCP_DHCLIENT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) +#define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type()) +#define NM_DHCP_DHCLIENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclient)) +#define NM_DHCP_DHCLIENT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) +#define NM_IS_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCLIENT)) +#define NM_IS_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCLIENT)) +#define NM_DHCP_DHCLIENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) typedef struct _NMDhcpDhclient NMDhcpDhclient; typedef struct _NMDhcpDhclientClass NMDhcpDhclientClass; @@ -78,8 +77,8 @@ struct _NMDhcpDhclientClass { G_DEFINE_TYPE(NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) - #define NM_DHCP_DHCLIENT_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMDhcpDhclient, NM_IS_DHCP_DHCLIENT) +#define NM_DHCP_DHCLIENT_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDhcpDhclient, NM_IS_DHCP_DHCLIENT) /*****************************************************************************/ @@ -731,9 +730,10 @@ nm_dhcp_dhclient_class_init(NMDhcpDhclientClass *dhclient_class) } const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient = { - .name = "dhclient", - .get_type = nm_dhcp_dhclient_get_type, - .get_path = nm_dhcp_dhclient_get_path, + .name = "dhclient", + .get_type_4 = nm_dhcp_dhclient_get_type, + .get_type_6 = nm_dhcp_dhclient_get_type, + .get_path = nm_dhcp_dhclient_get_path, }; #endif /* WITH_DHCLIENT */ diff --git a/src/core/dhcp/nm-dhcp-dhcpcanon.c b/src/core/dhcp/nm-dhcp-dhcpcanon.c index f3a52ea9..f993ffb9 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcanon.c +++ b/src/core/dhcp/nm-dhcp-dhcpcanon.c @@ -7,25 +7,24 @@ #if WITH_DHCPCANON - #include - #include - - #include "nm-utils.h" - #include "nm-dhcp-manager.h" - #include "NetworkManagerUtils.h" - #include "nm-dhcp-listener.h" - #include "nm-dhcp-client-logging.h" - - #define NM_TYPE_DHCP_DHCPCANON (nm_dhcp_dhcpcanon_get_type()) - #define NM_DHCP_DHCPCANON(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanon)) - #define NM_DHCP_DHCPCANON_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) - #define NM_IS_DHCP_DHCPCANON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCPCANON)) - #define NM_IS_DHCP_DHCPCANON_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCPCANON)) - #define NM_DHCP_DHCPCANON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) +#include +#include + +#include "nm-utils.h" +#include "nm-dhcp-manager.h" +#include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" +#include "nm-dhcp-client-logging.h" + +#define NM_TYPE_DHCP_DHCPCANON (nm_dhcp_dhcpcanon_get_type()) +#define NM_DHCP_DHCPCANON(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanon)) +#define NM_DHCP_DHCPCANON_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) +#define NM_IS_DHCP_DHCPCANON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCPCANON)) +#define NM_IS_DHCP_DHCPCANON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCPCANON)) +#define NM_DHCP_DHCPCANON_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) typedef struct _NMDhcpDhcpcanon NMDhcpDhcpcanon; typedef struct _NMDhcpDhcpcanonClass NMDhcpDhcpcanonClass; @@ -53,8 +52,8 @@ struct _NMDhcpDhcpcanonClass { G_DEFINE_TYPE(NMDhcpDhcpcanon, nm_dhcp_dhcpcanon, NM_TYPE_DHCP_CLIENT) - #define NM_DHCP_DHCPCANON_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMDhcpDhcpcanon, NM_IS_DHCP_DHCPCANON) +#define NM_DHCP_DHCPCANON_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDhcpDhcpcanon, NM_IS_DHCP_DHCPCANON) /*****************************************************************************/ @@ -232,9 +231,9 @@ nm_dhcp_dhcpcanon_class_init(NMDhcpDhcpcanonClass *dhcpcanon_class) } const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon = { - .name = "dhcpcanon", - .get_type = nm_dhcp_dhcpcanon_get_type, - .get_path = nm_dhcp_dhcpcanon_get_path, + .name = "dhcpcanon", + .get_type_4 = nm_dhcp_dhcpcanon_get_type, + .get_path = nm_dhcp_dhcpcanon_get_path, }; #endif /* WITH_DHCPCANON */ diff --git a/src/core/dhcp/nm-dhcp-dhcpcd.c b/src/core/dhcp/nm-dhcp-dhcpcd.c index 605fb84d..7522156b 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcd.c +++ b/src/core/dhcp/nm-dhcp-dhcpcd.c @@ -8,29 +8,28 @@ #if WITH_DHCPCD - #include - #include - #include - #include - #include - - #include "nm-dhcp-manager.h" - #include "nm-utils.h" - #include "NetworkManagerUtils.h" - #include "nm-dhcp-listener.h" - #include "nm-dhcp-client-logging.h" +#include +#include +#include +#include +#include + +#include "nm-dhcp-manager.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" +#include "nm-dhcp-client-logging.h" /*****************************************************************************/ - #define NM_TYPE_DHCP_DHCPCD (nm_dhcp_dhcpcd_get_type()) - #define NM_DHCP_DHCPCD(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcd)) - #define NM_DHCP_DHCPCD_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) - #define NM_IS_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCPCD)) - #define NM_IS_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCPCD)) - #define NM_DHCP_DHCPCD_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) +#define NM_TYPE_DHCP_DHCPCD (nm_dhcp_dhcpcd_get_type()) +#define NM_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcd)) +#define NM_DHCP_DHCPCD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) +#define NM_IS_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCPCD)) +#define NM_IS_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCPCD)) +#define NM_DHCP_DHCPCD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) typedef struct _NMDhcpDhcpcd NMDhcpDhcpcd; typedef struct _NMDhcpDhcpcdClass NMDhcpDhcpcdClass; @@ -54,7 +53,7 @@ struct _NMDhcpDhcpcdClass { G_DEFINE_TYPE(NMDhcpDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT) - #define NM_DHCP_DHCPCD_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDhcpDhcpcd, NM_IS_DHCP_DHCPCD) +#define NM_DHCP_DHCPCD_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDhcpDhcpcd, NM_IS_DHCP_DHCPCD) /*****************************************************************************/ @@ -233,9 +232,9 @@ nm_dhcp_dhcpcd_class_init(NMDhcpDhcpcdClass *dhcpcd_class) } const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd = { - .name = "dhcpcd", - .get_type = nm_dhcp_dhcpcd_get_type, - .get_path = nm_dhcp_dhcpcd_get_path, + .name = "dhcpcd", + .get_type_4 = nm_dhcp_dhcpcd_get_type, + .get_path = nm_dhcp_dhcpcd_get_path, }; #endif /* WITH_DHCPCD */ diff --git a/src/core/dhcp/nm-dhcp-helper.c b/src/core/dhcp/nm-dhcp-helper.c index 56d20101..fd666676 100644 --- a/src/core/dhcp/nm-dhcp-helper.c +++ b/src/core/dhcp/nm-dhcp-helper.c @@ -16,9 +16,9 @@ /*****************************************************************************/ #if NM_MORE_LOGGING - #define _NMLOG_ENABLED(level) TRUE +#define _NMLOG_ENABLED(level) TRUE #else - #define _NMLOG_ENABLED(level) ((level) <= LOG_ERR) +#define _NMLOG_ENABLED(level) ((level) <= LOG_ERR) #endif #define _NMLOG(always_enabled, level, ...) \ diff --git a/src/core/dhcp/nm-dhcp-listener.c b/src/core/dhcp/nm-dhcp-listener.c index b8bb3c33..ae2c40f1 100644 --- a/src/core/dhcp/nm-dhcp-listener.c +++ b/src/core/dhcp/nm-dhcp-listener.c @@ -26,8 +26,9 @@ /*****************************************************************************/ const NMDhcpClientFactory *const _nm_dhcp_manager_factories[6] = { + /* the order here matters, as we will try the plugins in this order to find - * the first available plugin. */ + * the first available plugin. */ #if WITH_DHCPCANON &_nm_dhcp_client_factory_dhcpcanon, diff --git a/src/core/dhcp/nm-dhcp-manager.c b/src/core/dhcp/nm-dhcp-manager.c index 44b8ede2..3cb89393 100644 --- a/src/core/dhcp/nm-dhcp-manager.c +++ b/src/core/dhcp/nm-dhcp-manager.c @@ -27,7 +27,6 @@ typedef struct { const NMDhcpClientFactory *client_factory; char * default_hostname; - CList dhcp_client_lst_head; } NMDhcpManagerPrivate; struct _NMDhcpManager { @@ -45,14 +44,6 @@ G_DEFINE_TYPE(NMDhcpManager, nm_dhcp_manager, G_TYPE_OBJECT) /*****************************************************************************/ -static void client_state_changed(NMDhcpClient * client, - NMDhcpState state, - GObject * ip_config, - GVariant * options, - NMDhcpManager *self); - -/*****************************************************************************/ - /* default to installed helper, but can be modified for testing */ const char *nm_dhcp_helper_path = LIBEXECDIR "/nm-dhcp-helper"; @@ -63,9 +54,9 @@ _client_factory_find_by_name(const char *name) { int i; - g_return_val_if_fail(name, NULL); + nm_assert(name); - for (i = 0; i < G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { + for (i = 0; i < (int) G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { const NMDhcpClientFactory *f = _nm_dhcp_manager_factories[i]; if (f && nm_streq(f->name, name)) @@ -85,11 +76,10 @@ _client_factory_available(const NMDhcpClientFactory *client_factory) static GType _client_factory_get_gtype(const NMDhcpClientFactory *client_factory, int addr_family) { - GType gtype; - nm_auto_unref_gtypeclass NMDhcpClientClass *klass = NULL; + GType gtype; + GType (*get_type_fcn)(void); nm_assert(client_factory); - nm_assert_addr_family(addr_family); /* currently, the chosen DHCP plugin for IPv4 and IPv6 is configured in NetworkManager.conf * and cannot be reloaded. It would be nice to configure the plugin per address family @@ -111,29 +101,22 @@ _client_factory_get_gtype(const NMDhcpClientFactory *client_factory, int addr_fa * to those plugins. But we don't intend to do so. The internal plugin is the way forward and * not extending other plugins. */ - if (client_factory->get_type_per_addr_family) - gtype = client_factory->get_type_per_addr_family(addr_family); + if (NM_IS_IPv4(addr_family)) + get_type_fcn = client_factory->get_type_4; else - gtype = client_factory->get_type(); - - if (client_factory == &_nm_dhcp_client_factory_internal) { - /* we are already using the internal plugin. Nothing to do. */ - goto out; + get_type_fcn = client_factory->get_type_6; + + if (!get_type_fcn) { + /* If the factory does not support the address family, we always + * fallback to the internal. */ + if (NM_IS_IPv4(addr_family)) + get_type_fcn = _nm_dhcp_client_factory_internal.get_type_4; + else + get_type_fcn = _nm_dhcp_client_factory_internal.get_type_6; } - klass = g_type_class_ref(gtype); - - nm_assert(NM_IS_DHCP_CLIENT_CLASS(klass)); + gtype = get_type_fcn(); - if (addr_family == AF_INET6) { - if (!klass->ip6_start) - gtype = _client_factory_get_gtype(&_nm_dhcp_client_factory_internal, addr_family); - } else { - if (!klass->ip4_start) - gtype = _client_factory_get_gtype(&_nm_dhcp_client_factory_internal, addr_family); - } - -out: nm_assert(g_type_is_a(gtype, NM_TYPE_DHCP_CLIENT)); nm_assert(({ nm_auto_unref_gtypeclass NMDhcpClientClass *k = g_type_class_ref(gtype); @@ -146,56 +129,6 @@ out: /*****************************************************************************/ -static NMDhcpClient * -get_client_for_ifindex(NMDhcpManager *manager, int addr_family, int ifindex) -{ - NMDhcpManagerPrivate *priv; - NMDhcpClient * client; - - g_return_val_if_fail(NM_IS_DHCP_MANAGER(manager), NULL); - g_return_val_if_fail(ifindex > 0, NULL); - - priv = NM_DHCP_MANAGER_GET_PRIVATE(manager); - - c_list_for_each_entry (client, &priv->dhcp_client_lst_head, dhcp_client_lst) { - if (nm_dhcp_client_get_ifindex(client) == ifindex - && nm_dhcp_client_get_addr_family(client) == addr_family) - return client; - } - - return NULL; -} - -static void -remove_client(NMDhcpManager *self, NMDhcpClient *client) -{ - g_signal_handlers_disconnect_by_func(client, client_state_changed, self); - c_list_unlink(&client->dhcp_client_lst); - - /* Stopping the client is left up to the controlling device - * explicitly since we may want to quit NetworkManager but not terminate - * the DHCP client. - */ -} - -static void -remove_client_unref(NMDhcpManager *self, NMDhcpClient *client) -{ - remove_client(self, client); - g_object_unref(client); -} - -static void -client_state_changed(NMDhcpClient * client, - NMDhcpState state, - GObject * ip_config, - GVariant * options, - NMDhcpManager *self) -{ - if (state >= NM_DHCP_STATE_TIMEOUT) - remove_client_unref(self, client); -} - static NMDhcpClient * client_start(NMDhcpManager * self, int addr_family, @@ -226,10 +159,10 @@ client_start(NMDhcpManager * self, GError ** error) { NMDhcpManagerPrivate *priv; - NMDhcpClient * client; - gboolean success = FALSE; - gsize hwaddr_len; - GType gtype; + gs_unref_object NMDhcpClient *client = NULL; + gboolean success = FALSE; + gsize hwaddr_len; + GType gtype; g_return_val_if_fail(NM_IS_DHCP_MANAGER(self), NULL); g_return_val_if_fail(iface, NULL); @@ -278,20 +211,6 @@ client_start(NMDhcpManager * self, priv = NM_DHCP_MANAGER_GET_PRIVATE(self); - /* Kill any old client instance */ - client = get_client_for_ifindex(self, addr_family, ifindex); - if (client) { - /* FIXME: we cannot just call synchronously "stop()" and forget about the client. - * We need to wait for the client to be fully stopped because most/all clients - * cannot quit right away. - * - * FIXME(shutdown): also fix this during shutdown, to wait for all DHCP clients - * to be fully stopped. */ - remove_client(self, client); - nm_dhcp_client_stop(client, FALSE); - g_object_unref(client); - } - gtype = _client_factory_get_gtype(priv->client_factory, addr_family); nm_log_trace(LOGD_DHCP, @@ -340,12 +259,6 @@ client_start(NMDhcpManager * self, NM_DHCP_CLIENT_ANYCAST_ADDRESS, anycast_address, NULL); - nm_assert(client && c_list_is_empty(&client->dhcp_client_lst)); - c_list_link_tail(&priv->dhcp_client_lst_head, &client->dhcp_client_lst); - g_signal_connect(client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK(client_state_changed), - self); /* unfortunately, our implementations work differently per address-family regarding client-id/DUID. * @@ -385,12 +298,10 @@ client_start(NMDhcpManager * self, error); } - if (!success) { - remove_client_unref(self, client); + if (!success) return NULL; - } - return g_object_ref(client); + return g_steal_pointer(&client); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -596,9 +507,7 @@ nm_dhcp_manager_init(NMDhcpManager *self) int i; const NMDhcpClientFactory *client_factory = NULL; - c_list_init(&priv->dhcp_client_lst_head); - - for (i = 0; i < G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { + for (i = 0; i < (int) G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { const NMDhcpClientFactory *f = _nm_dhcp_manager_factories[i]; if (!f) @@ -608,7 +517,7 @@ nm_dhcp_manager_init(NMDhcpManager *self) "dhcp-init: enabled DHCP client '%s'%s%s", f->name, _client_factory_available(f) ? "" : " (not available)", - f->experimental ? " (undocumented internal plugin)" : ""); + f->undocumented ? " (undocumented internal plugin)" : ""); } /* Client-specific setup */ @@ -644,7 +553,7 @@ nm_dhcp_manager_init(NMDhcpManager *self) } } if (!client_factory) { - for (i = 0; i < G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { + for (i = 0; i < (int) G_N_ELEMENTS(_nm_dhcp_manager_factories); i++) { client_factory = _client_factory_available(_nm_dhcp_manager_factories[i]); if (client_factory) break; @@ -668,10 +577,6 @@ dispose(GObject *object) { NMDhcpManager * self = NM_DHCP_MANAGER(object); NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE(self); - NMDhcpClient * client, *client_safe; - - c_list_for_each_entry_safe (client, client_safe, &priv->dhcp_client_lst_head, dhcp_client_lst) - remove_client_unref(self, client); G_OBJECT_CLASS(nm_dhcp_manager_parent_class)->dispose(object); diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index 4bb6c833..56b485dd 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -601,7 +601,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, nm_str_buf_append_len0(&sbuf, (const char *) l_data, l_data_len); /* Multiple domains sometimes stuffed into option 15 "Domain Name". */ - domains = nm_utils_strsplit_set(nm_str_buf_get_str(&sbuf), " "); + domains = nm_strsplit_set(nm_str_buf_get_str(&sbuf), " "); nm_str_buf_reset(&sbuf); if (domains) { @@ -997,9 +997,7 @@ nettools_create(NMDhcpNettools *self, GError **error) n_dhcp4_client_get_fd(priv->client, &fd); - priv->event_source = - nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, dhcp4_event_cb, self, NULL); - g_source_attach(priv->event_source, NULL); + priv->event_source = nm_g_unix_fd_add_source(fd, G_IO_IN, dhcp4_event_cb, self); return TRUE; } @@ -1221,7 +1219,7 @@ ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) return FALSE; } - _LOGT("dhcp-client4: start %p", (gpointer) priv->client); + _LOGT("dhcp-client4: start " NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(priv->client)); nm_dhcp_client_start_timeout(client); return TRUE; @@ -1235,7 +1233,7 @@ stop(NMDhcpClient *client, gboolean release) NM_DHCP_CLIENT_CLASS(nm_dhcp_nettools_parent_class)->stop(client, release); - _LOGT("dhcp-client4: stop %p", (gpointer) priv->client); + _LOGT("dhcp-client4: stop " NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(priv->client)); priv->probe = n_dhcp4_client_probe_free(priv->probe); } @@ -1276,6 +1274,6 @@ nm_dhcp_nettools_class_init(NMDhcpNettoolsClass *class) const NMDhcpClientFactory _nm_dhcp_client_factory_nettools = { .name = "nettools", - .get_type = nm_dhcp_nettools_get_type, - .experimental = TRUE, + .get_type_4 = nm_dhcp_nettools_get_type, + .undocumented = TRUE, }; diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index c789aaee..af1d2238 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -592,7 +592,7 @@ ip4_start(NMDhcpClient *client, const char *last_ip4_address, GError **error) return FALSE; } - _LOGT("dhcp-client4: set %p", sd_client); + _LOGT("dhcp-client4: set " NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(sd_client)); r = sd_dhcp_client_attach_event(sd_client, NULL, 0); if (r < 0) { @@ -1124,23 +1124,15 @@ nm_dhcp_systemd_class_init(NMDhcpSystemdClass *sdhcp_class) const NMDhcpClientFactory _nm_dhcp_client_factory_systemd = { .name = "systemd", - .get_type = nm_dhcp_systemd_get_type, - .experimental = TRUE, + .get_type_4 = nm_dhcp_systemd_get_type, + .get_type_6 = nm_dhcp_systemd_get_type, + .undocumented = TRUE, }; /*****************************************************************************/ -static GType -_get_type_per_addr_family(int addr_family) -{ - nm_assert_addr_family(addr_family); - - if (addr_family == AF_INET) - return nm_dhcp_nettools_get_type(); - return nm_dhcp_systemd_get_type(); -} - const NMDhcpClientFactory _nm_dhcp_client_factory_internal = { - .name = "internal", - .get_type_per_addr_family = _get_type_per_addr_family, + .name = "internal", + .get_type_4 = nm_dhcp_nettools_get_type, + .get_type_6 = nm_dhcp_systemd_get_type, }; diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 7fd18b0a..3cc6987a 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -35,7 +35,7 @@ ip4_process_dhcpcd_rfc3442_routes(const char * iface, const char ** r; gboolean have_routes = FALSE; - routes = nm_utils_strsplit_set(str, " "); + routes = nm_strsplit_set(str, " "); if (!routes) return FALSE; @@ -164,7 +164,7 @@ ip4_process_dhclient_rfc3442_routes(const char * iface, const char *const * o; gboolean have_routes = FALSE; - octets = nm_utils_strsplit_set_with_empty(str, " ."); + octets = nm_strsplit_set_with_empty(str, " ."); if (NM_PTRARRAY_LEN(octets) < 5) { _LOG2W(LOGD_DHCP4, iface, "ignoring invalid classless static routes '%s'", str); return FALSE; @@ -296,7 +296,7 @@ process_classful_routes(const char * iface, if (!str) return; - searches = nm_utils_strsplit_set(str, " "); + searches = nm_strsplit_set(str, " "); if (!searches) return; @@ -376,7 +376,7 @@ process_domain_search(const char *iface, const char *str, GFunc add_func, gpoint return; } - searches = nm_utils_strsplit_set(unescaped, " "); + searches = nm_strsplit_set(unescaped, " "); for (s = searches; searches && *s; s++) { _LOG2I(LOGD_DHCP, iface, " domain search '%s'", *s); add_func((gpointer) *s, user_data); @@ -450,7 +450,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, */ str = g_hash_table_lookup(options, "routers"); if (str) { - gs_free const char **routers = nm_utils_strsplit_set(str, " "); + gs_free const char **routers = nm_strsplit_set(str, " "); const char ** s; for (s = routers; routers && *s; s++) { @@ -491,7 +491,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, str = g_hash_table_lookup(options, "domain_name_servers"); if (str) { - gs_free const char **dns = nm_utils_strsplit_set(str, " "); + gs_free const char **dns = nm_strsplit_set(str, " "); const char ** s; for (s = dns; dns && *s; s++) { @@ -507,7 +507,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, str = g_hash_table_lookup(options, "domain_name"); if (str) { - gs_free const char **domains = nm_utils_strsplit_set(str, " "); + gs_free const char **domains = nm_strsplit_set(str, " "); const char ** s; for (s = domains; domains && *s; s++) { @@ -522,7 +522,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, str = g_hash_table_lookup(options, "netbios_name_servers"); if (str) { - gs_free const char **nbns = nm_utils_strsplit_set(str, " "); + gs_free const char **nbns = nm_strsplit_set(str, " "); const char ** s; for (s = nbns; nbns && *s; s++) { @@ -557,7 +557,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, str = g_hash_table_lookup(options, "nis_servers"); if (str) { - gs_free const char **nis = nm_utils_strsplit_set(str, " "); + gs_free const char **nis = nm_strsplit_set(str, " "); const char ** s; for (s = nis; nis && *s; s++) { @@ -689,7 +689,7 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx, str = g_hash_table_lookup(options, "dhcp6_name_servers"); if (str) { - gs_free const char **dns = nm_utils_strsplit_set(str, " "); + gs_free const char **dns = nm_strsplit_set(str, " "); const char ** s; for (s = dns; dns && *s; s++) { diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index e9a62096..9c6865cc 100644 --- a/src/core/dhcp/tests/test-dhcp-dhclient.c +++ b/src/core/dhcp/tests/test-dhcp-dhclient.c @@ -830,7 +830,7 @@ test_one_duid(const char *escaped, const guint8 *unescaped, guint len) t1 = nm_dhcp_dhclient_unescape_duid(escaped); g_assert(t1); - g_assert(nm_utils_gbytes_equal_mem(t1, unescaped, len)); + g_assert(nm_g_bytes_equal_mem(t1, unescaped, len)); t2 = g_bytes_new(unescaped, len); w = nm_dhcp_dhclient_escape_duid(t2); @@ -879,7 +879,7 @@ test_read_duid_from_leasefile(void) duid = nm_dhcp_dhclient_read_duid(TEST_DIR "/test-dhclient-duid.leases", &error); nmtst_assert_success(duid, error); - g_assert(nm_utils_gbytes_equal_mem(duid, expected, G_N_ELEMENTS(expected))); + g_assert(nm_g_bytes_equal_mem(duid, expected, G_N_ELEMENTS(expected))); } static void -- cgit 1.3.0-6-gf8a5