[network-manager-applet/danw/bridge: 3/3] connection-editor: add support for bridges
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/danw/bridge: 3/3] connection-editor: add support for bridges
- Date: Fri, 2 Nov 2012 15:04:13 +0000 (UTC)
commit 157643ab054bd36ad7e9296456a8b39d0a6d9ce4
Author: Dan Winship <danw gnome org>
Date: Thu Nov 1 15:46:37 2012 -0400
connection-editor: add support for bridges
src/connection-editor/Makefile.am | 3 +
src/connection-editor/ce-page-bridge.ui | 471 ++++++++++++++++++++++++++
src/connection-editor/new-connection.c | 7 +
src/connection-editor/nm-connection-editor.c | 5 +
src/connection-editor/nm-connection-list.c | 9 +-
src/connection-editor/page-bridge.c | 360 ++++++++++++++++++++
src/connection-editor/page-bridge.h | 62 ++++
7 files changed, 914 insertions(+), 3 deletions(-)
---
diff --git a/src/connection-editor/Makefile.am b/src/connection-editor/Makefile.am
index 742a7da..006a79c 100644
--- a/src/connection-editor/Makefile.am
+++ b/src/connection-editor/Makefile.am
@@ -56,6 +56,8 @@ nm_connection_editor_SOURCES = \
page-master.c \
page-bond.h \
page-bond.c \
+ page-bridge.h \
+ page-bridge.c \
page-vlan.h \
page-vlan.c \
vpn-helpers.h \
@@ -94,6 +96,7 @@ ui_DATA = \
ce-page-wimax.ui \
ce-page-infiniband.ui \
ce-page-bond.ui \
+ ce-page-bridge.ui \
ce-page-ip4.ui \
ce-ip4-routes.ui \
ce-page-ip6.ui \
diff --git a/src/connection-editor/ce-page-bridge.ui b/src/connection-editor/ce-page-bridge.ui
new file mode 100644
index 0000000..b499540
--- /dev/null
+++ b/src/connection-editor/ce-page-bridge.ui
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkAdjustment" id="bridge_ageing_time_adjustment">
+ <property name="upper">4294967296</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="bridge_forward_delay_adjustment">
+ <property name="upper">30</property>
+ <property name="value">15</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">100</property>
+ </object>
+ <object class="GtkAdjustment" id="bridge_hello_time_adjustment">
+ <property name="lower">1</property>
+ <property name="upper">10</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="bridge_max_age_adjustment">
+ <property name="lower">6</property>
+ <property name="upper">40</property>
+ <property name="value">6</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="bridge_priority_adjustment">
+ <property name="upper">65535</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkListStore" id="master_connections_model">
+ <columns>
+ <!-- column-name connection -->
+ <column type="NMRemoteConnection"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTable" id="BridgePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">9</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="master_connections_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Bridged _connections:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="master_connections">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">master_connections_model</property>
+ <property name="headers_visible">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="master_connection_name">
+ <child>
+ <object class="GtkCellRendererText" id="master_connection_renderer"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="master_connection_add">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="master_connection_edit">
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="master_connection_delete">
+ <property name="label" translatable="yes">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bridge_prio">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Priority:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="master_interface_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Interface name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">master_interface</property>
+ </object>
+ <packing>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="master_interface">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bridge_forward_delay_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Forward delay:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bridge_forward_delay</property>
+ </object>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bridge_hello_time_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Hello time:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bridge_hello_time</property>
+ </object>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="bridge_forward_delay_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkSpinButton" id="bridge_forward_delay">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">bridge_forward_delay_adjustment</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">s</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="bridge_hello_time_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkSpinButton" id="bridge_hello_time">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">bridge_hello_time_adjustment</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">s</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="bridge_stp_checkbox">
+ <property name="label" translatable="yes">Enable _STP (Spanning Tree Protocol)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="bridge_priority">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">bridge_priority_adjustment</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bridge_max_age_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Max age:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bridge_max_age</property>
+ </object>
+ <packing>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="bridge_max_age_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkSpinButton" id="bridge_max_age">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">bridge_max_age_adjustment</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">s</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bridge_ageing_time_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Aging time:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bridge_ageing_time</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="bridge_ageing_time_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkSpinButton" id="bridge_ageing_time">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">bridge_ageing_time_adjustment</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">s</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/src/connection-editor/new-connection.c b/src/connection-editor/new-connection.c
index 4a6e1a6..e60cfda 100644
--- a/src/connection-editor/new-connection.c
+++ b/src/connection-editor/new-connection.c
@@ -32,6 +32,7 @@
#include "page-dsl.h"
#include "page-infiniband.h"
#include "page-bond.h"
+#include "page-bridge.h"
#include "page-vlan.h"
#include "page-vpn.h"
#include "vpn-helpers.h"
@@ -139,6 +140,12 @@ get_connection_type_list (void)
data.virtual = TRUE;
g_array_append_val (array, data);
+ data.name = _("Bridge");
+ data.new_connection_func = bridge_connection_new;
+ data.setting_type = NM_TYPE_SETTING_BRIDGE;
+ data.virtual = TRUE;
+ g_array_append_val (array, data);
+
data.name = _("VLAN");
data.new_connection_func = vlan_connection_new;
data.setting_type = NM_TYPE_SETTING_VLAN;
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 0b99566..93ba2e3 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -48,6 +48,7 @@
#include <nm-setting-wimax.h>
#include <nm-setting-infiniband.h>
#include <nm-setting-bond.h>
+#include <nm-setting-bridge.h>
#include <nm-utils.h>
#include <nm-remote-connection.h>
@@ -70,6 +71,7 @@
#include "page-wimax.h"
#include "page-infiniband.h"
#include "page-bond.h"
+#include "page-bridge.h"
#include "page-vlan.h"
#include "ce-polkit-button.h"
#include "vpn-helpers.h"
@@ -843,6 +845,9 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor,
} else if (!strcmp (connection_type, NM_SETTING_BOND_SETTING_NAME)) {
if (!add_page (editor, ce_page_bond_new, editor->connection, error))
goto out;
+ } else if (!strcmp (connection_type, NM_SETTING_BRIDGE_SETTING_NAME)) {
+ if (!add_page (editor, ce_page_bridge_new, editor->connection, error))
+ goto out;
} else if (!strcmp (connection_type, NM_SETTING_VLAN_SETTING_NAME)) {
if (!add_page (editor, ce_page_vlan_new, editor->connection, error))
goto out;
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 2a7b708..f445edf 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -570,16 +570,19 @@ tree_model_visible_func (GtkTreeModel *model,
return gtk_tree_model_iter_has_child (model, iter);
}
- /* A connection node is visible unless it is a bond slave to
- * another known connection.
+ /* A connection node is visible unless it is a slave to a known
+ * bond or bridge.
*/
s_con = nm_connection_get_setting_connection (connection);
g_object_unref (connection);
g_return_val_if_fail (s_con != NULL, FALSE);
master = nm_setting_connection_get_master (s_con);
+ if (!master)
+ return TRUE;
slave_type = nm_setting_connection_get_slave_type (s_con);
- if (!master || g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME) != 0)
+ if ( g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME) != 0
+ && g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) != 0)
return TRUE;
if (nm_remote_settings_get_connection_by_uuid (self->settings, master))
diff --git a/src/connection-editor/page-bridge.c b/src/connection-editor/page-bridge.c
new file mode 100644
index 0000000..119bde2
--- /dev/null
+++ b/src/connection-editor/page-bridge.c
@@ -0,0 +1,360 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2012 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-bridge.h>
+
+#include "page-bridge.h"
+#include "nm-connection-editor.h"
+#include "new-connection.h"
+
+G_DEFINE_TYPE (CEPageBridge, ce_page_bridge, CE_TYPE_PAGE_MASTER)
+
+#define CE_PAGE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_BRIDGE, CEPageBridgePrivate))
+
+typedef struct {
+ NMSettingBridge *setting;
+
+ GtkWindow *toplevel;
+
+ GtkSpinButton *ageing_time;
+ GtkCheckButton *stp;
+ GtkSpinButton *priority;
+ GtkSpinButton *forward_delay;
+ GtkSpinButton *hello_time;
+ GtkSpinButton *max_age;
+
+} CEPageBridgePrivate;
+
+static void
+bridge_private_init (CEPageBridge *self)
+{
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+ GtkBuilder *builder;
+
+ builder = CE_PAGE (self)->builder;
+
+ priv->ageing_time = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "bridge_ageing_time"));
+ priv->stp = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "bridge_stp_checkbox"));
+ priv->priority = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "bridge_priority"));
+ priv->forward_delay = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "bridge_forward_delay"));
+ priv->hello_time = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "bridge_hello_time"));
+ priv->max_age = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "bridge_max_age"));
+
+ priv->toplevel = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (priv->stp),
+ GTK_TYPE_WINDOW));
+}
+
+static void
+stuff_changed (GtkWidget *w, gpointer user_data)
+{
+ ce_page_changed (CE_PAGE (user_data));
+}
+
+static void
+stp_toggled (GtkToggleButton *stp, gpointer user_data)
+{
+ CEPageBridge *self = user_data;
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+
+ if (gtk_toggle_button_get_active (stp)) {
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->priority), TRUE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->forward_delay), TRUE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->hello_time), TRUE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->max_age), TRUE);
+ } else {
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->priority), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->forward_delay), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->hello_time), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->max_age), FALSE);
+ }
+}
+
+static void
+populate_ui (CEPageBridge *self)
+{
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+ NMSettingBridge *setting = priv->setting;
+ const char *stp, *priority, *forward_delay, *hello_time, *max_age;
+ const char *ageing_time;
+
+ /* Ageing time */
+ ageing_time = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_AGEING_TIME);
+ if (!ageing_time)
+ ageing_time = nm_setting_bridge_get_option_default (setting, NM_SETTING_BRIDGE_OPTION_AGEING_TIME);
+ if (!ageing_time)
+ ageing_time = "0";
+ gtk_spin_button_set_value (priv->ageing_time, (gdouble) atoi (ageing_time));
+ g_signal_connect (priv->ageing_time, "value-changed",
+ G_CALLBACK (stuff_changed),
+ self);
+
+ /* STP */
+ g_signal_connect (priv->stp, "toggled",
+ G_CALLBACK (stp_toggled),
+ self);
+ stp = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_STP);
+ if (!g_strcmp0 (stp, "on") || !g_strcmp0 (stp, "yes"))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->stp), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->stp), FALSE);
+
+ /* Priority */
+ priority = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_PRIO);
+ if (!priority)
+ priority = nm_setting_bridge_get_option_default (setting, NM_SETTING_BRIDGE_OPTION_PRIO);
+ if (!priority)
+ priority = "0";
+ gtk_spin_button_set_value (priv->priority, (gdouble) atoi (priority));
+ g_signal_connect (priv->priority, "value-changed",
+ G_CALLBACK (stuff_changed),
+ self);
+
+ /* Forward delay */
+ forward_delay = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_FORWARD_DELAY);
+ if (!forward_delay)
+ forward_delay = nm_setting_bridge_get_option_default (setting, NM_SETTING_BRIDGE_OPTION_FORWARD_DELAY);
+ if (!forward_delay)
+ forward_delay = "0";
+ gtk_spin_button_set_value (priv->forward_delay, (gdouble) atoi (forward_delay));
+ g_signal_connect (priv->forward_delay, "value-changed",
+ G_CALLBACK (stuff_changed),
+ self);
+
+ /* Hello time */
+ hello_time = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_HELLO_TIME);
+ if (!hello_time)
+ hello_time = nm_setting_bridge_get_option_default (setting, NM_SETTING_BRIDGE_OPTION_HELLO_TIME);
+ if (!hello_time)
+ hello_time = "0";
+ gtk_spin_button_set_value (priv->hello_time, (gdouble) atoi (hello_time));
+ g_signal_connect (priv->hello_time, "value-changed",
+ G_CALLBACK (stuff_changed),
+ self);
+
+ /* Max age */
+ max_age = nm_setting_bridge_get_option_by_name (setting, NM_SETTING_BRIDGE_OPTION_MAX_AGE);
+ if (!max_age)
+ max_age = nm_setting_bridge_get_option_default (setting, NM_SETTING_BRIDGE_OPTION_MAX_AGE);
+ if (!max_age)
+ max_age = "0";
+ gtk_spin_button_set_value (priv->max_age, (gdouble) atoi (max_age));
+ g_signal_connect (priv->max_age, "value-changed",
+ G_CALLBACK (stuff_changed),
+ self);
+}
+
+static gboolean
+connection_type_filter (GType type, gpointer user_data)
+{
+ if (type == NM_TYPE_SETTING_WIRED ||
+ type == NM_TYPE_SETTING_WIRELESS ||
+ type == NM_TYPE_SETTING_VLAN)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void
+add_slave (CEPageMaster *master, NewConnectionResultFunc result_func)
+{
+ CEPageBridge *self = CE_PAGE_BRIDGE (master);
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+
+ new_connection_dialog (priv->toplevel,
+ CE_PAGE (self)->settings,
+ connection_type_filter,
+ result_func,
+ master);
+}
+
+static void
+finish_setup (CEPageBridge *self, gpointer unused, GError *error, gpointer user_data)
+{
+ if (error)
+ return;
+
+ populate_ui (self);
+}
+
+CEPage *
+ce_page_bridge_new (NMConnection *connection,
+ GtkWindow *parent_window,
+ NMClient *client,
+ NMRemoteSettings *settings,
+ const char **out_secrets_setting_name,
+ GError **error)
+{
+ CEPageBridge *self;
+ CEPageBridgePrivate *priv;
+
+ self = CE_PAGE_BRIDGE (ce_page_new (CE_TYPE_PAGE_BRIDGE,
+ connection,
+ parent_window,
+ client,
+ settings,
+ UIDIR "/ce-page-bridge.ui",
+ "BridgePage",
+ _("Bridge")));
+ if (!self) {
+ g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC,
+ _("Could not load bridge user interface."));
+ return NULL;
+ }
+
+ bridge_private_init (self);
+ priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+
+ priv->setting = nm_connection_get_setting_bridge (connection);
+ if (!priv->setting) {
+ priv->setting = NM_SETTING_BRIDGE (nm_setting_bridge_new ());
+ nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+ }
+
+ g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);
+
+ return CE_PAGE (self);
+}
+
+static void
+ui_to_setting (CEPageBridge *self)
+{
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+ const char *ageing_time;
+ const char *priority;
+ const char *forward_delay;
+ const char *hello_time;
+ const char *max_age;
+
+ ageing_time = gtk_entry_get_text (GTK_ENTRY (priv->ageing_time));
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_AGEING_TIME, ageing_time);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->stp))) {
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_STP, "yes");
+ priority = gtk_entry_get_text (GTK_ENTRY (priv->priority));
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_PRIO, priority);
+ forward_delay = gtk_entry_get_text (GTK_ENTRY (priv->forward_delay));
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_FORWARD_DELAY, forward_delay);
+ hello_time = gtk_entry_get_text (GTK_ENTRY (priv->hello_time));
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_HELLO_TIME, hello_time);
+ max_age = gtk_entry_get_text (GTK_ENTRY (priv->max_age));
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_MAX_AGE, max_age);
+ } else {
+ nm_setting_bridge_add_option (priv->setting, NM_SETTING_BRIDGE_OPTION_STP, "no");
+ nm_setting_bridge_remove_option (priv->setting, NM_SETTING_BRIDGE_OPTION_PRIO);
+ nm_setting_bridge_remove_option (priv->setting, NM_SETTING_BRIDGE_OPTION_FORWARD_DELAY);
+ nm_setting_bridge_remove_option (priv->setting, NM_SETTING_BRIDGE_OPTION_HELLO_TIME);
+ nm_setting_bridge_remove_option (priv->setting, NM_SETTING_BRIDGE_OPTION_MAX_AGE);
+ }
+}
+
+static gboolean
+validate (CEPage *page, NMConnection *connection, GError **error)
+{
+ CEPageBridge *self = CE_PAGE_BRIDGE (page);
+ CEPageBridgePrivate *priv = CE_PAGE_BRIDGE_GET_PRIVATE (self);
+
+ if (!CE_PAGE_CLASS (ce_page_bridge_parent_class)->validate (page, connection, error))
+ return FALSE;
+
+ ui_to_setting (self);
+ return nm_setting_verify (NM_SETTING (priv->setting), NULL, error);
+}
+
+static void
+ce_page_bridge_init (CEPageBridge *self)
+{
+}
+
+static void
+ce_page_bridge_class_init (CEPageBridgeClass *bridge_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (bridge_class);
+ CEPageClass *parent_class = CE_PAGE_CLASS (bridge_class);
+ CEPageMasterClass *master_class = CE_PAGE_MASTER_CLASS (bridge_class);
+
+ g_type_class_add_private (object_class, sizeof (CEPageBridgePrivate));
+
+ /* virtual methods */
+ parent_class->validate = validate;
+ master_class->add_slave = add_slave;
+}
+
+void
+bridge_connection_new (GtkWindow *parent,
+ const char *detail,
+ NMRemoteSettings *settings,
+ PageNewConnectionResultFunc result_func,
+ gpointer user_data)
+{
+ NMConnection *connection;
+ int bridge_num, max_bridge_num, num;
+ GSList *connections, *iter;
+ NMConnection *conn2;
+ NMSettingBridge *s_bridge;
+ const char *iface;
+ char *my_iface;
+
+ connection = ce_page_new_connection (_("Bridge connection %d"),
+ NM_SETTING_BRIDGE_SETTING_NAME,
+ TRUE,
+ settings,
+ user_data);
+ nm_connection_add_setting (connection, nm_setting_bridge_new ());
+
+ /* Find an available interface name */
+ bridge_num = max_bridge_num = 0;
+ connections = nm_remote_settings_list_connections (settings);
+ for (iter = connections; iter; iter = iter->next) {
+ conn2 = iter->data;
+
+ if (!nm_connection_is_type (conn2, NM_SETTING_BRIDGE_SETTING_NAME))
+ continue;
+ s_bridge = nm_connection_get_setting_bridge (conn2);
+ if (!s_bridge)
+ continue;
+ iface = nm_setting_bridge_get_interface_name (s_bridge);
+ if (!iface || strncmp (iface, "bridge", 4) != 0 || !g_ascii_isdigit (iface[4]))
+ continue;
+
+ num = atoi (iface + 4);
+ if (num > max_bridge_num)
+ max_bridge_num = num;
+ if (num == bridge_num)
+ bridge_num = max_bridge_num + 1;
+ }
+ g_slist_free (connections);
+
+ my_iface = g_strdup_printf ("bridge%d", bridge_num);
+ s_bridge = nm_connection_get_setting_bridge (connection);
+ g_object_set (G_OBJECT (s_bridge),
+ NM_SETTING_BRIDGE_INTERFACE_NAME, my_iface,
+ NULL);
+ g_free (my_iface);
+
+ (*result_func) (connection, FALSE, NULL, user_data);
+}
+
diff --git a/src/connection-editor/page-bridge.h b/src/connection-editor/page-bridge.h
new file mode 100644
index 0000000..fa6d927
--- /dev/null
+++ b/src/connection-editor/page-bridge.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2012 Red Hat, Inc.
+ */
+
+#ifndef __PAGE_BRIDGE_H__
+#define __PAGE_BRIDGE_H__
+
+#include <nm-connection.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "page-master.h"
+
+#define CE_TYPE_PAGE_BRIDGE (ce_page_bridge_get_type ())
+#define CE_PAGE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_BRIDGE, CEPageBridge))
+#define CE_PAGE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_BRIDGE, CEPageBridgeClass))
+#define CE_IS_PAGE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_BRIDGE))
+#define CE_IS_PAGE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_BRIDGE))
+#define CE_PAGE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_BRIDGE, CEPageBridgeClass))
+
+typedef struct {
+ CEPageMaster parent;
+} CEPageBridge;
+
+typedef struct {
+ CEPageMasterClass parent;
+} CEPageBridgeClass;
+
+GType ce_page_bridge_get_type (void);
+
+CEPage *ce_page_bridge_new (NMConnection *connection,
+ GtkWindow *parent,
+ NMClient *client,
+ NMRemoteSettings *settings,
+ const char **out_secrets_setting_name,
+ GError **error);
+
+void bridge_connection_new (GtkWindow *parent,
+ const char *detail,
+ NMRemoteSettings *settings,
+ PageNewConnectionResultFunc result_func,
+ gpointer user_data);
+
+#endif /* __PAGE_BRIDGE_H__ */
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]