diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2018-07-06 11:18:49 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-07-19 10:34:10 +0200 |
commit | ac85e9c3349d2de507f264b9810bf0144d268fc1 (patch) | |
tree | 200d4eba73e3ea7d447bfd209c39be88781cf14f | |
parent | 29362030661edfa4228a85767caea756d334d5f6 (diff) | |
download | NetworkManager-bg/dhcpv4-static-addr-rh1369905.tar.gz |
device: apply static addresses immediately for DHCPv4 methodbg/dhcpv4-static-addr-rh1369905
When the IPv4 method is 'auto' and there are static addresses
configured in the connection, start a DAD probe for the static
addresses and apply them immediately on success, without waiting for
DHCP to complete.
Note that if the static address is in the same subnet of the DHCP one,
when we add the DHCP address we want it to be primary and so we will
remove the static address temporarily to have the right order of
addresses.
https://bugzilla.redhat.com/show_bug.cgi?id=1369905
-rw-r--r-- | src/devices/nm-device.c | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7ca2360b27..4352f80f63 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6351,15 +6351,31 @@ acd_data_destroy (gpointer ptr, GClosure *closure) static void ipv4_manual_method_apply (NMDevice *self, NMIP4Config **configs, gboolean success) { + NMConnection *connection; + const char *method; NMIP4Config *empty; - if (success) { + connection = nm_device_get_applied_connection (self); + nm_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + nm_assert (NM_IN_STRSET (method, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_METHOD_AUTO)); + + if (!success) { + nm_device_ip_method_failed (self, AF_INET, + NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); + return; + } + + if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { empty = _ip4_config_new (self); nm_device_activate_schedule_ip4_config_result (self, empty); g_object_unref (empty); } else { - nm_device_ip_method_failed (self, AF_INET, - NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); + /* auto method */ + if (NM_DEVICE_GET_PRIVATE (self)->ip4_state != IP_DONE) + ip_config_merge_and_apply (self, AF_INET, TRUE); } } @@ -7609,30 +7625,44 @@ act_stage3_ip4_config_start (NMDevice *self, method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - /* Start IPv4 addressing based on the method requested */ - if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { - ret = dhcp4_start (self); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); - } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) { - ret = ipv4ll_start (self); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); - } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) { + if (NM_IN_STRSET (method, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + NMSettingIPConfig *s_ip4; NMIP4Config **configs, *config; + guint num_addresses; - config = _ip4_config_new (self); - nm_ip4_config_merge_setting (config, - nm_connection_get_setting_ip4_config (connection), - NM_SETTING_CONNECTION_MDNS_DEFAULT, - nm_device_get_route_table (self, AF_INET, TRUE), - nm_device_get_route_metric (self, AF_INET)); + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_return_val_if_fail (s_ip4, NM_ACT_STAGE_RETURN_FAILURE); + num_addresses = nm_setting_ip_config_get_num_addresses (s_ip4); + + if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + ret = dhcp4_start (self); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); + return ret; + } + } else { + g_return_val_if_fail (num_addresses != 0, NM_ACT_STAGE_RETURN_FAILURE); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } - configs = g_new0 (NMIP4Config *, 2); - configs[0] = config; - ipv4_dad_start (self, configs, ipv4_manual_method_apply); - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { + if (num_addresses) { + config = _ip4_config_new (self); + nm_ip4_config_merge_setting (config, + nm_connection_get_setting_ip4_config (connection), + NM_SETTING_CONNECTION_MDNS_DEFAULT, + nm_device_get_route_table (self, AF_INET, TRUE), + nm_device_get_route_metric (self, AF_INET)); + configs = g_new0 (NMIP4Config *, 2); + configs[0] = config; + ipv4_dad_start (self, configs, ipv4_manual_method_apply); + } + } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + ret = ipv4ll_start (self); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); + } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { if (out_config) { *out_config = shared4_new_config (self, connection); if (*out_config) { @@ -7643,8 +7673,8 @@ act_stage3_ip4_config_start (NMDevice *self, ret = NM_ACT_STAGE_RETURN_FAILURE; } } else - g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); + } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) ret = NM_ACT_STAGE_RETURN_SUCCESS; else _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); |