diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/devices/team/nm-device-team.c | 91 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-utils.c | 2 | ||||
| -rw-r--r-- | src/libnm-core-public/nm-version-macros.h | 2 |
3 files changed, 58 insertions, 37 deletions
diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index e6d34266..4e073ddf 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -43,6 +43,7 @@ typedef struct { bool kill_in_progress : 1; GFileMonitor *usock_monitor; NMDeviceStageState stage1_state : 3; + GHashTable *port_configs; } NMDeviceTeamPrivate; struct _NMDeviceTeam { @@ -138,20 +139,44 @@ complete_connection(NMDevice *device, } static gboolean +_update_port_config(NMDeviceTeam *self, const char *port_iface, const char *sanitized_config) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + int err; + + err = teamdctl_port_config_update_raw(priv->tdc, port_iface, sanitized_config); + if (err != 0) { + _LOGE(LOGD_TEAM, "failed to update config for port %s (err=%d)", port_iface, err); + return FALSE; + } + + return TRUE; +} + +static gboolean ensure_teamd_connection(NMDevice *device) { NMDeviceTeam *self = NM_DEVICE_TEAM(device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); gs_free_error GError *error = NULL; + const char *port_iface; + const char *port_config; + GHashTableIter iter; if (priv->tdc) return TRUE; priv->tdc = _tdc_connect_new(self, nm_device_get_iface(device), &error); - if (!priv->tdc) + if (!priv->tdc) { _LOGE(LOGD_TEAM, "failed to connect to teamd: %s", error->message); + return FALSE; + } - return !!priv->tdc; + g_hash_table_iter_init(&iter, priv->port_configs); + while (g_hash_table_iter_next(&iter, (gpointer *) &port_iface, (gpointer *) &port_config)) + _update_port_config(self, port_iface, port_config); + + return TRUE; } static const char * @@ -840,28 +865,20 @@ attach_port(NMDevice *device, s_team_port = nm_connection_get_setting_team_port(connection); if (s_team_port) { - const char *config = nm_setting_team_port_get_config(s_team_port); - - if (config) { - if (!priv->tdc) { - _LOGW(LOGD_TEAM, - "attached team port %s config not changed, not connected to teamd", - port_iface); - } else { - gs_free char *sanitized_config = NULL; - int err; - - sanitized_config = g_strdup(config); - g_strdelimit(sanitized_config, "\r\n", ' '); - err = teamdctl_port_config_update_raw(priv->tdc, port_iface, sanitized_config); - if (err != 0) { - _LOGE(LOGD_TEAM, - "failed to update config for port %s (err=%d)", - port_iface, - err); - return FALSE; - } - } + char *sanitized_config; + + sanitized_config = g_strdup(nm_setting_team_port_get_config(s_team_port) ?: "{}"); + g_strdelimit(sanitized_config, "\r\n", ' '); + + g_hash_table_insert(priv->port_configs, g_strdup(port_iface), sanitized_config); + + if (!priv->tdc) { + _LOGW(LOGD_TEAM, + "attached team port %s config not changed, not connected to teamd", + port_iface); + } else { + if (!_update_port_config(self, port_iface, sanitized_config)) + return FALSE; } } success = nm_platform_link_enslave(nm_device_get_platform(device), @@ -885,8 +902,9 @@ attach_port(NMDevice *device, static void detach_port(NMDevice *device, NMDevice *port, gboolean configure) { - NMDeviceTeam *self = NM_DEVICE_TEAM(device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + NMDeviceTeam *self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + const char *port_iface = nm_device_get_ip_iface(port); gboolean do_release, success; NMSettingTeamPort *s_port; int ifindex_port; @@ -902,36 +920,36 @@ detach_port(NMDevice *device, NMDevice *port, gboolean configure) ifindex_port = nm_device_get_ip_ifindex(port); if (ifindex_port <= 0) { - _LOGD(LOGD_TEAM, "team port %s is already detached", nm_device_get_ip_iface(port)); + _LOGD(LOGD_TEAM, "team port %s is already detached", port_iface); } else if (do_release) { success = nm_platform_link_release(nm_device_get_platform(device), nm_device_get_ip_ifindex(device), ifindex_port); if (success) - _LOGI(LOGD_TEAM, "detached team port %s", nm_device_get_ip_iface(port)); + _LOGI(LOGD_TEAM, "detached team port %s", port_iface); else - _LOGW(LOGD_TEAM, "failed to detach team port %s", nm_device_get_ip_iface(port)); + _LOGW(LOGD_TEAM, "failed to detach team port %s", port_iface); /* Kernel team code "closes" the port when releasing it, (which clears * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released port. */ if (!nm_device_bring_up(port, TRUE, NULL)) { - _LOGW(LOGD_TEAM, - "detached team port %s could not be brought up", - nm_device_get_ip_iface(port)); + _LOGW(LOGD_TEAM, "detached team port %s could not be brought up", port_iface); } nm_clear_g_source(&priv->teamd_read_timeout); priv->teamd_read_timeout = g_timeout_add_seconds(5, teamd_read_timeout_cb, self); } else - _LOGI(LOGD_TEAM, "team port %s was detached", nm_device_get_ip_iface(port)); + _LOGI(LOGD_TEAM, "team port %s was detached", port_iface); /* Delete any port configuration we previously set */ if (configure && priv->tdc && (s_port = nm_device_get_applied_setting(port, NM_TYPE_SETTING_TEAM_PORT)) - && (nm_setting_team_port_get_config(s_port))) - teamdctl_port_config_update_raw(priv->tdc, nm_device_get_ip_iface(port), "{}"); + && (nm_setting_team_port_get_config(s_port))) { + _update_port_config(self, port_iface, "{}"); + g_hash_table_remove(priv->port_configs, port_iface); + } } static gboolean @@ -995,6 +1013,8 @@ constructed(GObject *object) G_OBJECT_CLASS(nm_device_team_parent_class)->constructed(object); + priv->port_configs = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); + if (nm_dbus_manager_get_dbus_connection(nm_dbus_manager_get())) { /* Register D-Bus name watcher */ tmp_str = g_strdup_printf("org.libteam.teamd.%s", nm_device_get_ip_iface(device)); @@ -1054,6 +1074,7 @@ dispose(GObject *object) teamd_cleanup(self, TRUE); nm_clear_g_free(&priv->config); + nm_clear_pointer(&priv->port_configs, g_hash_table_destroy); G_OBJECT_CLASS(nm_device_team_parent_class)->dispose(object); } diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index be6ad4de..1c6d36c2 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -147,7 +147,7 @@ nm_sock_addr_endpoint_new(const char *endpoint) gsize i; gs_free char *host_clone = NULL; const char *host; - guint16 port; + guint16 port = 0; g_return_val_if_fail(endpoint, NULL); diff --git a/src/libnm-core-public/nm-version-macros.h b/src/libnm-core-public/nm-version-macros.h index 4dce57f6..04fce5df 100644 --- a/src/libnm-core-public/nm-version-macros.h +++ b/src/libnm-core-public/nm-version-macros.h @@ -30,7 +30,7 @@ * Evaluates to the micro version number of NetworkManager which this source * compiled against. */ -#define NM_MICRO_VERSION (4) +#define NM_MICRO_VERSION (6) /** * NM_CHECK_VERSION: |