diff options
Diffstat (limited to 'src')
31 files changed, 660 insertions, 251 deletions
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index 232e69ef..1c1d5eaa 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -143,14 +143,6 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory, return NULL; } - if (!nm_utils_is_valid_iface_name (ifname, error)) { - g_prefix_error (error, - "failed to determine interface name: name \"%s\" is invalid", - ifname); - g_free (ifname); - return NULL; - } - return ifname; } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e7a4a059..3bbc9757 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -76,7 +76,20 @@ _LOG_DECLARE_SELF (NMDevice); /*****************************************************************************/ #define DEFAULT_AUTOCONNECT TRUE -#define DHCP_GRACE_PERIOD_SEC 480 + +static guint32 +dhcp_grace_period_from_timeout (guint32 timeout) +{ +#define DHCP_GRACE_PERIOD_MULTIPLIER 2U + + nm_assert (timeout > 0); + nm_assert (timeout < G_MAXINT32); + + if (timeout < G_MAXUINT32 / DHCP_GRACE_PERIOD_MULTIPLIER) + return timeout * DHCP_GRACE_PERIOD_MULTIPLIER; + + return G_MAXUINT32; +} #define CARRIER_WAIT_TIME_MS 6000 #define CARRIER_WAIT_TIME_AFTER_MTU_MS 10000 @@ -463,12 +476,13 @@ typedef struct _NMDevicePrivate { /* DHCPv4 tracking */ struct { NMDhcpClient * client; - gulong state_sigid; NMDhcp4Config * config; char * pac_url; char * root_path; - bool was_active; + gulong state_sigid; guint grace_id; + bool was_active:1; + bool grace_pending:1; } dhcp4; struct { @@ -533,17 +547,18 @@ typedef struct _NMDevicePrivate { struct { NMDhcpClient * client; - NMNDiscDHCPLevel mode; - gulong state_sigid; - gulong prefix_sigid; NMDhcp6Config * config; /* IP6 config from DHCP */ AppliedConfig ip6_config; /* Event ID of the current IP6 config from DHCP */ char * event_id; + gulong state_sigid; + gulong prefix_sigid; + NMNDiscDHCPLevel mode; guint needed_prefixes; - bool was_active; guint grace_id; + bool was_active:1; + bool grace_pending:1; } dhcp6; gboolean needs_ip6_subnet; @@ -4240,6 +4255,12 @@ nm_device_create_and_realize (NMDevice *self, return TRUE; } +static gboolean +can_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) +{ + return TRUE; +} + void nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) { @@ -4248,6 +4269,9 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink int ifindex; guint32 mtu; + if (!NM_DEVICE_GET_CLASS (self)->can_update_from_platform_link (self, plink)) + return; + g_return_if_fail (plink == NULL || link_type_compatible (self, plink->type, NULL, NULL)); str = plink ? nm_platform_link_get_udi (nm_device_get_platform (self), plink->ifindex) : NULL; @@ -7474,6 +7498,51 @@ ensure_con_ip_config (NMDevice *self, int addr_family) /*****************************************************************************/ /* DHCPv4 stuff */ +static guint32 +get_dhcp_timeout (NMDevice *self, int addr_family) +{ + NMDeviceClass *klass; + NMConnection *connection; + int timeout_i; + guint32 timeout; + + nm_assert (NM_IS_DEVICE (self)); + nm_assert_addr_family (addr_family); + + connection = nm_device_get_applied_connection (self); + + timeout_i = nm_setting_ip_config_get_dhcp_timeout (nm_connection_get_setting_ip_config (connection, addr_family)); + nm_assert (timeout_i >= 0 && timeout_i <= G_MAXINT32); + + timeout = (guint32) timeout_i; + if (timeout) + goto out; + + timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? NM_CON_DEFAULT ("ipv4.dhcp-timeout") + : NM_CON_DEFAULT ("ipv6.dhcp-timeout"), + self, + 0, G_MAXINT32, 0); + if (timeout) + goto out; + + klass = NM_DEVICE_GET_CLASS (self); + if (klass->get_dhcp_timeout_for_device) { + timeout = klass->get_dhcp_timeout_for_device (self, addr_family); + if (timeout) + goto out; + } + + timeout = NM_DHCP_TIMEOUT_DEFAULT; + +out: + G_STATIC_ASSERT_EXPR (G_MAXINT32 == NM_DHCP_TIMEOUT_INFINITY); + nm_assert (timeout > 0); + nm_assert (timeout <= G_MAXINT32); + return timeout; +} + static void dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) { @@ -7481,6 +7550,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) priv->dhcp4.was_active = FALSE; nm_clear_g_source (&priv->dhcp4.grace_id); + priv->dhcp4.grace_pending = FALSE; g_clear_pointer (&priv->dhcp4.pac_url, g_free); g_clear_pointer (&priv->dhcp4.root_path, g_free); @@ -7723,9 +7793,10 @@ ip_config_merge_and_apply (NMDevice *self, } static gboolean -dhcp4_lease_change (NMDevice *self, NMIP4Config *config) +dhcp4_lease_change (NMDevice *self, NMIP4Config *config, gboolean bound) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gs_free_error GError *error = NULL; g_return_val_if_fail (config, FALSE); @@ -7736,6 +7807,15 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) return FALSE; } + /* TODO: we should perform DAD again whenever we obtain a + * new lease after an expiry. But what should we do if + * a duplicate address is detected? Fail the connection; + * restart DHCP; continue without an address? */ + if (bound && !nm_dhcp_client_accept (priv->dhcp4.client, &error)) { + _LOGW (LOGD_DHCP4, "error accepting lease: %s", error->message); + return FALSE; + } + nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE, self, NULL, @@ -7751,6 +7831,7 @@ dhcp4_grace_period_expired (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); priv->dhcp4.grace_id = 0; + priv->dhcp4.grace_pending = FALSE; _LOGI (LOGD_DHCP4, "DHCPv4: grace period expired"); nm_device_ip_method_failed (self, AF_INET, @@ -7798,13 +7879,26 @@ dhcp4_fail (NMDevice *self, NMDhcpState dhcp_state) /* In any other case (expired lease, assumed connection, etc.), * wait for some time before failing the IP method. */ - if (!priv->dhcp4.grace_id) { - priv->dhcp4.grace_id = g_timeout_add_seconds (DHCP_GRACE_PERIOD_SEC, - dhcp4_grace_period_expired, - self); - _LOGI (LOGD_DHCP4, - "DHCPv4: %u seconds grace period started", - DHCP_GRACE_PERIOD_SEC); + if (!priv->dhcp4.grace_pending) { + guint32 timeout; + + /* Start a grace period equal to the DHCP timeout multiplied + * by a constant factor. */ + timeout = get_dhcp_timeout (self, AF_INET); + if (timeout == NM_DHCP_TIMEOUT_INFINITY) { + _LOGI (LOGD_DHCP4, "DHCPv4: trying to acquire a new lease"); + } else { + timeout = dhcp_grace_period_from_timeout (timeout); + _LOGI (LOGD_DHCP4, + "DHCPv4: trying to acquire a new lease within %u seconds", + timeout); + nm_assert (!priv->dhcp4.grace_id); + priv->dhcp4.grace_id = g_timeout_add_seconds (timeout, + dhcp4_grace_period_expired, + self); + } + + priv->dhcp4.grace_pending = TRUE; goto clear_config; } return; @@ -7853,6 +7947,7 @@ dhcp4_state_changed (NMDhcpClient *client, switch (state) { case NM_DHCP_STATE_BOUND: + case NM_DHCP_STATE_EXTENDED: if (!ip4_config) { _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event."); dhcp4_fail (self, state); @@ -7860,6 +7955,7 @@ dhcp4_state_changed (NMDhcpClient *client, } nm_clear_g_source (&priv->dhcp4.grace_id); + priv->dhcp4.grace_pending = FALSE; /* After some failures, we have been able to renew the lease: * update the ip state @@ -7895,7 +7991,8 @@ dhcp4_state_changed (NMDhcpClient *client, ipv4_dad_start (self, configs, dhcp4_dad_cb); } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { - if (dhcp4_lease_change (self, ip4_config)) + if (dhcp4_lease_change (self, ip4_config, + state == NM_DHCP_STATE_BOUND)) nm_device_update_metered (self); else dhcp4_fail (self, state); @@ -7919,41 +8016,6 @@ dhcp4_state_changed (NMDhcpClient *client, } } -static int -get_dhcp_timeout (NMDevice *self, int addr_family) -{ - NMDeviceClass *klass; - NMConnection *connection; - NMSettingIPConfig *s_ip; - guint32 timeout; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert_addr_family (addr_family); - - connection = nm_device_get_applied_connection (self); - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - - timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip); - if (timeout) - return timeout; - - timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.dhcp-timeout") - : NM_CON_DEFAULT ("ipv6.dhcp-timeout"), - self, - 0, G_MAXINT32, 0); - if (timeout) - return timeout; - - klass = NM_DEVICE_GET_CLASS (self); - if (klass->get_dhcp_timeout) - timeout = klass->get_dhcp_timeout (self, addr_family); - - return timeout ?: NM_DHCP_TIMEOUT_DEFAULT; -} - /** * dhcp_get_iaid: * @self: the #NMDevice @@ -8520,6 +8582,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) applied_config_clear (&priv->dhcp6.ip6_config); g_clear_pointer (&priv->dhcp6.event_id, g_free); nm_clear_g_source (&priv->dhcp6.grace_id); + priv->dhcp6.grace_pending = FALSE; if (priv->dhcp6.client) { nm_clear_g_signal_handler (priv->dhcp6.client, &priv->dhcp6.state_sigid); @@ -8575,6 +8638,7 @@ dhcp6_grace_period_expired (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); priv->dhcp6.grace_id = 0; + priv->dhcp6.grace_pending = FALSE; _LOGI (LOGD_DHCP6, "DHCPv6: grace period expired"); nm_device_ip_method_failed (self, AF_INET6, @@ -8626,13 +8690,26 @@ dhcp6_fail (NMDevice *self, NMDhcpState dhcp_state) /* In any other case (expired lease, assumed connection, etc.), * wait for some time before failing the IP method. */ - if (!priv->dhcp6.grace_id) { - priv->dhcp6.grace_id = g_timeout_add_seconds (DHCP_GRACE_PERIOD_SEC, - dhcp6_grace_period_expired, - self); - _LOGI (LOGD_DHCP6, - "DHCPv6: %u seconds grace period started", - DHCP_GRACE_PERIOD_SEC); + if (!priv->dhcp6.grace_pending) { + guint32 timeout; + + /* Start a grace period equal to the DHCP timeout multiplied + * by a constant factor. */ + timeout = get_dhcp_timeout (self, AF_INET6); + if (timeout == NM_DHCP_TIMEOUT_INFINITY) + _LOGI (LOGD_DHCP6, "DHCPv6: trying to acquire a new lease"); + else { + timeout = dhcp_grace_period_from_timeout (timeout); + _LOGI (LOGD_DHCP6, + "DHCPv6: trying to acquire a new lease within %u seconds", + timeout); + nm_assert (!priv->dhcp6.grace_id); + priv->dhcp6.grace_id = g_timeout_add_seconds (timeout, + dhcp6_grace_period_expired, + self); + } + + priv->dhcp6.grace_pending = TRUE; goto clear_config; } } else { @@ -8670,7 +8747,9 @@ dhcp6_state_changed (NMDhcpClient *client, switch (state) { case NM_DHCP_STATE_BOUND: + case NM_DHCP_STATE_EXTENDED: nm_clear_g_source (&priv->dhcp6.grace_id); + priv->dhcp6.grace_pending = FALSE; /* If the server sends multiple IPv6 addresses, we receive a state * changed event for each of them. Use the event ID to merge IPv6 * addresses from the same transaction into a single configuration. @@ -10016,7 +10095,7 @@ addrconf6_start_with_link_ready (NMDevice *self) G_CALLBACK (ndisc_config_changed), self); priv->ndisc_timeout_id = g_signal_connect (priv->ndisc, - NM_NDISC_RA_TIMEOUT, + NM_NDISC_RA_TIMEOUT_SIGNAL, G_CALLBACK (ndisc_ra_timeout), self); @@ -10035,6 +10114,28 @@ ndisc_node_type (NMDevice *self) return NM_NDISC_NODE_TYPE_HOST; } +static gint32 +get_ra_timeout (NMDevice *self) +{ + NMConnection *connection; + gint32 timeout; + + G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_DEFAULT == 0); + G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_INFINITY == G_MAXINT32); + + connection = nm_device_get_applied_connection (self); + + timeout = nm_setting_ip6_config_get_ra_timeout (NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection))); + nm_assert (timeout >= 0); + if (timeout) + return timeout; + + return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, + NM_CON_DEFAULT ("ipv6.ra-timeout"), + self, + 0, G_MAXINT32, 0); +} + static gboolean addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) { @@ -10065,6 +10166,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) stable_id, nm_setting_ip6_config_get_addr_gen_mode (s_ip6), ndisc_node_type (self), + get_ra_timeout (self), &error); if (!priv->ndisc) { _LOGE (LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message); @@ -15515,6 +15617,12 @@ _set_state_full (NMDevice *self, reason_to_string_a (reason), _sys_iface_state_to_str (priv->sys_iface_state)); + /* in order to prevent triggering any callback caused + * by the device not having any pending action anymore + * we add one here that gets removed at the end of the function */ + nm_device_add_pending_action (self, + NM_PENDING_ACTION_IN_STATE_CHANGE, + TRUE); priv->in_state_changed = TRUE; priv->state = state; @@ -15821,6 +15929,9 @@ _set_state_full (NMDevice *self, g_object_unref (req); priv->in_state_changed = FALSE; + nm_device_remove_pending_action (self, + NM_PENDING_ACTION_IN_STATE_CHANGE, + TRUE); if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED)) _notify (self, PROP_MANAGED); @@ -17507,6 +17618,7 @@ nm_device_class_init (NMDeviceClass *klass) klass->get_type_description = get_type_description; klass->can_auto_connect = can_auto_connect; + klass->can_update_from_platform_link = can_update_from_platform_link; klass->check_connection_compatible = check_connection_compatible; klass->check_connection_available = check_connection_available; klass->can_unmanaged_external_down = can_unmanaged_external_down; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 518c66ca..8c6c856e 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -53,6 +53,7 @@ nm_device_state_reason_check (NMDeviceStateReason reason) } #define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate" +#define NM_PENDING_ACTION_IN_STATE_CHANGE "in-state-change" #define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available" #define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait" #define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant" @@ -436,11 +437,13 @@ typedef struct _NMDeviceClass { NMConnection *con_old, NMConnection *con_new); - guint32 (* get_dhcp_timeout) (NMDevice *self, - int addr_family); + guint32 (* get_dhcp_timeout_for_device) (NMDevice *self, + int addr_family); gboolean (* get_guessed_metered) (NMDevice *self); + gboolean (* can_update_from_platform_link) (NMDevice *self, const NMPlatformLink *plink); + /* Controls, whether to call act_stage2_config() callback also for assuming * a device or for external activations. In this case, act_stage2_config() must * take care not to touch the device's configuration. */ diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c index 726e9901..2868dee0 100644 --- a/src/devices/ovs/nm-device-ovs-interface.c +++ b/src/devices/ovs/nm-device-ovs-interface.c @@ -98,10 +98,12 @@ link_changed (NMDevice *device, { NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (device); - if ( pllink - && priv->waiting_for_interface - && nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { - priv->waiting_for_interface = FALSE; + if (!pllink || !priv->waiting_for_interface) + return; + + priv->waiting_for_interface = FALSE; + + if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { nm_device_bring_up (device, TRUE, NULL); nm_device_activate_schedule_stage3_ip_config_start (device); } @@ -125,12 +127,14 @@ act_stage3_ip_config_start (NMDevice *device, gpointer *out_config, NMDeviceStateReason *out_failure_reason) { + NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (device); if (!_is_internal_interface (device)) return NM_ACT_STAGE_RETURN_IP_FAIL; if (nm_device_get_ip_ifindex (device) <= 0) { + _LOGT (LOGD_DEVICE, "waiting for link to appear"); priv->waiting_for_interface = TRUE; return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -153,6 +157,160 @@ deactivate (NMDevice *device) priv->waiting_for_interface = FALSE; } +typedef struct { + NMDeviceOvsInterface *self; + GCancellable *cancellable; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gulong link_changed_id; + gulong cancelled_id; + guint link_timeout_id; +} DeactivateData; + +static void +deactivate_invoke_cb (DeactivateData *data, GError *error) +{ + NMDeviceOvsInterface *self = data->self; + + _LOGT (LOGD_CORE, + "deactivate: async callback (%s)", + error ? error->message : "success"); + data->callback (NM_DEVICE (data->self), + error, + data->callback_user_data); + + nm_clear_g_signal_handler (nm_device_get_platform (NM_DEVICE (data->self)), + &data->link_changed_id); + nm_clear_g_signal_handler (data->cancellable, + &data->cancelled_id); + nm_clear_g_source (&data->link_timeout_id); + g_object_unref (data->self); + g_object_unref (data->cancellable); + nm_g_slice_free (data); +} + +static void +deactivate_link_changed_cb (NMPlatform *platform, + int obj_type_i, + int ifindex, + NMPlatformLink *info, + int change_type_i, + DeactivateData *data) +{ + NMDeviceOvsInterface *self = data->self; + const NMPlatformSignalChangeType change_type = change_type_i; + + if ( change_type == NM_PLATFORM_SIGNAL_REMOVED + && nm_streq0 (info->name, nm_device_get_iface (NM_DEVICE (self)))) { + _LOGT (LOGD_DEVICE, "deactivate: link removed, proceeding"); + nm_device_update_from_platform_link (NM_DEVICE (self), NULL); + deactivate_invoke_cb (data, NULL); + return; + } +} + +static gboolean +deactivate_link_timeout (gpointer user_data) +{ + DeactivateData *data = user_data; + NMDeviceOvsInterface *self = data->self; + + _LOGT (LOGD_DEVICE, "deactivate: timeout waiting link removal"); + deactivate_invoke_cb (data, NULL); + return G_SOURCE_REMOVE; +} + +static void +deactivate_cancelled_cb (GCancellable *cancellable, + gpointer user_data) +{ + gs_free_error GError *error = NULL; + + nm_utils_error_set_cancelled (&error, FALSE, NULL); + deactivate_invoke_cb ((DeactivateData *) user_data, error); +} + +static void +deactivate_cb_on_idle (gpointer user_data, + GCancellable *cancellable) +{ + DeactivateData *data = user_data; + gs_free_error GError *cancelled_error = NULL; + + g_cancellable_set_error_if_cancelled (data->cancellable, &cancelled_error); + deactivate_invoke_cb (data, cancelled_error); +} + +static void +deactivate_async (NMDevice *device, + GCancellable *cancellable, + NMDeviceDeactivateCallback callback, + gpointer callback_user_data) { + + NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (self); + DeactivateData *data; + + _LOGT (LOGD_CORE, "deactivate: start async"); + + /* We want to ensure that the kernel link for this device is + * removed upon disconnection so that it will not interfere with + * later activations of the same device. Unfortunately there is + * no synchronization mechanism with vswitchd, we only update + * ovsdb and wait that changes are picked up. + */ + + data = g_slice_new (DeactivateData); + *data = (DeactivateData) { + .self = g_object_ref (self), + .cancellable = g_object_ref (cancellable), + .callback = callback, + .callback_user_data = callback_user_data, + }; + + if ( !priv->waiting_for_interface + && !nm_platform_link_get_by_ifname (nm_device_get_platform (device), + nm_device_get_iface (device))) { + _LOGT (LOGD_CORE, "deactivate: link not present, proceeding"); + nm_device_update_from_platform_link (NM_DEVICE (self), NULL); + nm_utils_invoke_on_idle (deactivate_cb_on_idle, data, cancellable); + return; + } + + if (priv->waiting_for_interface) { + /* At this point we have issued an INSERT and a DELETE + * command for the interface to ovsdb. We don't know if + * vswitchd will see the two updates or only one. We + * must add a timeout to avoid waiting forever in case + * the link doesn't appear. + */ + data->link_timeout_id = g_timeout_add (6000, deactivate_link_timeout, data); + _LOGT (LOGD_DEVICE, "deactivate: waiting for link to disappear in 6 seconds"); + } else + _LOGT (LOGD_DEVICE, "deactivate: waiting for link to disappear"); + + data->cancelled_id = g_cancellable_connect (cancellable, + G_CALLBACK (deactivate_cancelled_cb), + data, + NULL); + data->link_changed_id = g_signal_connect (nm_device_get_platform (device), + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK (deactivate_link_changed_cb), + data); +} + +static gboolean +can_update_from_platform_link (NMDevice *device, const NMPlatformLink *plink) +{ + /* If the device is deactivating, we already sent the + * deletion command to ovsdb and we don't want to deal + * with any new link appearing from the previous + * activation. + */ + return !plink + || nm_device_get_state (device) != NM_DEVICE_STATE_DEACTIVATING; +} + /*****************************************************************************/ static void @@ -182,7 +340,9 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH); + device_class->can_update_from_platform_link = can_update_from_platform_link; device_class->deactivate = deactivate; + device_class->deactivate_async = deactivate_async; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index fb9c9c69..a0749c21 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -356,6 +356,12 @@ teamd_dbus_appeared (GDBusConnection *connection, _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); nm_device_queue_recheck_assume (device); + if (priv->kill_in_progress) { + /* If we are currently killing teamd, we are not + * interested in knowing when it becomes ready. */ + return; + } + /* If another teamd grabbed the bus name while our teamd was starting, * just ignore the death of our teamd and run with the existing one. */ @@ -380,11 +386,14 @@ teamd_dbus_appeared (GDBusConnection *connection, if (pid != priv->teamd_pid) teamd_cleanup (self, FALSE); } else { - _LOGW (LOGD_TEAM, "failed to determine D-Bus name owner"); - /* If we can't determine the bus name owner, don't kill our - * teamd instance. Hopefully another existing teamd just died and - * our instance will be able to grab the bus name. - */ + /* The process that registered on the bus died. If it's + * the teamd instance we just started, ignore the event + * as we already detect the failure through the process + * watch. If it's a previous instance that got killed, + * also ignore that as our new instance will register + * again. */ + _LOGD (LOGD_TEAM, "failed to determine D-Bus name owner, ignoring"); + return; } } diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index c19ec766..516dc78b 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -405,7 +405,7 @@ state_changed (NMDevice *device, } static guint32 -get_dhcp_timeout (NMDevice *device, int addr_family) +get_dhcp_timeout_for_device (NMDevice *device, int addr_family) { /* shorter timeout for mesh connectivity */ return 20; @@ -521,7 +521,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) device_class->act_stage1_prepare = act_stage1_prepare; device_class->act_stage2_config = act_stage2_config; device_class->state_changed = state_changed; - device_class->get_dhcp_timeout = get_dhcp_timeout; + device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; obj_properties[PROP_COMPANION] = g_param_spec_string (NM_DEVICE_OLPC_MESH_COMPANION, "", "", diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 3e6ccc8f..3de5ae07 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -732,7 +732,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) } static guint32 -get_dhcp_timeout (NMDevice *device, int addr_family) +get_dhcp_timeout_for_device (NMDevice *device, int addr_family) { /* DHCP is always done by the modem firmware, not by the network, and * by the time we get around to DHCP the firmware should already know @@ -897,7 +897,7 @@ nm_device_modem_class_init (NMDeviceModemClass *klass) device_class->is_available = is_available; device_class->get_ip_iface_identifier = get_ip_iface_identifier; device_class->get_configured_mtu = nm_modem_get_configured_mtu; - device_class->get_dhcp_timeout = get_dhcp_timeout; + device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; device_class->state_changed = device_state_changed; diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 0a07b26c..81c4ad9c 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -317,6 +317,7 @@ nm_dhcp_client_get_use_fqdn (NMDhcpClient *self) static const char *state_table[NM_DHCP_STATE_MAX + 1] = { [NM_DHCP_STATE_UNKNOWN] = "unknown", [NM_DHCP_STATE_BOUND] = "bound", + [NM_DHCP_STATE_EXTENDED] = "extended", [NM_DHCP_STATE_TIMEOUT] = "timeout", [NM_DHCP_STATE_EXPIRE] = "expire", [NM_DHCP_STATE_DONE] = "done", @@ -336,13 +337,14 @@ static NMDhcpState reason_to_state (NMDhcpClient *self, const char *iface, const char *reason) { 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) + g_ascii_strcasecmp (reason, "bound6") == 0) return NM_DHCP_STATE_BOUND; + else if (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_EXTENDED; else if (g_ascii_strcasecmp (reason, "timeout") == 0) return NM_DHCP_STATE_TIMEOUT; else if (g_ascii_strcasecmp (reason, "nak") == 0 || @@ -415,7 +417,7 @@ nm_dhcp_client_set_state (NMDhcpClient *self, NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); gs_free char *event_id = NULL; - if (new_state == NM_DHCP_STATE_BOUND) { + if (NM_IN_SET (new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) { g_return_if_fail (NM_IS_IP_CONFIG (ip_config, priv->addr_family)); g_return_if_fail (options); } else { @@ -430,10 +432,11 @@ nm_dhcp_client_set_state (NMDhcpClient *self, /* The client may send same-state transitions for RENEW/REBIND events and * the lease may have changed, so handle same-state transitions for the - * BOUND state. Ignore same-state transitions for other events since - * the lease won't have changed and the state was already handled. + * EXTENDED and BOUND states. Ignore same-state transitions for other + * events since the lease won't have changed and the state was already handled. */ - if ((priv->state == new_state) && (new_state != NM_DHCP_STATE_BOUND)) + if ( (priv->state == new_state) + && !NM_IN_SET (new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) return; if (_LOGI_ENABLED ()) { @@ -448,7 +451,7 @@ nm_dhcp_client_set_state (NMDhcpClient *self, } if ( priv->addr_family == AF_INET6 - && new_state == NM_DHCP_STATE_BOUND) { + && NM_IN_SET (new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) { char *start, *iaid; iaid = g_hash_table_lookup (options, "iaid"); @@ -877,7 +880,7 @@ nm_dhcp_client_handle_event (gpointer unused, _LOGD ("DHCP state '%s' -> '%s' (reason: '%s')", state_to_string (old_state), state_to_string (new_state), reason); - if (new_state == NM_DHCP_STATE_BOUND) { + if (NM_IN_SET (new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED)) { GVariantIter iter; const char *name; GVariant *value; @@ -918,7 +921,7 @@ nm_dhcp_client_handle_event (gpointer unused, nm_dhcp_client_emit_ipv6_prefix_delegated (self, &prefix); } else { /* Fail if no valid IP config was received */ - if ( new_state == NM_DHCP_STATE_BOUND + if ( NM_IN_SET (new_state, NM_DHCP_STATE_BOUND, NM_DHCP_STATE_EXTENDED) && !ip_config) { _LOGW ("client bound but IP config not received"); new_state = NM_DHCP_STATE_FAIL; @@ -1007,8 +1010,8 @@ set_property (GObject *object, guint prop_id, case PROP_IFACE: /* construct-only */ priv->iface = g_value_dup_string (value); - g_return_if_fail ( priv->iface - && nm_utils_is_valid_iface_name (priv->iface, NULL)); + g_return_if_fail (priv->iface); + nm_assert (nm_utils_ifname_valid_kernel (priv->iface, NULL)); break; case PROP_IFINDEX: /* construct-only */ @@ -1200,6 +1203,7 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + G_STATIC_ASSERT_EXPR (G_MAXINT32 == NM_DHCP_TIMEOUT_INFINITY); obj_properties[PROP_TIMEOUT] = g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, "", "", 1, G_MAXINT32, NM_DHCP_TIMEOUT_DEFAULT, diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 6a431fa8..1ff09067 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -12,8 +12,8 @@ #include "nm-ip6-config.h" #include "nm-dhcp-utils.h" -#define NM_DHCP_TIMEOUT_DEFAULT ((guint32) 45) /* default DHCP timeout, in seconds */ -#define NM_DHCP_TIMEOUT_INFINITY G_MAXINT32 +#define NM_DHCP_TIMEOUT_DEFAULT ((guint32) 45) /* default DHCP timeout, in seconds */ +#define NM_DHCP_TIMEOUT_INFINITY ((guint32) G_MAXINT32) #define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ()) #define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClient)) @@ -43,7 +43,8 @@ typedef enum { NM_DHCP_STATE_UNKNOWN = 0, - NM_DHCP_STATE_BOUND, /* new lease or lease changed */ + NM_DHCP_STATE_BOUND, /* new lease */ + NM_DHCP_STATE_EXTENDED, /* lease extended */ NM_DHCP_STATE_TIMEOUT, /* timed out contacting server */ NM_DHCP_STATE_DONE, /* client quit or stopped */ NM_DHCP_STATE_EXPIRE, /* lease expired or NAKed */ diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index b4c0a451..45ff46f5 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -977,7 +977,7 @@ lease_save (NMDhcpNettools *self, NDhcp4ClientLease *lease, const char *lease_fi } static void -bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease) +bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease, gboolean extended) { NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); @@ -985,7 +985,7 @@ bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease) gs_unref_hashtable GHashTable *options = NULL; GError *error = NULL; - _LOGT ("lease available"); + _LOGT ("lease available (%s)", extended ? "extended" : "new"); ip4_config = lease_to_ip4_config (nm_dhcp_client_get_multi_idx (NM_DHCP_CLIENT (self)), iface, @@ -1006,7 +1006,7 @@ bound4_handle (NMDhcpNettools *self, NDhcp4ClientLease *lease) lease_save (self, lease, priv->lease_file); nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), - NM_DHCP_STATE_BOUND, + extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND, NM_IP_CONFIG_CAST (ip4_config), options); } @@ -1037,10 +1037,10 @@ dhcp4_event_handle (NMDhcpNettools *self, break; case N_DHCP4_CLIENT_EVENT_GRANTED: priv->lease = n_dhcp4_client_lease_ref (event->granted.lease); - bound4_handle (self, event->granted.lease); + bound4_handle (self, event->granted.lease, FALSE); break; case N_DHCP4_CLIENT_EVENT_EXTENDED: - bound4_handle (self, event->extended.lease); + bound4_handle (self, event->extended.lease, TRUE); break; case N_DHCP4_CLIENT_EVENT_DOWN: /* ignore down events, they are purely informational */ @@ -1064,8 +1064,18 @@ dhcp4_event_cb (GIOChannel *source, int r; r = n_dhcp4_client_dispatch (priv->client); - if (r < 0) - return G_SOURCE_CONTINUE; + if (r < 0) { + /* FIXME: if any operation (e.g. send()) fails during the + * dispatch, n-dhcp4 returns an error without arming timers + * or progressing state, so the only reasonable thing to do + * is to move to failed state so that the client will be + * restarted. Ideally n-dhcp4 should retry failed operations + * a predefined number of times (possibly infinite). + */ + _LOGE ("error %d dispatching events", r); + nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); + return G_SOURCE_REMOVE; + } while (!n_dhcp4_client_pop_event (priv->client, &event) && event) { dhcp4_event_handle (self, event); diff --git a/src/dhcp/nm-dhcp-options.c b/src/dhcp/nm-dhcp-options.c index 4c003f31..1d391f3e 100644 --- a/src/dhcp/nm-dhcp-options.c +++ b/src/dhcp/nm-dhcp-options.c @@ -34,7 +34,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = { REQ (NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, "nis_domain", TRUE ), REQ (NM_DHCP_OPTION_DHCP4_NIS_SERVERS, "nis_servers", TRUE ), REQ (NM_DHCP_OPTION_DHCP4_NTP_SERVER, "ntp_servers", TRUE ), - REQ (NM_DHCP_OPTION_DHCP4_SERVER_ID, "dhcp_server_identifier", TRUE ), + REQ (NM_DHCP_OPTION_DHCP4_SERVER_ID, "dhcp_server_identifier", FALSE ), REQ (NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, "domain_search", TRUE ), REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE, "ms_classless_static_routes", TRUE ), REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, "wpad", TRUE ), diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 1518d465..6e6aa243 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -477,7 +477,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx, /*****************************************************************************/ static void -bound4_handle (NMDhcpSystemd *self) +bound4_handle (NMDhcpSystemd *self, gboolean extended) { NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); @@ -514,7 +514,7 @@ bound4_handle (NMDhcpSystemd *self) dhcp_lease_save (lease, priv->lease_file); nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), - NM_DHCP_STATE_BOUND, + extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND, NM_IP_CONFIG_CAST (ip4_config), options); } @@ -538,8 +538,10 @@ dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data) break; case SD_DHCP_CLIENT_EVENT_RENEW: case SD_DHCP_CLIENT_EVENT_IP_CHANGE: + bound4_handle (self, TRUE); + break; case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE: - bound4_handle (self); + bound4_handle (self, FALSE); break; case SD_DHCP_CLIENT_EVENT_SELECTING: break; diff --git a/src/initrd/nmi-cmdline-reader.c b/src/initrd/nmi-cmdline-reader.c index c32ef1cf..2cb93a2d 100644 --- a/src/initrd/nmi-cmdline-reader.c +++ b/src/initrd/nmi-cmdline-reader.c @@ -195,6 +195,47 @@ _base_setting_set (NMConnection *connection, const char *property, const char *v } static void +read_all_connections_from_fw (GHashTable *connections, const char *sysfs_dir) +{ + gs_unref_hashtable GHashTable *ibft = NULL; + NMConnection *connection; + GHashTableIter iter; + const char *mac; + GHashTable *nic; + const char *index; + GError *error = NULL; + + ibft = nmi_ibft_read (sysfs_dir); + + g_hash_table_iter_init (&iter, ibft); + while (g_hash_table_iter_next (&iter, (gpointer *) &mac, (gpointer *) &nic)) { + connection = nm_simple_connection_new (); + + index = g_hash_table_lookup (nic, "index"); + if (!index) { + _LOGW (LOGD_CORE, "Ignoring an iBFT entry without an index"); + continue; + } + + if (!nmi_ibft_update_connection_from_nic (connection, nic, &error)) { + _LOGW (LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); + g_error_free (error); + } + + g_hash_table_insert (connections, + g_strdup_printf ("ibft%s", index), + connection); + } + + connection = nmi_dt_reader_parse (sysfs_dir); + if (connection) { + g_hash_table_insert (connections, + g_strdup ("ofw"), + connection); + } +} + +static void parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) { NMConnection *connection; @@ -258,44 +299,7 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) if (ifname == NULL && ( g_strcmp0 (kind, "fw") == 0 || g_strcmp0 (kind, "ibft") == 0)) { - GHashTableIter iter; - const char *mac; - GHashTable *nic; - const char *index; - - /* This is the ip=ibft case. Just take all we got from iBFT - * and don't process anything else, since there's no ifname - * specified to apply it to. */ - if (!ibft) - ibft = nmi_ibft_read (sysfs_dir); - - g_hash_table_iter_init (&iter, ibft); - while (g_hash_table_iter_next (&iter, (gpointer)&mac, (gpointer)&nic)) { - connection = nm_simple_connection_new (); - - index = g_hash_table_lookup (nic, "index"); - if (!index) { - _LOGW (LOGD_CORE, "Ignoring an iBFT entry without an index"); - continue; - } - - if (!nmi_ibft_update_connection_from_nic (connection, nic, &error)) { - _LOGW (LOGD_CORE, "Unable to merge iBFT configuration: %s", error->message); - g_error_free (error); - } - - g_hash_table_insert (connections, - g_strdup_printf ("ibft%s", index), - connection); - } - - connection = nmi_dt_reader_parse (sysfs_dir); - if (connection) { - g_hash_table_insert (connections, - g_strdup ("ofw"), - connection); - } - + read_all_connections_from_fw (connections, sysfs_dir); return; } @@ -421,8 +425,7 @@ parse_ip (GHashTable *connections, const char *sysfs_dir, char *argument) if (mac) { g_strchomp (mac); mac_up = g_ascii_strup (mac, -1); - if (!ibft) - ibft = nmi_ibft_read (sysfs_dir); + ibft = nmi_ibft_read (sysfs_dir); nic = g_hash_table_lookup (ibft, mac_up); if (!nic) _LOGW (LOGD_CORE, "No iBFT NIC for %s (%s)", ifname, mac_up); @@ -838,6 +841,8 @@ nmi_cmdline_reader_parse (const char *sysfs_dir, const char *const*argv) parse_nameserver (connections, argument); else if (strcmp (tag, "rd.peerdns") == 0) parse_rd_peerdns (connections, argument); + else if (strcmp (tag, "rd.iscsi.ibft") == 0 && _nm_utils_ascii_str_to_bool (argument, TRUE)) + read_all_connections_from_fw (connections, sysfs_dir); else if (strcmp (tag, "rd.bootif") == 0) ignore_bootif = !_nm_utils_ascii_str_to_bool (argument, TRUE); else if (strcmp (tag, "rd.neednet") == 0) diff --git a/src/initrd/nmi-ibft-reader.c b/src/initrd/nmi-ibft-reader.c index ffce98fc..47b90ebf 100644 --- a/src/initrd/nmi-ibft-reader.c +++ b/src/initrd/nmi-ibft-reader.c @@ -296,6 +296,7 @@ connection_setting_add (GHashTable *nic, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_INTERFACE_NAME, NULL, NULL); g_free (uuid); diff --git a/src/initrd/tests/test-cmdline-reader.c b/src/initrd/tests/test-cmdline-reader.c index 1d4bb9a6..8951e491 100644 --- a/src/initrd/tests/test-cmdline-reader.c +++ b/src/initrd/tests/test-cmdline-reader.c @@ -768,10 +768,30 @@ test_team (void) } static void -test_ibft (void) +test_ibft_ip_dev (void) +{ + const char *const*ARGV = NM_MAKE_STRV ("ip=eth0:ibft"); + gs_unref_hashtable GHashTable *connections = NULL; + NMSettingConnection *s_con; + NMConnection *connection; + + connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); + g_assert (connections); + g_assert_cmpint (g_hash_table_size (connections), ==, 1); + + connection = g_hash_table_lookup (connections, "eth0"); + g_assert (connection); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, NULL); +} + +static void +_test_ibft_ip (const char *const*ARGV) { gs_unref_hashtable GHashTable *connections = NULL; - const char *const*ARGV = NM_MAKE_STRV ("ip=ibft"); NMConnection *connection; connections = nmi_cmdline_reader_parse (TEST_INITRD_DIR "/sysfs", ARGV); @@ -782,11 +802,29 @@ test_ibft (void) g_assert (connection); nmtst_assert_connection_verifies_without_normalization (connection); g_assert_cmpstr (nm_connection_get_id (connection), ==, "iBFT VLAN Connection 0"); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, NULL); connection = g_hash_table_lookup (connections, "ibft2"); g_assert (connection); nmtst_assert_connection_verifies_without_normalization (connection); g_assert_cmpstr (nm_connection_get_id (connection), ==, "iBFT Connection 2"); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, NULL); +} + +static void +test_ibft_ip (void) +{ + const char *const*ARGV = NM_MAKE_STRV ("ip=ibft"); + + _test_ibft_ip (ARGV); +} + +static void +test_ibft_rd_iscsi_ibft (void) +{ + const char *const*ARGV = NM_MAKE_STRV ("rd.iscsi.ibft"); + + _test_ibft_ip (ARGV); } static void @@ -1045,7 +1083,9 @@ int main (int argc, char **argv) g_test_add_func ("/initrd/cmdline/team", test_team); g_test_add_func ("/initrd/cmdline/bridge", test_bridge); g_test_add_func ("/initrd/cmdline/bridge/default", test_bridge_default); - g_test_add_func ("/initrd/cmdline/ibft", test_ibft); + g_test_add_func ("/initrd/cmdline/ibft/ip_dev", test_ibft_ip_dev); + g_test_add_func ("/initrd/cmdline/ibft/ip", test_ibft_ip); + g_test_add_func ("/initrd/cmdline/ibft/rd_iscsi_ibft", test_ibft_rd_iscsi_ibft); g_test_add_func ("/initrd/cmdline/ignore_extra", test_ignore_extra); g_test_add_func ("/initrd/cmdline/rd_znet", test_rd_znet); g_test_add_func ("/initrd/cmdline/rd_znet/legacy", test_rd_znet_legacy); diff --git a/src/initrd/tests/test-ibft-reader.c b/src/initrd/tests/test-ibft-reader.c index 932c1a48..f7709543 100644 --- a/src/initrd/tests/test-ibft-reader.c +++ b/src/initrd/tests/test-ibft-reader.c @@ -65,6 +65,7 @@ test_read_ibft_dhcp (void) g_assert (s_con); g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT Connection 1"); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, NULL); g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); g_assert (nm_setting_connection_get_autoconnect (s_con)); @@ -109,6 +110,7 @@ test_read_ibft_static (void) g_assert (s_con); g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT Connection 0"); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, NULL); g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); g_assert (nm_setting_connection_get_autoconnect (s_con)); @@ -178,6 +180,7 @@ test_read_ibft_vlan (void) s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_VLAN_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, NULL); /* ===== WIRED SETTING ===== */ s_wired = nm_connection_get_setting_wired (connection); diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 8077099f..6f2815ef 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -557,6 +557,7 @@ nm_lndp_ndisc_new (NMPlatform *platform, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, NMNDiscNodeType node_type, + gint32 ra_timeout, GError **error) { nm_auto_pop_netns NMPNetns *netns = NULL; @@ -582,6 +583,7 @@ nm_lndp_ndisc_new (NMPlatform *platform, NM_NDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, "max_addresses", 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT), + NM_NDISC_RA_TIMEOUT, (int) ra_timeout, NM_NDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname, "router_solicitations", 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT), diff --git a/src/ndisc/nm-lndp-ndisc.h b/src/ndisc/nm-lndp-ndisc.h index 22f21e41..82e7b2de 100644 --- a/src/ndisc/nm-lndp-ndisc.h +++ b/src/ndisc/nm-lndp-ndisc.h @@ -28,6 +28,7 @@ NMNDisc *nm_lndp_ndisc_new (NMPlatform *platform, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, NMNDiscNodeType node_type, + gint32 ra_timeout, GError **error); #endif /* __NETWORKMANAGER_LNDP_NDISC_H__ */ diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index 41201e24..0afca26b 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -48,6 +48,7 @@ struct _NMNDiscPrivate { char *network_id; NMSettingIP6ConfigAddrGenMode addr_gen_mode; NMUtilsStableType stable_type; + gint32 ra_timeout; gint32 max_addresses; gint32 router_solicitations; gint32 router_solicitation_interval; @@ -67,6 +68,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_NETWORK_ID, PROP_ADDR_GEN_MODE, PROP_MAX_ADDRESSES, + PROP_RA_TIMEOUT, PROP_ROUTER_SOLICITATIONS, PROP_ROUTER_SOLICITATION_INTERVAL, PROP_NODE_TYPE, @@ -74,7 +76,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( enum { CONFIG_RECEIVED, - RA_TIMEOUT, + RA_TIMEOUT_SIGNAL, LAST_SIGNAL }; @@ -898,7 +900,7 @@ ndisc_ra_timeout_cb (gpointer user_data) NMNDisc *ndisc = NM_NDISC (user_data); NM_NDISC_GET_PRIVATE (ndisc)->ra_timeout_id = 0; - g_signal_emit (ndisc, signals[RA_TIMEOUT], 0); + g_signal_emit (ndisc, signals[RA_TIMEOUT_SIGNAL], 0); return G_SOURCE_REMOVE; } @@ -906,34 +908,46 @@ void nm_ndisc_start (NMNDisc *ndisc) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); - NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); - gint64 ra_wait_secs; + NMNDiscPrivate *priv; + + g_return_if_fail (NM_IS_NDISC (ndisc)); + + priv = NM_NDISC_GET_PRIVATE (ndisc); - g_return_if_fail (klass->start); - g_return_if_fail (!priv->ra_timeout_id); + nm_assert (NM_NDISC_GET_CLASS (ndisc)->start); + nm_assert (!priv->ra_timeout_id); - _LOGD ("starting neighbor discovery: %d", priv->ifindex); + _LOGD ("starting neighbor discovery for ifindex %d%s", + priv->ifindex, + priv->node_type == NM_NDISC_NODE_TYPE_HOST + ? " (solicit)" + : " (announce)"); if (!nm_ndisc_netns_push (ndisc, &netns)) return; - klass->start (ndisc); + NM_NDISC_GET_CLASS (ndisc)->start (ndisc); + + if (priv->node_type == NM_NDISC_NODE_TYPE_HOST) { + gint32 ra_timeout = priv->ra_timeout; - switch (priv->node_type) { - case NM_NDISC_NODE_TYPE_HOST: - ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; - ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); - priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); - _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); + G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_DEFAULT == 0); + G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_INFINITY == G_MAXINT32); + if (ra_timeout != NM_RA_TIMEOUT_INFINITY) { + if (ra_timeout == NM_RA_TIMEOUT_DEFAULT) { + ra_timeout = NM_MAX ((((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1, + 30); + } + nm_assert (ra_timeout > 0 && ra_timeout < NM_RA_TIMEOUT_INFINITY); + _LOGD ("scheduling RA timeout in %d seconds", ra_timeout); + priv->ra_timeout_id = g_timeout_add_seconds (ra_timeout, ndisc_ra_timeout_cb, ndisc); + } solicit_routers (ndisc); - break; - case NM_NDISC_NODE_TYPE_ROUTER: - announce_router_initial (ndisc); - break; - default: - g_assert_not_reached (); + return; } + + nm_assert (priv->node_type == NM_NDISC_NODE_TYPE_ROUTER); + announce_router_initial (ndisc); } NMNDiscConfigMap @@ -1312,6 +1326,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->max_addresses = g_value_get_int (value); break; + case PROP_RA_TIMEOUT: + /* construct-only */ + priv->ra_timeout = g_value_get_int (value); + break; case PROP_ROUTER_SOLICITATIONS: /* construct-only */ priv->router_solicitations = g_value_get_int (value); @@ -1323,6 +1341,8 @@ set_property (GObject *object, guint prop_id, case PROP_NODE_TYPE: /* construct-only */ priv->node_type = g_value_get_int (value); + nm_assert (NM_IN_SET (priv->node_type, NM_NDISC_NODE_TYPE_HOST, + NM_NDISC_NODE_TYPE_ROUTER)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1401,8 +1421,8 @@ nm_ndisc_class_init (NMNDiscClass *klass) g_type_class_add_private (klass, sizeof (NMNDiscPrivate)); object_class->set_property = set_property; - object_class->dispose = dispose; - object_class->finalize = finalize; + object_class->dispose = dispose; + object_class->finalize = finalize; obj_properties[PROP_PLATFORM] = g_param_spec_object (NM_NDISC_PLATFORM, "", "", @@ -1446,6 +1466,13 @@ nm_ndisc_class_init (NMNDiscClass *klass) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + G_STATIC_ASSERT_EXPR (G_MAXINT32 == NM_RA_TIMEOUT_INFINITY); + obj_properties[PROP_RA_TIMEOUT] = + g_param_spec_int (NM_NDISC_RA_TIMEOUT, "", "", + 0, G_MAXINT32, 0, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTER_SOLICITATIONS] = g_param_spec_int (NM_NDISC_ROUTER_SOLICITATIONS, "", "", 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT, @@ -1473,8 +1500,8 @@ nm_ndisc_class_init (NMNDiscClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); - signals[RA_TIMEOUT] = - g_signal_new (NM_NDISC_RA_TIMEOUT, + signals[RA_TIMEOUT_SIGNAL] = + g_signal_new (NM_NDISC_RA_TIMEOUT_SIGNAL, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, 0, diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index 92295ac6..eeda38e2 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -16,6 +16,9 @@ #include "platform/nm-platform.h" #include "platform/nmp-object.h" +#define NM_RA_TIMEOUT_DEFAULT ((gint32) 0) +#define NM_RA_TIMEOUT_INFINITY G_MAXINT32 + #define NM_TYPE_NDISC (nm_ndisc_get_type ()) #define NM_NDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NDISC, NMNDisc)) #define NM_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NDISC, NMNDiscClass)) @@ -31,11 +34,12 @@ #define NM_NDISC_STABLE_TYPE "stable-type" #define NM_NDISC_NODE_TYPE "node-type" #define NM_NDISC_MAX_ADDRESSES "max-addresses" +#define NM_NDISC_RA_TIMEOUT "ra-timeout" #define NM_NDISC_ROUTER_SOLICITATIONS "router-solicitations" #define NM_NDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" -#define NM_NDISC_CONFIG_RECEIVED "config-received" -#define NM_NDISC_RA_TIMEOUT "ra-timeout" +#define NM_NDISC_CONFIG_RECEIVED "config-received" +#define NM_NDISC_RA_TIMEOUT_SIGNAL "ra-timeout-signal" typedef enum { NM_NDISC_DHCP_LEVEL_UNKNOWN, diff --git a/src/ndisc/tests/test-ndisc-linux.c b/src/ndisc/tests/test-ndisc-linux.c index e9ceaa2b..a25478e8 100644 --- a/src/ndisc/tests/test-ndisc-linux.c +++ b/src/ndisc/tests/test-ndisc-linux.c @@ -52,6 +52,7 @@ main (int argc, char **argv) "8ce666e8-d34d-4fb1-b858-f15a7al28086", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, NM_NDISC_NODE_TYPE_HOST, + 0, &error); if (!ndisc) { g_print ("Failed to create NMNDisc instance: %s\n", error->message); diff --git a/src/nm-config.c b/src/nm-config.c index a7bb3503..a0995cf9 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -430,7 +430,7 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device) * * Instead, try the interface-name... */ ifname = nm_device_get_ip_iface (device); - if (!nm_utils_is_valid_iface_name (ifname, NULL)) + if (!nm_utils_ifname_valid_kernel (ifname, NULL)) return; spec_to_free = g_strdup_printf (NM_MATCH_SPEC_INTERFACE_NAME_TAG"=%s", ifname); diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index ccac6376..e941fe7e 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -686,7 +686,6 @@ do_curl_request (NMConnectivityCheckHandle *cb_data) curl_multi_setopt (mhandle, CURLMOPT_SOCKETDATA, cb_data); curl_multi_setopt (mhandle, CURLMOPT_TIMERFUNCTION, multi_timer_cb); curl_multi_setopt (mhandle, CURLMOPT_TIMERDATA, cb_data); - curl_multi_setopt (mhandle, CURLOPT_VERBOSE, 1); switch (cb_data->addr_family) { case AF_INET: diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index fb92289f..e059994a 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2145,7 +2145,7 @@ nm_utils_sysctl_ip_conf_path (int addr_family, char *buf, const char *ifname, co nm_assert (buf); nm_assert_addr_family (addr_family); - g_assert (nm_utils_is_valid_iface_name (ifname, NULL)); + g_assert (nm_utils_ifname_valid_kernel (ifname, NULL)); property = NM_ASSERT_VALID_PATH_COMPONENT (property); len = g_snprintf (buf, @@ -2163,7 +2163,7 @@ nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char * { g_return_val_if_fail (path, FALSE); NM_ASSERT_VALID_PATH_COMPONENT (property); - g_assert (!ifname || nm_utils_is_valid_iface_name (ifname, NULL)); + g_assert (!ifname || nm_utils_ifname_valid_kernel (ifname, NULL)); if (addr_family == AF_INET) { if (!g_str_has_prefix (path, IPV4_PROPERTY_DIR)) @@ -2196,7 +2196,7 @@ nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char * return FALSE; memcpy (buf, path, l); buf[l] = '\0'; - if (!nm_utils_is_valid_iface_name (buf, NULL)) + if (!nm_utils_ifname_valid_kernel (buf, NULL)) return FALSE; path = slash + 1; } @@ -3635,7 +3635,7 @@ nm_utils_ifname_cpy (char *dst, const char *name) g_return_if_fail (dst); g_return_if_fail (name && name[0]); - nm_assert (nm_utils_is_valid_iface_name (name, NULL)); + nm_assert (nm_utils_ifname_valid_kernel (name, NULL)); /* ensures NUL padding of the entire IFNAMSIZ buffer. */ diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index bfb7af57..df70c71b 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -106,6 +106,7 @@ dhcp4_state_changed (NMDhcpClient *client, switch (state) { case NM_DHCP_STATE_BOUND: + case NM_DHCP_STATE_EXTENDED: g_assert (ip4_config); g_assert (nm_ip4_config_get_ifindex (ip4_config) == gl.ifindex); @@ -551,10 +552,14 @@ main (int argc, char *argv[]) stable_type = (global_opt.stable_id[0] - '0'); stable_id = &global_opt.stable_id[2]; } - ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, gl.ifindex, global_opt.ifname, - stable_type, stable_id, + ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, + gl.ifindex, + global_opt.ifname, + stable_type, + stable_id, global_opt.addr_gen_mode, NM_NDISC_NODE_TYPE_HOST, + NM_RA_TIMEOUT_DEFAULT, NULL); g_assert (ndisc); @@ -572,7 +577,7 @@ main (int argc, char *argv[]) G_CALLBACK (ndisc_config_changed), NULL); g_signal_connect (ndisc, - NM_NDISC_RA_TIMEOUT, + NM_NDISC_RA_TIMEOUT_SIGNAL, G_CALLBACK (ndisc_ra_timeout), NULL); nm_ndisc_start (ndisc); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3696c789..6d3a5ddb 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2011,6 +2011,20 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) return device; } + if (!find_master (self, + connection, + device, + NULL, + NULL, + NULL, + &error)) { + _LOG3D (LOGD_DEVICE, connection, + "skip activation: %s", + error->message); + g_error_free (error); + return device; + } + /* Create backing resources if the device has any autoconnect connections */ connections = nm_settings_get_connections_clone (priv->settings, NULL, NULL, NULL, @@ -4649,6 +4663,19 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (nm_active_connection_get_activation_type (active) == NM_ACTIVATION_TYPE_MANAGED) nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_MANAGED); + /* Try to find the master connection/device if the connection has a dependency */ + if (!find_master (self, + applied, + device, + &master_connection, + &master_device, + &master_ac, + error)) { + g_prefix_error (error, "Can not find a master for %s: ", + nm_settings_connection_get_id (sett_conn)); + return FALSE; + } + /* Create any backing resources the device needs */ if (!nm_device_is_real (device)) { NMDevice *parent; @@ -4717,19 +4744,6 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } } - /* Try to find the master connection/device if the connection has a dependency */ - if (!find_master (self, - applied, - device, - &master_connection, - &master_device, - &master_ac, - error)) { - g_prefix_error (error, "Can not find a master for %s: ", - nm_settings_connection_get_id (sett_conn)); - return FALSE; - } - /* Ensure there's a master active connection the new connection we're * activating can depend on. */ diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 4f0da581..b55fbd66 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -155,7 +155,7 @@ again: const char *ifname = known_ifnames[try_count % 2]; nm_assert (ifindex > 0); - nm_assert (ifname && nm_utils_is_valid_iface_name (ifname, NULL)); + nm_assert (ifname && nm_utils_ifname_valid_kernel (ifname, NULL)); nm_assert (fd >= 0); memset (&ifr, 0, sizeof (ifr)); @@ -343,6 +343,7 @@ ethtool_get_stringset (SocketHandle *shandle, int stringset_id) .info.reserved = 0, .info.sset_mask = (1ULL << stringset_id), }; + const guint32 *pdata; gs_free struct ethtool_gstrings *gstrings = NULL; gsize gstrings_len; guint32 i, len; @@ -352,7 +353,9 @@ ethtool_get_stringset (SocketHandle *shandle, int stringset_id) if (!sset_info.info.sset_mask) return NULL; - len = sset_info.info.data[0]; + pdata = (guint32 *) sset_info.info.data; + + len = *pdata; gstrings_len = sizeof (*gstrings) + (len * ETH_GSTRING_LEN); gstrings = g_malloc0 (gstrings_len); @@ -838,6 +841,7 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, .e.cmd = ETHTOOL_GPERMADDR, .e.size = NM_UTILS_HWADDR_LEN_MAX, }; + const guint8 *pdata; guint i; @@ -851,20 +855,22 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, if (edata.e.size < 1) return FALSE; - if (NM_IN_SET (edata.e.data[0], 0, 0xFF)) { + pdata = (const guint8 *) edata.e.data; + + if (NM_IN_SET (pdata[0], 0, 0xFF)) { /* Some drivers might return a permanent address of all zeros. * Reject that (rh#1264024) * * Some drivers return a permanent address of all ones. Reject that too */ for (i = 1; i < edata.e.size; i++) { - if (edata.e.data[0] != edata.e.data[i]) + if (pdata[0] != pdata[i]) goto not_all_0or1; } return FALSE; } not_all_0or1: - memcpy (buf, edata.e.data, edata.e.size); + memcpy (buf, pdata, edata.e.size); *length = edata.e.size; return TRUE; } @@ -1410,7 +1416,7 @@ nmp_utils_sysctl_open_netdir (int ifindex, return -1; } - nm_assert (nm_utils_is_valid_iface_name (ifname, NULL)); + nm_assert (nm_utils_ifname_valid_kernel (ifname, NULL)); if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ) g_return_val_if_reached (-1); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index b93213ef..f831fe94 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1175,7 +1175,7 @@ nmtstp_link_veth_add (NMPlatform *platform, const NMPlatformLink *pllink = NULL; gboolean success; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1204,7 +1204,7 @@ nmtstp_link_dummy_add (NMPlatform *platform, const NMPlatformLink *pllink = NULL; gboolean success; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1235,7 +1235,7 @@ nmtstp_link_gre_add (NMPlatform *platform, char b2[INET_ADDRSTRLEN]; NMLinkType link_type; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; @@ -1287,7 +1287,7 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean encap_ignore; gboolean tclass_inherit; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); g_assert (!lnk->is_gre); external_command = nmtstp_run_command_check_external (external_command); @@ -1348,7 +1348,7 @@ nmtstp_link_ip6gre_add (NMPlatform *platform, char tclass[20]; gboolean tclass_inherit; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); g_assert (lnk->is_gre); external_command = nmtstp_run_command_check_external (external_command); @@ -1397,7 +1397,7 @@ nmtstp_link_ipip_add (NMPlatform *platform, char b1[INET_ADDRSTRLEN]; char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1438,7 +1438,7 @@ nmtstp_link_macvlan_add (NMPlatform *platform, gboolean success; NMLinkType link_type; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1486,7 +1486,7 @@ nmtstp_link_sit_add (NMPlatform *platform, char b1[INET_ADDRSTRLEN]; char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1532,7 +1532,7 @@ nmtstp_link_tun_add (NMPlatform *platform, int err; int r; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); g_assert (lnk); g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP)); g_assert (!out_fd || *out_fd == -1); @@ -1595,7 +1595,7 @@ nmtstp_link_vxlan_add (NMPlatform *platform, int err; int r; - g_assert (nm_utils_is_valid_iface_name (name, NULL)); + g_assert (nm_utils_ifname_valid_kernel (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1684,7 +1684,7 @@ nmtstp_link_get_typed (NMPlatform *platform, g_assert_cmpstr (name, ==, pllink->name); } - g_assert (!name || nm_utils_is_valid_iface_name (name, NULL)); + g_assert (!name || nm_utils_ifname_valid_kernel (name, NULL)); if (pllink && link_type != NM_LINK_TYPE_NONE) g_assert_cmpint (pllink->type, ==, link_type); diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index a1d3236e..e01f7344 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -399,7 +399,7 @@ make_connection_setting (const char *file, if (v) { GError *error = NULL; - if (nm_utils_is_valid_iface_name (v, &error)) { + if (nm_utils_ifname_valid_kernel (v, &error)) { g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, v, NULL); @@ -1692,7 +1692,7 @@ make_ip4_setting (shvarFile *ifcfg, g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCP_SEND_HOSTNAME", TRUE), - NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), NULL); nm_clear_g_free (&value); @@ -2159,9 +2159,11 @@ make_ip6_setting (shvarFile *ifcfg, if (v) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); - g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, - svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), NULL); - + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), + NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV6_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0), + NM_SETTING_IP6_CONFIG_RA_TIMEOUT, (int) svGetValueInt64 (ifcfg, "IPV6_RA_TIMEOUT", 10, 0, G_MAXINT32, 0), + NULL); i64 = svGetValueInt64 (ifcfg, "DHCPV6_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1); if (i64 > -1) { diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index d33845c2..f328cc8f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -2748,30 +2748,6 @@ write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path) } } -static void -write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg) -{ - NMDhcpHostnameFlags flags; - const char *hostname; - - hostname = nm_setting_ip_config_get_dhcp_hostname (s_ip6); - svSetValueStr (ifcfg, "DHCPV6_HOSTNAME", hostname); - - /* Missing DHCPV6_SEND_HOSTNAME means TRUE, and we prefer not write it - * explicitly in that case, because it is NM-specific variable - */ - if (nm_setting_ip_config_get_dhcp_send_hostname (s_ip6)) - svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME"); - else - svSetValueStr (ifcfg, "DHCPV6_SEND_HOSTNAME", "no"); - - flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6); - svSetValueInt64_cond (ifcfg, - "DHCPV6_HOSTNAME_FLAGS", - flags != NM_DHCP_HOSTNAME_FLAG_NONE, - flags); -} - static gboolean write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, @@ -2789,6 +2765,9 @@ write_ip6_setting (NMConnection *connection, NMIPRouteTableSyncMode route_table; GString *ip_str1, *ip_str2, *ip_ptr; NMSettingIP6ConfigAddrGenMode addr_gen_mode; + NMDhcpHostnameFlags flags; + const char *hostname; + int timeout; NM_SET_OUT (out_route6_content, NULL); @@ -2855,7 +2834,34 @@ write_ip6_setting (NMConnection *connection, svSetValueStr (ifcfg, "DHCPV6_IAID", nm_setting_ip_config_get_dhcp_iaid (s_ip6)); - write_ip6_setting_dhcp_hostname (s_ip6, ifcfg); + hostname = nm_setting_ip_config_get_dhcp_hostname (s_ip6); + svSetValueStr (ifcfg, "DHCPV6_HOSTNAME", hostname); + + /* Missing DHCPV6_SEND_HOSTNAME means TRUE, and we prefer not write it + * explicitly in that case, because it is NM-specific variable + */ + if (nm_setting_ip_config_get_dhcp_send_hostname (s_ip6)) + svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME"); + else + svSetValueStr (ifcfg, "DHCPV6_SEND_HOSTNAME", "no"); + + timeout = nm_setting_ip6_config_get_ra_timeout (NM_SETTING_IP6_CONFIG (s_ip6)); + svSetValueInt64_cond (ifcfg, + "IPV6_RA_TIMEOUT", + timeout != 0, + timeout); + + timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip6); + svSetValueInt64_cond (ifcfg, + "IPV6_DHCP_TIMEOUT", + timeout != 0, + timeout); + + flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6); + svSetValueInt64_cond (ifcfg, + "DHCPV6_HOSTNAME_FLAGS", + flags != NM_DHCP_HOSTNAME_FLAG_NONE, + flags); /* Write out IP addresses */ num = nm_setting_ip_config_get_num_addresses (s_ip6); diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index 6ef29311..c19da11c 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -3184,5 +3184,5 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_VARIANT); + G_TYPE_NONE, 1, G_TYPE_STRING); } |