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

Signed-off-by: Thomas Graf <[email protected]>
---
 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 <[email protected]>
  * Copyright (C) January, 1998 Sergei Viznyuk <[email protected]>
@@ -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

_______________________________________________
networkmanager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to