[PATCH 3/4] bridge: Create NMDeviceEthernet for bridge devices



Connection is matched against settings via the interface name just like
with bonding.

Signed-off-by: Thomas Graf <tgraf redhat com>
---
 src/nm-device-ethernet.c |    9 +++-
 src/nm-device-ethernet.h |    1 +
 src/nm-manager.c         |   10 ++++
 src/nm-system.c          |  121 +++++++++++++++++++++++++++++++++++++++++++++-
 src/nm-system.h          |    5 ++
 src/nm-udev-manager.c    |    4 ++
 6 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index e88e09d..e0aa6ca 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -49,6 +49,7 @@
 #include "nm-setting-8021x.h"
 #include "nm-setting-pppoe.h"
 #include "nm-setting-bond.h"
+#include "nm-setting-bridge.h"
 #include "ppp-manager/nm-ppp-manager.h"
 #include "nm-logging.h"
 #include "nm-properties-changed-signal.h"
@@ -77,6 +78,7 @@ typedef enum
 {
 	NM_ETHERNET_TYPE_UNSPEC = 0,
 	NM_ETHERNET_TYPE_BOND,
+	NM_ETHERNET_TYPE_BRIDGE,
 } NMEthernetType;
 
 typedef struct Supplicant {
@@ -291,6 +293,8 @@ constructor (GType type,
 	//        when the device is created.
 	if (!strcmp(nm_device_get_driver (self), "bonding"))
 		priv->type = NM_ETHERNET_TYPE_BOND;
+	else if (!strcmp (nm_device_get_driver (self), "bridge"))
+		priv->type = NM_ETHERNET_TYPE_BRIDGE;
 	else
 		priv->type = NM_ETHERNET_TYPE_UNSPEC;
 
@@ -338,6 +342,7 @@ device_state_changed (NMDevice *device,
 	case NM_DEVICE_STATE_UNAVAILABLE:
 		switch (priv->type) {
 		case NM_ETHERNET_TYPE_BOND:
+		case NM_ETHERNET_TYPE_BRIDGE:
 			/* Use NM_DEVICE_STATE_REASON_CARRIER to make sure num retries is reset */
 			nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
 			break;
@@ -619,6 +624,8 @@ match_ethernet_connection (NMDevice *device, NMConnection *connection,
 		/* NOP */
 	} else if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) {
 		/* NOP */
+	} else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) {
+		/* NOP */
 	} else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) {
 		if (!s_wired) {
 			g_set_error (error,
@@ -629,7 +636,7 @@ match_ethernet_connection (NMDevice *device, NMConnection *connection,
 	} else {
 		g_set_error (error,
 		             NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED,
-		             "The connection was not a wired, bond, or PPPoE connection.");
+		             "The connection was not a wired, bond, bridge, or PPPoE connection.");
 		return FALSE;
 	}
 
diff --git a/src/nm-device-ethernet.h b/src/nm-device-ethernet.h
index 51993db..7464b50 100644
--- a/src/nm-device-ethernet.h
+++ b/src/nm-device-ethernet.h
@@ -60,6 +60,7 @@ NMDevice *nm_device_ethernet_new (const char *udi,
                                   const char *driver);
 
 gboolean nm_device_bond_connection_matches (NMDevice *device, NMConnection *connection);
+gboolean nm_device_bridge_connection_matches (NMDevice *device, NMConnection *connection);
 
 G_END_DECLS
 
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f689837..324e1a0 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -944,6 +944,9 @@ connection_needs_virtual_device (NMConnection *connection)
 	if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
 		return TRUE;
 
+	if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME))
+		return TRUE;
+
 	return FALSE;
 }
 
@@ -957,6 +960,13 @@ system_update_virtual_device (NMConnection *connection)
 		g_assert (s_bond);
 
 		return nm_system_add_bonding_master (s_bond);
+	} else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) {
+		NMSettingBridge *s_bridge;
+
+		s_bridge = nm_connection_get_setting_bridge (connection);
+		g_assert (s_bridge);
+
+		return nm_system_add_bridge (s_bridge);
 	}
 
 	return TRUE;
diff --git a/src/nm-system.c b/src/nm-system.c
index 08f5084..de17c44 100644
--- a/src/nm-system.c
+++ b/src/nm-system.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2012 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
  * Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi fore com>
  * Copyright (C) January, 1998 Sergei Viznyuk <sv phystech com>
@@ -44,6 +44,7 @@
 #include <linux/if.h>
 #include <linux/sockios.h>
 #include <linux/if_bonding.h>
+#include <linux/if_bridge.h>
 
 #include "nm-system.h"
 #include "nm-device.h"
@@ -1528,9 +1529,127 @@ nm_system_get_iface_type (const char *name)
 		res = NM_IFACE_TYPE_VLAN;
 	else if (!g_strcmp0 (type, "dummy"))
 		res = NM_IFACE_TYPE_DUMMY;
