diff options
Diffstat (limited to 'src/core/dhcp/nm-dhcp-client.c')
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.c | 112 |
1 files changed, 74 insertions, 38 deletions
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 @@ -608,6 +636,20 @@ nm_dhcp_client_accept(NMDhcpClient *self, GError **error) } 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) { g_return_val_if_fail(NM_IS_DHCP_CLIENT(self), FALSE); @@ -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 */); } |