diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b3c6265be9..3efc3a2874 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2699,7 +2699,7 @@ dhcp4_fail (NMDevice *device, gboolean timeout) static void dhcp4_state_changed (NMDHCPClient *client, - NMDHCPState state, + NMDhcpState state, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); @@ -2712,10 +2712,7 @@ dhcp4_state_changed (NMDHCPClient *client, nm_device_get_iface (device), state); switch (state) { - case DHC_BOUND4: /* lease obtained */ - case DHC_RENEW4: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND4: /* new, different lease */ + case NM_DHCP_STATE_BOUND: config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); if (!config) { nm_log_warn (LOGD_DHCP4, "(%s): failed to get IPv4 config in response to DHCP event.", @@ -2740,12 +2737,11 @@ dhcp4_state_changed (NMDHCPClient *client, g_object_unref (config); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ + case NM_DHCP_STATE_TIMEOUT: dhcp4_fail (device, TRUE); break; - case DHC_END: /* dhclient exited normally */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: /* dhclient quit and can't get/renew a lease; so kill the connection */ dhcp4_fail (device, FALSE); break; @@ -3150,7 +3146,7 @@ dhcp6_fail (NMDevice *device, gboolean timeout) static void dhcp6_state_changed (NMDHCPClient *client, - NMDHCPState state, + NMDhcpState state, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); @@ -3162,10 +3158,7 @@ dhcp6_state_changed (NMDHCPClient *client, nm_device_get_iface (device), state); switch (state) { - case DHC_BOUND6: - case DHC_RENEW6: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND6: /* new, different lease */ + case NM_DHCP_STATE_BOUND: g_clear_object (&priv->dhcp6_ip6_config); priv->dhcp6_ip6_config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); @@ -3188,10 +3181,10 @@ dhcp6_state_changed (NMDHCPClient *client, } else if (priv->ip6_state == IP_DONE) dhcp6_lease_change (device); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ + case NM_DHCP_STATE_TIMEOUT: dhcp6_fail (device, TRUE); break; - case DHC_END: /* dhclient exited normally */ + case NM_DHCP_STATE_DONE: /* In IPv6 info-only mode, the client doesn't handle leases so it * may exit right after getting a response from the server. That's * normal. In that case we just ignore the exit. @@ -3199,8 +3192,7 @@ dhcp6_state_changed (NMDHCPClient *client, if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) break; /* Otherwise, fall through */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ + case NM_DHCP_STATE_FAIL: /* dhclient quit and can't get/renew a lease; so kill the connection */ dhcp6_fail (device, FALSE); break; diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index b123b5afdb..abe3bf6360 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -44,7 +44,7 @@ typedef struct { guint32 timeout; GByteArray * duid; - guchar state; + NMDhcpState state; pid_t pid; guint timeout_id; guint watch_id; @@ -201,7 +201,7 @@ signal_remove (gpointer user_data) static void dhcp_client_set_state (NMDHCPClient *self, - NMDHCPState state, + NMDhcpState state, gboolean emit_state, gboolean remove_now) { @@ -212,7 +212,7 @@ dhcp_client_set_state (NMDHCPClient *self, if (emit_state) g_signal_emit (G_OBJECT (self), signals[SIGNAL_STATE_CHANGED], 0, priv->state); - if (state == DHC_END || state == DHC_ABEND) { + if (state == NM_DHCP_STATE_DONE || state == NM_DHCP_STATE_FAIL) { /* Start the remove signal timer */ if (remove_now) { g_signal_emit (G_OBJECT (self), signals[SIGNAL_REMOVE], 0); @@ -228,7 +228,7 @@ daemon_watch_cb (GPid pid, gint status, gpointer user_data) { NMDHCPClient *self = NM_DHCP_CLIENT (user_data); NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - NMDHCPState new_state; + NMDhcpState new_state; if (priv->ipv6) { nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 client pid %d exited with status %d", @@ -241,10 +241,10 @@ daemon_watch_cb (GPid pid, gint status, gpointer user_data) } if (!WIFEXITED (status)) { - new_state = DHC_ABEND; + new_state = NM_DHCP_STATE_FAIL; nm_log_warn (LOGD_DHCP, "DHCP client died abnormally"); } else - new_state = DHC_END; + new_state = NM_DHCP_STATE_DONE; watch_cleanup (self); timeout_cleanup (self); @@ -519,7 +519,7 @@ nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) /* And clean stuff up */ - dhcp_client_set_state (self, DHC_END, FALSE, TRUE); + dhcp_client_set_state (self, NM_DHCP_STATE_DONE, FALSE, TRUE); g_hash_table_remove_all (priv->options); @@ -529,71 +529,44 @@ nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) /********************************************/ -static gboolean -state_is_bound (guint32 state) -{ - if ( (state == DHC_BOUND4) - || (state == DHC_BOUND6) - || (state == DHC_RENEW4) - || (state == DHC_RENEW6) - || (state == DHC_REBOOT) - || (state == DHC_REBIND4) - || (state == DHC_REBIND6) - || (state == DHC_IPV4LL)) - return TRUE; - - return FALSE; -} - -static const char *state_table[] = { - [DHC_NBI] = "nbi", - [DHC_PREINIT] = "preinit", - [DHC_PREINIT6] = "preinit6", - [DHC_BOUND4] = "bound", - [DHC_BOUND6] = "bound6", - [DHC_IPV4LL] = "ipv4ll", - [DHC_RENEW4] = "renew", - [DHC_RENEW6] = "renew6", - [DHC_REBOOT] = "reboot", - [DHC_REBIND4] = "rebind", - [DHC_REBIND6] = "rebind6", - [DHC_DEPREF6] = "depref6", - [DHC_STOP] = "stop", - [DHC_STOP6] = "stop6", - [DHC_MEDIUM] = "medium", - [DHC_TIMEOUT] = "timeout", - [DHC_FAIL] = "fail", - [DHC_EXPIRE] = "expire", - [DHC_EXPIRE6] = "expire6", - [DHC_RELEASE] = "release", - [DHC_RELEASE6] = "release6", - [DHC_START] = "start", - [DHC_ABEND] = "abend", - [DHC_END] = "end", +static const char *state_table[NM_DHCP_STATE_MAX + 1] = { + [NM_DHCP_STATE_UNKNOWN] = "unknown", + [NM_DHCP_STATE_BOUND] = "bound", + [NM_DHCP_STATE_TIMEOUT] = "timeout", + [NM_DHCP_STATE_DONE] = "done", + [NM_DHCP_STATE_FAIL] = "fail", }; static const char * -state_to_string (NMDHCPState state) +state_to_string (NMDhcpState state) { if (state >= 0 && state < G_N_ELEMENTS (state_table)) return state_table[state]; return NULL; } -static NMDHCPState -string_to_state (const char *name) +static NMDhcpState +reason_to_state (const char *iface, const char *reason) { - int i; + if (g_ascii_strcasecmp (reason, "bound") == 0 || + g_ascii_strcasecmp (reason, "bound6") == 0 || + g_ascii_strcasecmp (reason, "renew") == 0 || + g_ascii_strcasecmp (reason, "renew6") == 0 || + g_ascii_strcasecmp (reason, "reboot") == 0 || + g_ascii_strcasecmp (reason, "rebind") == 0 || + g_ascii_strcasecmp (reason, "rebind6") == 0) + return NM_DHCP_STATE_BOUND; + else if (g_ascii_strcasecmp (reason, "timeout") == 0) + return NM_DHCP_STATE_TIMEOUT; + else if (g_ascii_strcasecmp (reason, "end") == 0) + return NM_DHCP_STATE_DONE; + else if (g_ascii_strcasecmp (reason, "fail") == 0 || + g_ascii_strcasecmp (reason, "abend") == 0 || + g_ascii_strcasecmp (reason, "nak") == 0) + return NM_DHCP_STATE_FAIL; - if (name) { - for (i = 0; i < G_N_ELEMENTS (state_table); i++) { - const char *n = state_table[i]; - - if (n && !strcasecmp (name, n)) - return i; - } - } - return 255; + nm_log_dbg (LOGD_DHCP, "(%s): unmapped DHCP state '%s'", iface, reason); + return NM_DHCP_STATE_UNKNOWN; } static char * @@ -665,44 +638,31 @@ nm_dhcp_client_new_options (NMDHCPClient *self, priv = NM_DHCP_CLIENT_GET_PRIVATE (self); old_state = priv->state; - new_state = string_to_state (reason); + new_state = reason_to_state (priv->iface, reason); /* Clear old and save new DHCP options */ g_hash_table_remove_all (priv->options); g_hash_table_foreach (options, copy_option, priv->options); - if (old_state == new_state) { - /* dhclient will stay in the same state (or, really, provide the same - * reason) for operations like RENEW and REBIND. We need to ensure - * that triggers various DHCP lease change code, so we need to pass - * along same-state transitions for these states. - */ - if ( new_state != DHC_BOUND4 - && new_state != DHC_RENEW4 - && new_state != DHC_REBIND4 - && new_state != DHC_BOUND6 - && new_state != DHC_RENEW6 - && new_state != DHC_REBIND6) - return; - } + /* dhclient sends same-state transitions for RENEW/REBIND events, but + * the lease may have changed, so handle same-state transitions for + * these events. Ignore same-state transitions for other events since + * the lease won't have changed and the state was already handled. + */ + if ((old_state == new_state) && (new_state != NM_DHCP_STATE_BOUND)) + return; - /* Handle changed device state */ - if (state_is_bound (new_state)) { + if (new_state == NM_DHCP_STATE_BOUND) { /* Cancel the timeout if the DHCP client is now bound */ timeout_cleanup (self); } - if (priv->ipv6) { - nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 state changed %s -> %s", - priv->iface, - state_to_string (old_state), - state_to_string (new_state)); - } else { - nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 state changed %s -> %s", - priv->iface, - state_to_string (old_state), - state_to_string (new_state)); - } + nm_log_info (priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): DHCPv%c state changed %s -> %s", + priv->iface, + priv->ipv6 ? '6' : '4', + state_to_string (old_state), + state_to_string (new_state)); dhcp_client_set_state (self, new_state, TRUE, FALSE); } @@ -724,12 +684,11 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self, priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - if (!state_is_bound (priv->state)) { - if (priv->ipv6) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); - } else { - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface); - } + if (priv->state != NM_DHCP_STATE_BOUND) { + nm_log_warn (priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): DHCPv%c client didn't bind to a lease.", + priv->iface, + priv->ipv6 ? '6' : '4'); } g_hash_table_iter_init (&iter, priv->options); @@ -1319,7 +1278,7 @@ nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test) priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - if (test && !state_is_bound (priv->state)) { + if (test && (priv->state != NM_DHCP_STATE_BOUND)) { nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface); return NULL; } @@ -1437,7 +1396,7 @@ nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - if (test && !state_is_bound (priv->state)) { + if (test && (priv->state != NM_DHCP_STATE_BOUND)) { nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); return NULL; } @@ -1640,8 +1599,7 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDHCPClientClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT); signals[SIGNAL_TIMEOUT] = diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index d6a1a1b32f..9fef69da08 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -47,32 +47,14 @@ #define NM_DHCP_CLIENT_SIGNAL_REMOVE "remove" typedef enum { - DHC_NBI = 0, /* no broadcast interfaces found */ - DHC_PREINIT, /* configuration started */ - DHC_PREINIT6, /* configuration started */ - DHC_BOUND4, /* IPv4 lease obtained */ - DHC_BOUND6, /* IPv6 lease obtained */ - DHC_IPV4LL, /* IPv4LL address obtained */ - DHC_RENEW4, /* IPv4 lease renewed */ - DHC_RENEW6, /* IPv6 lease renewed */ - DHC_REBOOT, /* have valid lease, but now obtained a different one */ - DHC_REBIND4, /* IPv4 new/different lease */ - DHC_REBIND6, /* IPv6 new/different lease */ - DHC_DEPREF6, /* IPv6 lease depreferred */ - DHC_STOP, /* remove old lease */ - DHC_STOP6, /* remove old lease */ - DHC_MEDIUM, /* media selection begun */ - DHC_TIMEOUT, /* timed out contacting DHCP server */ - DHC_FAIL, /* all attempts to contact server timed out, sleeping */ - DHC_EXPIRE, /* lease has expired, renewing */ - DHC_EXPIRE6, /* lease has expired, renewing */ - DHC_RELEASE, /* releasing lease */ - DHC_RELEASE6, /* releasing lease */ - DHC_START, /* sent when dhclient started OK */ - DHC_ABEND, /* dhclient exited abnormally */ - DHC_END, /* dhclient exited normally */ - DHC_END_OPTIONS, /* last option in subscription sent */ -} NMDHCPState; + NM_DHCP_STATE_UNKNOWN = 0, + NM_DHCP_STATE_BOUND, /* lease changed (state_is_bound) */ + NM_DHCP_STATE_TIMEOUT, /* TIMEOUT */ + NM_DHCP_STATE_DONE, /* END */ + NM_DHCP_STATE_FAIL, /* failed or quit unexpectedly */ + __NM_DHCP_STATE_MAX, + NM_DHCP_STATE_MAX = __NM_DHCP_STATE_MAX - 1, +} NMDhcpState; typedef struct { GObject parent; @@ -110,7 +92,7 @@ typedef struct { GByteArray * (*get_duid) (NMDHCPClient *self); /* Signals */ - void (*state_changed) (NMDHCPClient *self, NMDHCPState state); + void (*state_changed) (NMDHCPClient *self, NMDhcpState state); void (*timeout) (NMDHCPClient *self); void (*remove) (NMDHCPClient *self); } NMDHCPClientClass;