gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) { NMSettingTeamPort *s_port; const char *iface = nm_device_get_iface (slave); char *port_config = NULL; gboolean with_teamdctl = FALSE; int err = 0; #if WITH_TEAMDCTL const char *master_iface; int master_ifindex; struct teamdctl *tdc; const char *team_port_config = NULL; #endif g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); #if WITH_TEAMDCTL master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave)); g_assert (master_ifindex > 0); master_iface = nm_platform_link_get_name (master_ifindex); g_assert (master_iface); tdc = teamdctl_alloc (); g_assert (tdc); err = teamdctl_connect (tdc, master_iface, NULL, NULL); if (err) { nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)", iface, master_iface, err); teamdctl_free (tdc); return FALSE; } err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config); port_config = g_strdup (team_port_config); teamdctl_free (tdc); with_teamdctl = TRUE; #endif s_port = nm_connection_get_setting_team_port (connection); if (!s_port) { s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); nm_connection_add_setting (connection, NM_SETTING (s_port)); } g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free (port_config); if (!with_teamdctl || err != 0) { if (!with_teamdctl) nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration " " (compiled without libteamdctl support)", iface); else nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)", iface, err); return FALSE; } return TRUE; }
static gboolean enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { #if WITH_TEAMDCTL NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); #endif gboolean success = TRUE, no_firmware = FALSE; const char *iface = nm_device_get_ip_iface (device); const char *slave_iface = nm_device_get_ip_iface (slave); NMSettingTeamPort *s_team_port; nm_device_master_check_slave_physical_port (device, slave, LOGD_TEAM); if (configure) { nm_device_take_down (slave, TRUE); 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 WITH_TEAMDCTL if (!priv->tdc) { nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed, not connected to teamd", iface, slave_iface); } else { int err; char *sanitized_config; sanitized_config = g_strdelimit (g_strdup (config), "\r\n", ' '); err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); g_free (sanitized_config); if (err != 0) { nm_log_err (LOGD_TEAM, "(%s): failed to update config for port %s (err=%d)", iface, slave_iface, err); return FALSE; } } #else nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed due to lack of Teamd control support", iface, slave_iface); #endif } } success = nm_platform_link_enslave (nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)); nm_device_bring_up (slave, TRUE, &no_firmware); } if (success) { nm_log_info (LOGD_TEAM, "(%s): enslaved team port %s", iface, slave_iface); g_object_notify (G_OBJECT (device), "slaves"); } return success; }
static void nmt_page_team_port_constructed (GObject *object) { NmtPageTeamPort *team = NMT_PAGE_TEAM_PORT (object); NmtPageTeamPortPrivate *priv = NMT_PAGE_TEAM_PORT_GET_PRIVATE (team); NmtEditorSection *section; NmtNewtGrid *grid; NMSettingTeamPort *s_port; NmtNewtWidget *widget; NMConnection *conn; conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (team)); s_port = nm_connection_get_setting_team_port (conn); if (!s_port) { nm_connection_add_setting (conn, nm_setting_team_port_new ()); s_port = nm_connection_get_setting_team_port (conn); } priv->s_port = s_port; section = nmt_editor_section_new (_("TEAM PORT"), NULL, TRUE); widget = nmt_newt_grid_new (); nmt_editor_grid_append (nmt_editor_section_get_body (section), NULL, widget, NULL); grid = NMT_NEWT_GRID (widget); widget = nmt_newt_label_new (_("JSON configuration")); nmt_newt_grid_add (grid, widget, 0, 2); widget = nmt_newt_textbox_new (NMT_NEWT_TEXTBOX_SCROLLABLE | NMT_NEWT_TEXTBOX_SET_BACKGROUND, 60); g_object_bind_property (s_port, NM_SETTING_TEAM_PORT_CONFIG, widget, "text", G_BINDING_SYNC_CREATE); nmt_newt_grid_add (grid, widget, 0, 3); nmt_newt_widget_set_padding (widget, 2, 0, 2, 1); widget = nmt_newt_button_new (_("Edit...")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_clicked), team); nmt_newt_grid_add (grid, widget, 0, 4); nmt_editor_page_add_section (NMT_EDITOR_PAGE (team), section); G_OBJECT_CLASS (nmt_page_team_port_parent_class)->constructed (object); }
static gboolean enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); gboolean success = TRUE, no_firmware = FALSE; const char *slave_iface = nm_device_get_ip_iface (slave); NMSettingTeamPort *s_team_port; nm_device_master_check_slave_physical_port (device, slave, LOGD_TEAM); if (configure) { nm_device_take_down (slave, TRUE); 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, "enslaved team port %s config not changed, not connected to teamd", slave_iface); } else { int err; char *sanitized_config; sanitized_config = g_strdelimit (g_strdup (config), "\r\n", ' '); err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); g_free (sanitized_config); if (err != 0) { _LOGE (LOGD_TEAM, "failed to update config for port %s (err=%d)", slave_iface, err); return FALSE; } } } } success = nm_platform_link_enslave (NM_PLATFORM_GET, nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)); nm_device_bring_up (slave, TRUE, &no_firmware); if (!success) return FALSE; _LOGI (LOGD_TEAM, "enslaved team port %s", slave_iface); } else _LOGI (LOGD_TEAM, "team port %s was enslaved", slave_iface); g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); return TRUE; }
static gboolean master_update_slave_connection (NMDevice *self, NMDevice *slave, NMConnection *connection, GError **error) { NMSettingTeamPort *s_port; char *port_config = NULL; int err = 0; struct teamdctl *tdc; const char *team_port_config = NULL; const char *iface = nm_device_get_iface (self); const char *iface_slave = nm_device_get_iface (slave); tdc = teamdctl_alloc (); if (!tdc) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "update slave connection for slave '%s' failed to connect to teamd for master %s (out of memory?)", iface_slave, iface); g_return_val_if_reached (FALSE); } err = teamdctl_connect (tdc, iface, NULL, NULL); if (err) { teamdctl_free (tdc); g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "update slave connection for slave '%s' failed to connect to teamd for master %s (err=%d)", iface_slave, iface, err); return FALSE; } err = teamdctl_port_config_get_raw_direct (tdc, iface_slave, (char **)&team_port_config); port_config = g_strdup (team_port_config); teamdctl_disconnect (tdc); teamdctl_free (tdc); if (err) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "update slave connection for slave '%s' failed to get configuration from teamd master %s (err=%d)", iface_slave, iface, err); g_free (port_config); return FALSE; } s_port = nm_connection_get_setting_team_port (connection); if (!s_port) { s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); nm_connection_add_setting (connection, NM_SETTING (s_port)); } g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free (port_config); g_object_set (nm_connection_get_setting_connection (connection), NM_SETTING_CONNECTION_MASTER, iface, NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, NULL); return TRUE; }