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
