summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-11-04 15:28:19 -0500
committerDan Winship <danw@gnome.org>2013-11-06 10:27:53 -0500
commit3dd9102947845abd5145e3d688df9ff989eb362f (patch)
tree0398f690e0db3e188cfb31141680dbd4e1cc3604
parent736dfcc59547d77a82b474f28ce47ecc47baf660 (diff)
downloadnetwork-manager-applet-3dd9102947845abd5145e3d688df9ff989eb362f.tar.gz
connection-editor: improve handling of NPAR/SR-IOV devices (rh #804527)
Warn the user when a bond or team connection contains multiple slaves on the same physical port.
-rw-r--r--src/connection-editor/nm-connection-editor.c30
-rw-r--r--src/connection-editor/nm-connection-editor.h4
-rw-r--r--src/connection-editor/page-bond.c1
-rw-r--r--src/connection-editor/page-master.c90
-rw-r--r--src/connection-editor/page-master.h2
-rw-r--r--src/connection-editor/page-team.c1
6 files changed, 122 insertions, 6 deletions
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 3024244f..eb4055a0 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -1103,22 +1103,20 @@ nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy)
}
}
-void
-nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...)
+static void
+nm_connection_editor_dialog (GtkWindow *parent, GtkMessageType type, const char *heading,
+ const char *format, va_list args)
{
GtkWidget *dialog;
- va_list args;
char *message;
dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
+ type,
GTK_BUTTONS_CLOSE,
"%s", heading);
- va_start (args, format);
message = g_strdup_vprintf (format, args);
- va_end (args);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message);
g_free (message);
@@ -1129,3 +1127,23 @@ nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *
gtk_widget_destroy (dialog);
}
+void
+nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ nm_connection_editor_dialog (parent, GTK_MESSAGE_ERROR, heading, format, args);
+ va_end (args);
+}
+
+void
+nm_connection_editor_warning (GtkWindow *parent, const char *heading, const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ nm_connection_editor_dialog (parent, GTK_MESSAGE_WARNING, heading, format, args);
+ va_end (args);
+}
+
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index 4798b0fe..0a13afda 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -93,5 +93,9 @@ void nm_connection_editor_error (GtkWindow *parent,
const char *heading,
const char *format,
...);
+void nm_connection_editor_warning (GtkWindow *parent,
+ const char *heading,
+ const char *format,
+ ...);
#endif
diff --git a/src/connection-editor/page-bond.c b/src/connection-editor/page-bond.c
index 9c2c8895..69746859 100644
--- a/src/connection-editor/page-bond.c
+++ b/src/connection-editor/page-bond.c
@@ -548,6 +548,7 @@ validate (CEPage *page, NMConnection *connection, GError **error)
static void
ce_page_bond_init (CEPageBond *self)
{
+ CE_PAGE_MASTER (self)->aggregating = TRUE;
}
static void
diff --git a/src/connection-editor/page-master.c b/src/connection-editor/page-master.c
index dfa75e34..e9c928ab 100644
--- a/src/connection-editor/page-master.c
+++ b/src/connection-editor/page-master.c
@@ -176,6 +176,94 @@ connection_updated (NMRemoteConnection *connection, gpointer user_data)
-1);
}
+static NMDevice *
+get_device_for_connection (NMClient *client, NMConnection *conn)
+{
+ const GPtrArray *devices;
+ NMSettingConnection *s_con;
+ int i;
+
+ devices = nm_client_get_devices (client);
+ if (!devices)
+ return NULL;
+
+ /* Make sure the connection is actually locked to a specific device */
+ s_con = nm_connection_get_setting_connection (conn);
+ if ( !nm_setting_connection_get_interface_name (s_con)
+ && !nm_connection_get_virtual_iface_name (conn)) {
+ NMSetting *s_hw;
+ GByteArray *mac_address;
+
+ s_hw = nm_connection_get_setting_by_name (conn, nm_setting_connection_get_connection_type (s_con));
+ if (!s_hw || !g_object_class_find_property (G_OBJECT_GET_CLASS (s_hw), "mac-address"))
+ return NULL;
+
+ g_object_get (G_OBJECT (s_hw), "mac-address", &mac_address, NULL);
+ if (!mac_address)
+ return NULL;
+ g_byte_array_unref (mac_address);
+ }
+
+ /* OK, now find that device */
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = devices->pdata[i];
+
+ if (nm_device_connection_compatible (device, conn, NULL))
+ return device;
+ }
+
+ return NULL;
+}
+
+static void
+check_new_slave_physical_port (CEPageMaster *self, NMConnection *conn)
+{
+ CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self);
+ NMConnection *conn2;
+ NMDevice *dev, *dev2;
+ const char *id, *id2;
+ GtkTreeIter iter;
+
+ dev = get_device_for_connection (CE_PAGE (self)->client, conn);
+ if (!dev)
+ return;
+ id = nm_device_get_physical_port_id (dev);
+ if (!id)
+ return;
+
+ if (!gtk_tree_model_get_iter_first (priv->connections_model, &iter))
+ return;
+ do {
+ gtk_tree_model_get (priv->connections_model, &iter, 0, &conn2, -1);
+ g_object_unref (conn2); /* gtk_tree_model_get() adds a ref */
+ dev2 = get_device_for_connection (CE_PAGE (self)->client, conn2);
+ if (!dev2)
+ continue;
+ if (dev == dev2) {
+ nm_connection_editor_warning (CE_PAGE (self)->parent_window,
+ _("Duplicate slaves"),
+ _("Slaves '%s' and '%s' both apply to device '%s'"),
+ nm_connection_get_id (conn),
+ nm_connection_get_id (conn2),
+ nm_device_get_iface (dev));
+ return;
+ }
+
+ id2 = nm_device_get_physical_port_id (dev2);
+ if (self->aggregating && id && id2 && !strcmp (id, id2)) {
+ nm_connection_editor_warning (CE_PAGE (self)->parent_window,
+ _("Duplicate slaves"),
+ _("Slaves '%s' and '%s' apply to different virtual "
+ "ports ('%s' and '%s') of the same physical device."),
+ nm_connection_get_id (conn),
+ nm_connection_get_id (conn2),
+ nm_device_get_iface (dev),
+ nm_device_get_iface (dev2));
+ return;
+ }
+ } while (gtk_tree_model_iter_next (priv->connections_model, &iter));
+}
+
static void
connection_added (NMRemoteSettings *settings,
NMRemoteConnection *connection,
@@ -208,6 +296,8 @@ connection_added (NMRemoteSettings *settings,
if (strcmp (master, interface_name) != 0 && strcmp (master, priv->uuid) != 0)
return;
+ check_new_slave_physical_port (self, NM_CONNECTION (connection));
+
gtk_list_store_append (GTK_LIST_STORE (priv->connections_model), &iter);
gtk_list_store_set (GTK_LIST_STORE (priv->connections_model), &iter,
COL_CONNECTION, connection,
diff --git a/src/connection-editor/page-master.h b/src/connection-editor/page-master.h
index 5bd05756..56cc6c41 100644
--- a/src/connection-editor/page-master.h
+++ b/src/connection-editor/page-master.h
@@ -38,6 +38,8 @@
typedef struct {
CEPage parent;
+
+ gboolean aggregating;
} CEPageMaster;
typedef struct {
diff --git a/src/connection-editor/page-team.c b/src/connection-editor/page-team.c
index 9b2e0f5c..1c79a76d 100644
--- a/src/connection-editor/page-team.c
+++ b/src/connection-editor/page-team.c
@@ -314,6 +314,7 @@ validate (CEPage *page, NMConnection *connection, GError **error)
static void
ce_page_team_init (CEPageTeam *self)
{
+ CE_PAGE_MASTER (self)->aggregating = TRUE;
}
static void