diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 192f9a5178..46747a6529 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -548,6 +548,9 @@ typedef enum { /* DCB or FCoE setup failed */ NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55, + /* teamd control failed */ + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED = 56, + /* Unused */ NM_DEVICE_STATE_REASON_LAST = 0xFFFF } NMDeviceStateReason; diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index d9e7702d14..2332bdd874 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -592,6 +592,11 @@ DCB or FCoE setup failed. + + + teamd control failed. + + diff --git a/src/devices/nm-device-team.c b/src/devices/nm-device-team.c index 1fe7caf927..f302ce3fb8 100644 --- a/src/devices/nm-device-team.c +++ b/src/devices/nm-device-team.c @@ -195,11 +195,53 @@ complete_connection (NMDevice *device, return TRUE; } +#if WITH_TEAMDCTL static gboolean -match_l2_config (NMDevice *self, NMConnection *connection) +ensure_teamd_connection (NMDevice *self) { - /* FIXME */ - return TRUE; + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + int err; + + if (priv->tdc) + return TRUE; + + priv->tdc = teamdctl_alloc (); + g_assert (priv->tdc); + err = teamdctl_connect (priv->tdc, nm_device_get_iface (self), NULL, NULL); + if (err) { + nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd", nm_device_get_iface (self)); + teamdctl_free (priv->tdc); + priv->tdc = NULL; + } + + return !!priv->tdc; +} +#endif + +static void +update_connection (NMDevice *device, NMConnection *connection) +{ + NMSettingTeam *s_team = nm_connection_get_setting_team (connection); + const char *iface = nm_device_get_iface (device); + + if (!s_team) { + s_team = (NMSettingTeam *) nm_setting_team_new (); + nm_connection_add_setting (connection, (NMSetting *) s_team); + g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, iface, NULL); + } + +#if WITH_TEAMDCTL + if (ensure_teamd_connection (device)) { + char *config; + + config = teamdctl_config_get_raw (NM_DEVICE_TEAM_GET_PRIVATE (device)->tdc); + if (config) + g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL); + else + nm_log_err (LOGD_TEAM, "(%s): failed to read teamd config", iface); + g_free (config); + } +#endif } /******************************************************************/ @@ -279,7 +321,7 @@ teamd_cleanup (NMDevice *dev, gboolean device_state_failed) if (device_state_failed) { if (nm_device_is_activating (dev) || (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); + nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); } } @@ -311,17 +353,9 @@ teamd_dbus_appeared (GDBusConnection *connection, nm_log_info (LOGD_TEAM, "(%s): teamd appeared on D-Bus", nm_device_get_iface (dev)); teamd_timeout_remove (dev); #if WITH_TEAMDCTL - if (!priv->tdc) { - int err; - - priv->tdc = teamdctl_alloc (); - g_assert (priv->tdc); - err = teamdctl_connect (priv->tdc, nm_device_get_iface (dev), NULL, NULL); - if (err) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd", nm_device_get_iface (dev)); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } + if (!ensure_teamd_connection (dev)) { + nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + return; } #endif nm_device_activate_schedule_stage2_device_config (dev); @@ -744,8 +778,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->check_connection_available = check_connection_available; parent_class->complete_connection = complete_connection; - - parent_class->match_l2_config = match_l2_config; + parent_class->update_connection = update_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->deactivate = deactivate;