+	else if (!g_strcmp0 (type, "bridge"))
+		res = NM_IFACE_TYPE_BRIDGE;
 
 	rtnl_link_put (result);
 out:
 	return res;
 }
 
+static int
+nm_system_add_bridge_compat (const char *name)
+{
+	int ret, fd;
+
+	if ((fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) {
+		nm_log_err (LOGD_DEVICE, "couldn't open control socket.");
+		return FALSE;
+	}
+
+#ifdef SIOCBRADDBR
+	ret = ioctl(fd, SIOCBRADDBR, name);
+	if (ret < 0)
+#endif
+	{
+		char _br[IFNAMSIZ];
+		unsigned long arg[3] = { BRCTL_ADD_BRIDGE, (unsigned long) _br };
+
+		strncpy(_br, name, IFNAMSIZ);
+		ret = ioctl(fd, SIOCSIFBR, arg);
+	}
+
+	close (fd);
+
+	return ret;
+}
+
+/**
+ * nm_system_add_bridge:
+ * @s_bridge: Bridge device settings
+ *
+ * Creates a new bridging device according to the settings specified. If
+ * a bridging device with the specified name already exists, it is being
+ * reused and its settings are updated.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ */
+gboolean
+nm_system_add_bridge (NMSettingBridge *s_bridge)
+{
+	const char *name;
+	int err;
+
+	name = nm_setting_bridge_get_interface_name (s_bridge);
+	g_assert (name);
+
+	err = nm_system_add_bridge_compat (name);
+	if (err == -EEXIST) {
+		/* Reuse existing bridging devices */
+		goto configure;
+	} else if (err < 0) {
+		nm_log_err (LOGD_DEVICE, "(%s): error while adding bridge: %s ",
+		            name, strerror(err));
+		return FALSE;
+	}
+
+configure:
+	/* FIXME: apply bridging settings */
+
+	return TRUE;
+}
+
+static int
+nm_system_del_bridge_compat (const char *name)
+{
+	int ret, fd;
+
+	if ((fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) {
+		nm_log_err (LOGD_DEVICE, "couldn't open control socket.");
+		return FALSE;
+	}
+
+#ifdef SIOCBRDELBR
+	ret = ioctl(fd, SIOCBRDELBR, name);
+	if (ret < 0)
+#endif
+	{
+		char _br[IFNAMSIZ];
+		unsigned long arg[3]
+			= { BRCTL_DEL_BRIDGE, (unsigned long) _br };
+
+		strncpy(_br, name, IFNAMSIZ);
+		ret = ioctl(fd, SIOCSIFBR, arg);
+	}
+
+	close (fd);
+
+	return ret;
+}
+
+/**
+ * nm_system_del_bridge:
+ * @s_bridge: Bridge device settings
+ *
+ * Deletes the bridge device specified in the specified settings.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ */
+gboolean
+nm_system_del_bridge (NMSettingBridge *s_bridge)
+{
+	const char *name;
+	int err;
+
+	name = nm_setting_bridge_get_interface_name (s_bridge);
+	g_assert (name);
+
+	err = nm_system_del_bridge_compat (name);
+	if (err < 0) {
+		nm_log_err (LOGD_DEVICE, "(%s): error while deleting bridge: %s ",
+		            name, strerror(err));
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/src/nm-system.h b/src/nm-system.h
index 34bfb86..382ff6c 100644
--- a/src/nm-system.h
+++ b/src/nm-system.h
@@ -31,6 +31,7 @@
 #include "nm-device.h"
 #include "nm-ip4-config.h"
 #include "nm-setting-bond.h"
+#include "nm-setting-bridge.h"
 
 /* Prototypes for system/distribution dependent functions,
  * implemented in the backend files in backends/ directory
@@ -98,8 +99,12 @@ enum {
 		NM_IFACE_TYPE_BOND,
 		NM_IFACE_TYPE_VLAN,
 		NM_IFACE_TYPE_DUMMY,
+		NM_IFACE_TYPE_BRIDGE,
 };
 
 int             nm_system_get_iface_type                (const char *name);
 
+gboolean        nm_system_add_bridge                    (NMSettingBridge *s_bridge);
+gboolean        nm_system_del_bridge                    (NMSettingBridge *s_bridge);
+
 #endif
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index 2e250e8..5ee8454 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -433,6 +433,10 @@ device_creator (NMUdevManager *manager,
 			driver = "bonding";
 			break;
 
+		case NM_IFACE_TYPE_BRIDGE:
+			driver = "bridge";
+			break;
+
 		default:
 			if (g_str_has_prefix (ifname, "easytether"))
 				driver = "easytether";
-- 
1.7.7.6



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]