mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-16 03:50:34 +01:00
dhcp: simplify DHCP states
The existing DHC_* states are pretty specific to dhclient, and aren't useful for more generalized DHCP. NetworkManager wasn't using many of the states anyway, and doesn't need to differentiate between states like REBOOT/REBIND/RENEW anyway. So simplify the DHCP states into the ones we really care about.
This commit is contained in:
parent
30cdd1248c
commit
9e75e2ad0d
3 changed files with 76 additions and 144 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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] =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue