|
Packit Service |
639700 |
// SPDX-License-Identifier: GPL-2.0+
|
|
Packit |
fabffb |
/* NetworkManager Connection editor -- Connection editor for NetworkManager
|
|
Packit |
fabffb |
*
|
|
Packit |
fabffb |
* Copyright 2008 - 2014 Red Hat, Inc.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include "nm-default.h"
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include <stdlib.h>
|
|
Packit |
fabffb |
#include <string.h>
|
|
Packit |
fabffb |
#include <net/ethernet.h>
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include "page-vlan.h"
|
|
Packit |
fabffb |
#include "connection-helpers.h"
|
|
Packit |
fabffb |
#include "nm-connection-editor.h"
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
G_DEFINE_TYPE (CEPageVlan, ce_page_vlan, CE_TYPE_PAGE)
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#define CE_PAGE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_VLAN, CEPageVlanPrivate))
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
typedef struct {
|
|
Packit |
fabffb |
char *label;
|
|
Packit |
fabffb |
NMDevice *device;
|
|
Packit |
fabffb |
NMConnection *connection;
|
|
Packit |
fabffb |
} VlanParent;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
typedef struct {
|
|
Packit |
fabffb |
NMSettingVlan *setting;
|
|
Packit |
fabffb |
NMSetting *s_hw;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
VlanParent **parents;
|
|
Packit |
fabffb |
char **parent_labels;
|
|
Packit |
fabffb |
int parents_len;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
GtkWindow *toplevel;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
GtkComboBox *parent;
|
|
Packit |
fabffb |
GtkEntry *parent_entry;
|
|
Packit |
fabffb |
GtkSpinButton *id_entry;
|
|
Packit |
fabffb |
GtkEntry *name_entry;
|
|
Packit |
fabffb |
GtkComboBoxText *cloned_mac;
|
|
Packit |
fabffb |
GtkSpinButton *mtu;
|
|
Packit |
fabffb |
GtkToggleButton *flag_reorder_hdr, *flag_gvrp, *flag_loose_binding, *flag_mvrp;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
char *last_parent;
|
|
Packit |
fabffb |
int last_id;
|
|
Packit |
fabffb |
} CEPageVlanPrivate;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
vlan_private_init (CEPageVlan *self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
GtkBuilder *builder;
|
|
Packit |
fabffb |
GtkWidget *vbox;
|
|
Packit |
fabffb |
GtkLabel *label;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
builder = CE_PAGE (self)->builder;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
priv->parent = GTK_COMBO_BOX (gtk_combo_box_text_new_with_entry ());
|
|
Packit |
fabffb |
gtk_combo_box_set_entry_text_column (priv->parent, 0);
|
|
Packit |
fabffb |
priv->parent_entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (priv->parent)));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vlan_parent_vbox"));
|
|
Packit |
fabffb |
gtk_container_add (GTK_CONTAINER (vbox), GTK_WIDGET (priv->parent));
|
|
Packit |
fabffb |
gtk_widget_show_all (GTK_WIDGET (priv->parent));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Set mnemonic widget for parent label */
|
|
Packit |
fabffb |
label = GTK_LABEL (gtk_builder_get_object (builder, "vlan_parent_label"));
|
|
Packit |
fabffb |
gtk_label_set_mnemonic_widget (label, GTK_WIDGET (priv->parent));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
priv->id_entry = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_id_entry"));
|
|
Packit |
fabffb |
priv->name_entry = GTK_ENTRY (gtk_builder_get_object (builder, "vlan_name_entry"));
|
|
Packit |
fabffb |
priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "vlan_cloned_mac_entry"));
|
|
Packit |
fabffb |
priv->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_mtu"));
|
|
Packit |
fabffb |
priv->flag_reorder_hdr = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "reorder_hdr_flag"));
|
|
Packit |
fabffb |
priv->flag_gvrp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "gvrp_flag"));
|
|
Packit |
fabffb |
priv->flag_loose_binding = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "loose_binding_flag"));
|
|
Packit |
fabffb |
priv->flag_mvrp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "mvrp_flag"));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
priv->toplevel = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (priv->mtu),
|
|
Packit |
fabffb |
GTK_TYPE_WINDOW));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
stuff_changed (GtkWidget *w, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
ce_page_changed (CE_PAGE (user_data));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void name_changed (GtkWidget *widget, gpointer user_data);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
sync_iface (CEPageVlan *self, GtkEntry *changed_entry)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
const char *iface, *iface_end, *parent_text;
|
|
Packit |
fabffb |
char *new_iface, *end;
|
|
Packit |
fabffb |
int iface_id, iface_len, parent_iface_len, id;
|
|
Packit |
fabffb |
gboolean vlan_style_name;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
iface = gtk_entry_get_text (priv->name_entry);
|
|
Packit |
fabffb |
if (!*iface)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (g_str_has_prefix (iface, "vlan")) {
|
|
Packit |
fabffb |
iface_end = iface + 4;
|
|
Packit |
fabffb |
iface_id = strtoul (iface_end, &end, 10);
|
|
Packit |
fabffb |
vlan_style_name = TRUE;
|
|
Packit |
fabffb |
} else if ((iface_end = strchr (iface, '.'))) {
|
|
Packit |
fabffb |
iface_id = strtoul (iface_end + 1, &end, 10);
|
|
Packit |
fabffb |
vlan_style_name = FALSE;
|
|
Packit |
fabffb |
} else
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
if (*end)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
iface_len = iface_end - iface;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
parent_text = gtk_entry_get_text (priv->parent_entry);
|
|
Packit |
fabffb |
parent_iface_len = strcspn (parent_text, " ");
|
|
Packit |
fabffb |
id = gtk_spin_button_get_value_as_int (priv->id_entry);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (changed_entry == priv->name_entry) {
|
|
Packit |
fabffb |
/* The user changed the interface name. If it now matches
|
|
Packit |
fabffb |
* parent and id, then update the last_* members, so we'll
|
|
Packit |
fabffb |
* start keeping it in sync again.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
if (iface_id == id)
|
|
Packit |
fabffb |
priv->last_id = iface_id;
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
priv->last_id = -1;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (priv->last_parent);
|
|
Packit |
fabffb |
if ( iface_len == parent_iface_len
|
|
Packit |
fabffb |
&& !strncmp (iface, parent_text, iface_len))
|
|
Packit |
fabffb |
priv->last_parent = g_strndup (iface, iface_len);
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
priv->last_parent = NULL;
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* The user changed the parent or ID; if the previous parent and
|
|
Packit |
fabffb |
* ID matched the interface name, then update the interface name
|
|
Packit |
fabffb |
* to match the new one as well.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
if (iface_id != priv->last_id)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
if ( !vlan_style_name
|
|
Packit |
fabffb |
&& priv->last_parent
|
|
Packit |
fabffb |
&& strncmp (iface, priv->last_parent, iface_len) != 0)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (vlan_style_name) {
|
|
Packit |
fabffb |
new_iface = g_strdup_printf ("vlan%d", id);
|
|
Packit |
fabffb |
} else if (changed_entry == priv->parent_entry) {
|
|
Packit |
fabffb |
new_iface = g_strdup_printf ("%.*s.%d",
|
|
Packit |
fabffb |
parent_iface_len,
|
|
Packit |
fabffb |
parent_text, id);
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
new_iface = g_strdup_printf ("%.*s.%d", iface_len, iface, id);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_signal_handlers_block_by_func (priv->name_entry, G_CALLBACK (name_changed), self);
|
|
Packit |
fabffb |
gtk_entry_set_text (priv->name_entry, new_iface);
|
|
Packit |
fabffb |
g_signal_handlers_unblock_by_func (priv->name_entry, G_CALLBACK (name_changed), self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (new_iface);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (changed_entry == priv->parent_entry) {
|
|
Packit |
fabffb |
g_free (priv->last_parent);
|
|
Packit |
fabffb |
priv->last_parent = g_strndup (parent_text, parent_iface_len);
|
|
Packit |
fabffb |
} else if (changed_entry == GTK_ENTRY (priv->id_entry))
|
|
Packit |
fabffb |
priv->last_id = id;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* The first item in the combo box may be an arbitrary string not contained in parents array */
|
|
Packit |
fabffb |
static int
|
|
Packit |
fabffb |
get_parents_index (int parents_len, GtkComboBox *box, int combo_index)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
int size;
|
|
Packit |
fabffb |
GtkTreeModel *model;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Get number of items in the combo box */
|
|
Packit |
fabffb |
model = gtk_combo_box_get_model (box);
|
|
Packit |
fabffb |
size = gtk_tree_model_iter_n_children (model, NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return combo_index - (size - parents_len);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
edit_parent_cb (NMConnectionEditor *editor, GtkResponseType response, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = user_data;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
NMConnection *connection;
|
|
Packit |
fabffb |
NMConnection *parent;
|
|
Packit |
fabffb |
NMSettingConnection *s_con;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (response != GTK_RESPONSE_OK)
|
|
Packit |
fabffb |
goto finish;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
connection = nm_connection_editor_get_connection (editor);
|
|
Packit |
fabffb |
parent = (NMConnection *)nm_client_get_connection_by_uuid (CE_PAGE (self)->client,
|
|
Packit |
fabffb |
nm_connection_get_uuid (connection));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
s_con = nm_connection_get_setting_connection (parent);
|
|
Packit |
fabffb |
gtk_entry_set_text (priv->parent_entry, nm_setting_connection_get_interface_name (s_con));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
finish:
|
|
Packit |
fabffb |
g_object_unref (editor);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
edit_parent (FUNC_TAG_NEW_CONNECTION_RESULT_IMPL,
|
|
Packit |
fabffb |
NMConnection *connection,
|
|
Packit |
fabffb |
gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = user_data;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
NMSettingConnection *s_con;
|
|
Packit |
fabffb |
NMConnectionEditor *editor;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!connection)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
s_con = nm_connection_get_setting_connection (CE_PAGE (self)->connection);
|
|
Packit |
fabffb |
g_object_set (G_OBJECT (s_con),
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
editor = ce_page_new_editor (CE_PAGE (self), priv->toplevel, connection);
|
|
Packit |
fabffb |
if (!editor)
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_signal_connect (editor, NM_CONNECTION_EDITOR_DONE, G_CALLBACK (edit_parent_cb), self);
|
|
Packit |
fabffb |
nm_connection_editor_run (editor);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static gboolean
|
|
Packit |
fabffb |
connection_type_filter (FUNC_TAG_NEW_CONNECTION_TYPE_FILTER_IMPL,
|
|
Packit |
fabffb |
GType type,
|
|
Packit |
fabffb |
gpointer self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
return nm_utils_check_virtual_device_compatibility (NM_TYPE_SETTING_VLAN, type);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
parent_changed (GtkWidget *widget, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = user_data;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
int active_id, parent_id;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
active_id = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->parent));
|
|
Packit |
fabffb |
parent_id = get_parents_index (priv->parents_len, GTK_COMBO_BOX (priv->parent), active_id);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (parent_id == priv->parents_len - 1) {
|
|
Packit |
fabffb |
gtk_entry_set_text (priv->parent_entry, "");
|
|
Packit |
fabffb |
new_connection_dialog (priv->toplevel,
|
|
Packit |
fabffb |
CE_PAGE (self)->client,
|
|
Packit |
fabffb |
connection_type_filter,
|
|
Packit |
fabffb |
edit_parent,
|
|
Packit |
fabffb |
self);
|
|
Packit |
fabffb |
return;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (parent_id > -1 && priv->parents[parent_id]->device != NULL) {
|
|
Packit |
fabffb |
gtk_widget_set_sensitive (GTK_WIDGET (priv->cloned_mac), TRUE);
|
|
Packit |
fabffb |
gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), TRUE);
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
gtk_widget_set_sensitive (GTK_WIDGET (priv->cloned_mac), FALSE);
|
|
Packit |
fabffb |
ce_page_setup_cloned_mac_combo (priv->cloned_mac, NULL);
|
|
Packit |
fabffb |
gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), FALSE);
|
|
Packit |
fabffb |
gtk_spin_button_set_value (priv->mtu, 1500);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
sync_iface (self, priv->parent_entry);
|
|
Packit |
fabffb |
ce_page_changed (CE_PAGE (self));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
name_changed (GtkWidget *w, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = user_data;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
sync_iface (self, priv->name_entry);
|
|
Packit |
fabffb |
ce_page_changed (CE_PAGE (self));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
id_changed (GtkWidget *w, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = user_data;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
sync_iface (self, GTK_ENTRY (priv->id_entry));
|
|
Packit |
fabffb |
ce_page_changed (CE_PAGE (self));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static int
|
|
Packit |
fabffb |
sort_parents (gconstpointer a, gconstpointer b)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
VlanParent *pa = *(VlanParent **)a;
|
|
Packit |
fabffb |
VlanParent *pb = *(VlanParent **)b;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (pa->connection && !pb->connection)
|
|
Packit |
fabffb |
return 1;
|
|
Packit |
fabffb |
else if (pb->connection && !pa->connection)
|
|
Packit |
fabffb |
return -1;
|
|
Packit |
fabffb |
return strcmp (pa->label, pb->label);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static GSList *
|
|
Packit |
fabffb |
get_vlan_devices (CEPageVlan *self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
const GPtrArray *devices_array;
|
|
Packit |
fabffb |
GSList *devices;
|
|
Packit |
fabffb |
NMDevice *device;
|
|
Packit |
fabffb |
int i;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
devices_array = nm_client_get_devices (CE_PAGE (self)->client);
|
|
Packit |
fabffb |
devices = NULL;
|
|
Packit |
fabffb |
for (i = 0; i < devices_array->len; i++) {
|
|
Packit |
fabffb |
device = devices_array->pdata[i];
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!nm_utils_check_virtual_device_compatibility (NM_TYPE_SETTING_VLAN,
|
|
Packit |
fabffb |
nm_device_get_setting_type (device)))
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
devices = g_slist_prepend (devices, device);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return devices;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
build_vlan_parent_list (CEPageVlan *self, GSList *devices)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
const GPtrArray *connections;
|
|
Packit |
fabffb |
GSList *d_iter;
|
|
Packit |
fabffb |
GPtrArray *parents;
|
|
Packit |
fabffb |
VlanParent *parent;
|
|
Packit |
fabffb |
NMDevice *device;
|
|
Packit |
fabffb |
const char *iface, *mac, *id;
|
|
Packit |
fabffb |
int i;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
parents = g_ptr_array_new ();
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Devices with no interesting L2 configuration can spawn VLANs directly. At the
|
|
Packit |
fabffb |
* moment, this means just Ethernet.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
for (d_iter = devices; d_iter; d_iter = d_iter->next) {
|
|
Packit |
fabffb |
device = d_iter->data;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!NM_IS_DEVICE_ETHERNET (device))
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
parent = g_slice_new (VlanParent);
|
|
Packit |
fabffb |
parent->device = device;
|
|
Packit |
fabffb |
parent->connection = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
iface = nm_device_get_iface (device);
|
|
Packit |
fabffb |
mac = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
|
|
Packit |
fabffb |
parent->label = g_strdup_printf ("%s (%s)", iface, mac);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_ptr_array_add (parents, parent);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Otherwise, VLANs have to be built on top of configured connections */
|
|
Packit |
fabffb |
connections = nm_client_get_connections (CE_PAGE (self)->client);
|
|
Packit |
fabffb |
for (i = 0; i < connections->len; i++) {
|
|
Packit |
fabffb |
NMConnection *candidate = connections->pdata[i];
|
|
Packit |
fabffb |
NMSettingConnection *s_con = nm_connection_get_setting_connection (candidate);
|
|
Packit |
fabffb |
GType connection_gtype;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (nm_setting_connection_get_master (s_con))
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
connection_gtype = nm_setting_lookup_type (nm_setting_connection_get_connection_type (s_con));
|
|
Packit |
fabffb |
if (!nm_utils_check_virtual_device_compatibility (NM_TYPE_SETTING_VLAN, connection_gtype))
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
for (d_iter = devices; d_iter; d_iter = d_iter->next) {
|
|
Packit |
fabffb |
device = d_iter->data;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (nm_device_connection_valid (device, candidate)) {
|
|
Packit |
fabffb |
parent = g_slice_new (VlanParent);
|
|
Packit |
fabffb |
parent->device = device;
|
|
Packit |
fabffb |
parent->connection = candidate;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
iface = nm_device_get_iface (device);
|
|
Packit |
fabffb |
id = nm_setting_connection_get_id (s_con);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Translators: the first %s is a device name (eg, "em1"), the
|
|
Packit |
fabffb |
* second is a connection name (eg, "Auto Ethernet").
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
parent->label = g_strdup_printf (_("%s (via “%s”)"), iface, id);
|
|
Packit |
fabffb |
g_ptr_array_add (parents, parent);
|
|
Packit |
fabffb |
/* no break here; the connection may apply to multiple devices */
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_ptr_array_sort (parents, sort_parents);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
parent = g_slice_new (VlanParent);
|
|
Packit |
fabffb |
parent->device = NULL;
|
|
Packit |
fabffb |
parent->connection = NULL;
|
|
Packit |
fabffb |
parent->label = g_strdup_printf (_("New connection…"));
|
|
Packit |
fabffb |
g_ptr_array_add (parents, parent);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_ptr_array_add (parents, NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
priv->parent_labels = g_new (char *, parents->len);
|
|
Packit |
fabffb |
priv->parents = (VlanParent **)g_ptr_array_free (parents, FALSE);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
for (i = 0; priv->parents[i]; i++)
|
|
Packit |
fabffb |
priv->parent_labels[i] = priv->parents[i]->label;
|
|
Packit |
fabffb |
priv->parent_labels[i] = NULL;
|
|
Packit |
fabffb |
priv->parents_len = i;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
populate_ui (CEPageVlan *self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
GSList *devices, *d_iter;
|
|
Packit |
fabffb |
NMConnection *parent_connection = NULL;
|
|
Packit |
fabffb |
NMDevice *device, *parent_device = NULL;
|
|
Packit |
fabffb |
const char *parent, *iface, *current_parent;
|
|
Packit |
fabffb |
int i, mtu_def, mtu_val;
|
|
Packit |
fabffb |
guint32 flags;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
devices = get_vlan_devices (self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Parent */
|
|
Packit |
fabffb |
build_vlan_parent_list (self, devices);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
parent = nm_setting_vlan_get_parent (priv->setting);
|
|
Packit |
fabffb |
if (parent) {
|
|
Packit |
fabffb |
/* UUID? */
|
|
Packit |
fabffb |
parent_connection = (NMConnection *)nm_client_get_connection_by_uuid (CE_PAGE (self)->client, parent);
|
|
Packit |
fabffb |
if (!parent_connection) {
|
|
Packit |
fabffb |
/* Interface name? */
|
|
Packit |
fabffb |
for (d_iter = devices; d_iter; d_iter = d_iter->next) {
|
|
Packit |
fabffb |
device = d_iter->data;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!g_strcmp0 (parent, nm_device_get_iface (device))) {
|
|
Packit |
fabffb |
parent_device = device;
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* If NMSettingVlan:parent didn't indicate a device, but we have a
|
|
Packit |
fabffb |
* wired setting, figure out the device from that.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
if (priv->s_hw && !parent_device) {
|
|
Packit |
fabffb |
const char *device_mac;
|
|
Packit |
fabffb |
const char *mac;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (NM_IS_SETTING_WIRED (priv->s_hw))
|
|
Packit |
fabffb |
mac = nm_setting_wired_get_mac_address (NM_SETTING_WIRED (priv->s_hw));
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
mac = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (mac) {
|
|
Packit |
fabffb |
for (d_iter = devices; d_iter; d_iter = d_iter->next) {
|
|
Packit |
fabffb |
device = d_iter->data;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (NM_IS_DEVICE_ETHERNET (device))
|
|
Packit |
fabffb |
device_mac = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
device_mac = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (device_mac && nm_utils_hwaddr_matches (mac, -1, device_mac, -1)) {
|
|
Packit |
fabffb |
parent_device = device;
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
current_parent = parent;
|
|
Packit |
fabffb |
if (parent_device || parent_connection) {
|
|
Packit |
fabffb |
for (i = 0; priv->parents[i]; i++) {
|
|
Packit |
fabffb |
if (parent_device && parent_device != priv->parents[i]->device)
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
if (parent_connection != priv->parents[i]->connection)
|
|
Packit |
fabffb |
continue;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
current_parent = priv->parents[i]->label;
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
g_signal_connect (priv->parent, "changed", G_CALLBACK (parent_changed), self);
|
|
Packit |
fabffb |
ce_page_setup_data_combo (CE_PAGE (self), priv->parent, current_parent, priv->parent_labels);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (current_parent)
|
|
Packit |
fabffb |
priv->last_parent = g_strndup (current_parent, strcspn (current_parent, " "));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Name */
|
|
Packit |
fabffb |
iface = nm_connection_get_interface_name (CE_PAGE (self)->connection);
|
|
Packit |
fabffb |
if (iface)
|
|
Packit |
fabffb |
gtk_entry_set_text (priv->name_entry, iface);
|
|
Packit |
fabffb |
g_signal_connect (priv->name_entry, "changed", G_CALLBACK (name_changed), self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* ID */
|
|
Packit |
fabffb |
priv->last_id = nm_setting_vlan_get_id (priv->setting);
|
|
Packit |
fabffb |
gtk_spin_button_set_value (priv->id_entry, priv->last_id);
|
|
Packit |
fabffb |
g_signal_connect (priv->id_entry, "value-changed", G_CALLBACK (id_changed), self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Cloned MAC address */
|
|
Packit |
fabffb |
if (NM_IS_SETTING_WIRED (priv->s_hw)) {
|
|
Packit |
fabffb |
const char *mac = nm_setting_wired_get_cloned_mac_address (NM_SETTING_WIRED (priv->s_hw));
|
|
Packit |
fabffb |
ce_page_setup_cloned_mac_combo (priv->cloned_mac, mac);
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
ce_page_setup_cloned_mac_combo (priv->cloned_mac, NULL);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* MTU */
|
|
Packit |
fabffb |
if (NM_IS_SETTING_WIRED (priv->s_hw)) {
|
|
Packit |
fabffb |
mtu_def = ce_get_property_default (priv->s_hw, NM_SETTING_WIRED_MTU);
|
|
Packit |
fabffb |
mtu_val = nm_setting_wired_get_mtu (NM_SETTING_WIRED (priv->s_hw));
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
mtu_def = mtu_val = 1500;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
ce_spin_automatic_val (priv->mtu, mtu_def);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_spin_button_set_value (priv->mtu, (gdouble) mtu_val);
|
|
Packit |
fabffb |
g_signal_connect (priv->mtu, "value-changed", G_CALLBACK (stuff_changed), self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Flags */
|
|
Packit |
fabffb |
flags = nm_setting_vlan_get_flags (priv->setting);
|
|
Packit |
fabffb |
if (flags & NM_VLAN_FLAG_REORDER_HEADERS)
|
|
Packit |
fabffb |
gtk_toggle_button_set_active (priv->flag_reorder_hdr, TRUE);
|
|
Packit |
fabffb |
if (flags & NM_VLAN_FLAG_GVRP)
|
|
Packit |
fabffb |
gtk_toggle_button_set_active (priv->flag_gvrp, TRUE);
|
|
Packit |
fabffb |
if (flags & NM_VLAN_FLAG_LOOSE_BINDING)
|
|
Packit |
fabffb |
gtk_toggle_button_set_active (priv->flag_loose_binding, TRUE);
|
|
Packit |
fabffb |
if (flags & NM_VLAN_FLAG_MVRP)
|
|
Packit |
fabffb |
gtk_toggle_button_set_active (priv->flag_mvrp, TRUE);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_slist_free (devices);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
finish_setup (CEPageVlan *self, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
populate_ui (self);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
CEPage *
|
|
Packit |
fabffb |
ce_page_vlan_new (NMConnectionEditor *editor,
|
|
Packit |
fabffb |
NMConnection *connection,
|
|
Packit |
fabffb |
GtkWindow *parent_window,
|
|
Packit |
fabffb |
NMClient *client,
|
|
Packit |
fabffb |
const char **out_secrets_setting_name,
|
|
Packit |
fabffb |
GError **error)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self;
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
self = CE_PAGE_VLAN (ce_page_new (CE_TYPE_PAGE_VLAN,
|
|
Packit |
fabffb |
editor,
|
|
Packit |
fabffb |
connection,
|
|
Packit |
fabffb |
parent_window,
|
|
Packit |
fabffb |
client,
|
|
Packit |
fabffb |
"/org/gnome/nm_connection_editor/ce-page-vlan.ui",
|
|
Packit |
fabffb |
"VlanPage",
|
|
Packit |
fabffb |
_("VLAN")));
|
|
Packit |
fabffb |
if (!self) {
|
|
Packit |
fabffb |
g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load vlan user interface."));
|
|
Packit |
fabffb |
return NULL;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
vlan_private_init (self);
|
|
Packit |
fabffb |
priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
priv->setting = nm_connection_get_setting_vlan (connection);
|
|
Packit |
fabffb |
if (!priv->setting) {
|
|
Packit |
fabffb |
priv->setting = NM_SETTING_VLAN (nm_setting_vlan_new ());
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, NM_SETTING (priv->setting));
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
priv->s_hw = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_signal_connect (self, CE_PAGE_INITIALIZED, G_CALLBACK (finish_setup), NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return CE_PAGE (self);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
ui_to_setting (CEPageVlan *self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
NMConnection *connection = CE_PAGE (self)->connection;
|
|
Packit |
fabffb |
NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
|
|
Packit |
fabffb |
char *cloned_mac = NULL;
|
|
Packit |
fabffb |
VlanParent *parent = NULL;
|
|
Packit |
fabffb |
int active_id, parent_id, vid;
|
|
Packit |
fabffb |
const char *parent_iface = NULL, *parent_uuid = NULL;
|
|
Packit |
fabffb |
const char *slave_type;
|
|
Packit |
fabffb |
const char *iface;
|
|
Packit |
fabffb |
char *tmp_parent_iface = NULL;
|
|
Packit |
fabffb |
GType hwtype;
|
|
Packit |
fabffb |
gboolean mtu_set;
|
|
Packit |
fabffb |
int mtu;
|
|
Packit |
fabffb |
guint32 flags = 0;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
active_id = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->parent));
|
|
Packit |
fabffb |
parent_id = get_parents_index (priv->parents_len, GTK_COMBO_BOX (priv->parent), active_id);
|
|
Packit |
fabffb |
if (parent_id < 0) {
|
|
Packit |
fabffb |
parent_iface = gtk_entry_get_text (priv->parent_entry);
|
|
Packit |
fabffb |
tmp_parent_iface = g_strndup (parent_iface, strcspn (parent_iface, " "));
|
|
Packit |
fabffb |
parent_iface = tmp_parent_iface;
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
parent = priv->parents[parent_id];
|
|
Packit |
fabffb |
if (parent->connection)
|
|
Packit |
fabffb |
parent_uuid = nm_connection_get_uuid (parent->connection);
|
|
Packit |
fabffb |
if (parent->device)
|
|
Packit |
fabffb |
parent_iface = nm_device_get_iface (parent->device);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_assert (parent_uuid != NULL || parent_iface != NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
slave_type = nm_setting_connection_get_slave_type (s_con);
|
|
Packit |
fabffb |
if (parent_uuid) {
|
|
Packit |
fabffb |
/* Update NMSettingConnection:master if it's set, but don't
|
|
Packit |
fabffb |
* set it if it's not.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME)) {
|
|
Packit |
fabffb |
g_object_set (s_con,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_MASTER, parent_uuid,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
} else if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME)) {
|
|
Packit |
fabffb |
g_object_set (s_con,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_MASTER, NULL,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_SLAVE_TYPE, NULL,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (parent && NM_IS_DEVICE_ETHERNET (parent->device))
|
|
Packit |
fabffb |
hwtype = NM_TYPE_SETTING_WIRED;
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
hwtype = G_TYPE_NONE;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (priv->s_hw && G_OBJECT_TYPE (priv->s_hw) != hwtype) {
|
|
Packit |
fabffb |
nm_connection_remove_setting (connection, G_OBJECT_TYPE (priv->s_hw));
|
|
Packit |
fabffb |
priv->s_hw = NULL;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
iface = gtk_entry_get_text (priv->name_entry);
|
|
Packit |
fabffb |
vid = gtk_spin_button_get_value_as_int (priv->id_entry);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Flags */
|
|
Packit |
fabffb |
if (gtk_toggle_button_get_active (priv->flag_reorder_hdr))
|
|
Packit |
fabffb |
flags |= NM_VLAN_FLAG_REORDER_HEADERS;
|
|
Packit |
fabffb |
if (gtk_toggle_button_get_active (priv->flag_gvrp))
|
|
Packit |
fabffb |
flags |= NM_VLAN_FLAG_GVRP;
|
|
Packit |
fabffb |
if (gtk_toggle_button_get_active (priv->flag_loose_binding))
|
|
Packit |
fabffb |
flags |= NM_VLAN_FLAG_LOOSE_BINDING;
|
|
Packit |
fabffb |
if (gtk_toggle_button_get_active (priv->flag_mvrp))
|
|
Packit |
fabffb |
flags |= NM_VLAN_FLAG_MVRP;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, *iface ? iface : NULL, NULL);
|
|
Packit |
fabffb |
g_object_set (priv->setting,
|
|
Packit |
fabffb |
NM_SETTING_VLAN_PARENT, parent_uuid ? parent_uuid : parent_iface,
|
|
Packit |
fabffb |
NM_SETTING_VLAN_ID, vid,
|
|
Packit |
fabffb |
NM_SETTING_VLAN_FLAGS, flags,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (hwtype != G_TYPE_NONE) {
|
|
Packit |
fabffb |
cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
|
|
Packit |
fabffb |
if (cloned_mac && !*cloned_mac)
|
|
Packit |
fabffb |
cloned_mac = NULL;
|
|
Packit |
fabffb |
mtu_set = g_ascii_isdigit (*gtk_entry_get_text (GTK_ENTRY (priv->mtu)));
|
|
Packit |
fabffb |
mtu = gtk_spin_button_get_value_as_int (priv->mtu);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (cloned_mac || mtu_set) {
|
|
Packit |
fabffb |
if (!priv->s_hw) {
|
|
Packit |
fabffb |
priv->s_hw = g_object_new (hwtype, NULL);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, priv->s_hw);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_object_set (priv->s_hw,
|
|
Packit |
fabffb |
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac,
|
|
Packit |
fabffb |
NM_SETTING_WIRED_MTU, (guint32) mtu,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
} else if (priv->s_hw) {
|
|
Packit |
fabffb |
nm_connection_remove_setting (connection, G_OBJECT_TYPE (priv->s_hw));
|
|
Packit |
fabffb |
priv->s_hw = NULL;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (tmp_parent_iface);
|
|
Packit |
fabffb |
g_free (cloned_mac);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static gboolean
|
|
Packit |
fabffb |
ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = CE_PAGE_VLAN (page);
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
const char *parent;
|
|
Packit |
fabffb |
char *parent_iface;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (gtk_combo_box_get_active (GTK_COMBO_BOX (priv->parent)) == -1) {
|
|
Packit |
fabffb |
parent = gtk_entry_get_text (priv->parent_entry);
|
|
Packit |
fabffb |
parent_iface = g_strndup (parent, strcspn (parent, " "));
|
|
Packit |
fabffb |
if (!ce_page_interface_name_valid (parent_iface, _("vlan parent"), error)) {
|
|
Packit |
fabffb |
g_free (parent_iface);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
g_free (parent_iface);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
ui_to_setting (self);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if ( priv->s_hw
|
|
Packit |
fabffb |
&& !nm_setting_verify (priv->s_hw, NULL, error))
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return nm_setting_verify (NM_SETTING (priv->setting), NULL, error);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
finalize (GObject *object)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
CEPageVlan *self = CE_PAGE_VLAN (object);
|
|
Packit |
fabffb |
CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
|
|
Packit |
fabffb |
int i;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (priv->last_parent);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
for (i = 0; priv->parents[i]; i++)
|
|
Packit |
fabffb |
g_slice_free (VlanParent, priv->parents[i]);
|
|
Packit |
fabffb |
g_free (priv->parents);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
G_OBJECT_CLASS (ce_page_vlan_parent_class)->finalize (object);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
ce_page_vlan_init (CEPageVlan *self)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
ce_page_vlan_class_init (CEPageVlanClass *vlan_class)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
GObjectClass *object_class = G_OBJECT_CLASS (vlan_class);
|
|
Packit |
fabffb |
CEPageClass *parent_class = CE_PAGE_CLASS (vlan_class);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_type_class_add_private (object_class, sizeof (CEPageVlanPrivate));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* virtual methods */
|
|
Packit |
fabffb |
object_class->finalize = finalize;
|
|
Packit |
fabffb |
parent_class->ce_page_validate_v = ce_page_validate_v;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
void
|
|
Packit |
fabffb |
vlan_connection_new (FUNC_TAG_PAGE_NEW_CONNECTION_IMPL,
|
|
Packit |
fabffb |
GtkWindow *parent,
|
|
Packit |
fabffb |
const char *detail,
|
|
Packit |
fabffb |
gpointer detail_data,
|
|
Packit |
fabffb |
NMConnection *connection,
|
|
Packit |
fabffb |
NMClient *client,
|
|
Packit |
fabffb |
PageNewConnectionResultFunc result_func,
|
|
Packit |
fabffb |
gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
gs_unref_object NMConnection *connection_tmp = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
connection = _ensure_connection_other (connection, &connection_tmp);
|
|
Packit |
fabffb |
ce_page_complete_connection (connection,
|
|
Packit |
fabffb |
_("VLAN connection %d"),
|
|
Packit |
fabffb |
NM_SETTING_VLAN_SETTING_NAME,
|
|
Packit |
fabffb |
TRUE,
|
|
Packit |
fabffb |
client);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, nm_setting_vlan_new ());
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
(*result_func) (FUNC_TAG_PAGE_NEW_CONNECTION_RESULT_CALL, connection, FALSE, NULL, user_data);
|
|
Packit |
fabffb |
}
|