summary refs log tree commit diff
path: root/src/core/dhcp/nm-dhcp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/dhcp/nm-dhcp-client.c')
-rw-r--r--src/core/dhcp/nm-dhcp-client.c112
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, &notify_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, &notify_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 */);
 }