diff options
-rw-r--r-- | include/NetworkManager.h | 2 | ||||
-rw-r--r-- | introspection/Makefile.am | 1 | ||||
-rw-r--r-- | introspection/all.xml.in | 1 | ||||
-rw-r--r-- | introspection/nm-device-bond.xml | 27 | ||||
-rw-r--r-- | introspection/nm-device.xml | 5 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/nm-device-bond.c | 407 | ||||
-rw-r--r-- | src/nm-device-bond.h | 65 | ||||
-rw-r--r-- | src/nm-device-ethernet.c | 40 | ||||
-rw-r--r-- | src/nm-device-wired.c | 4 | ||||
-rw-r--r-- | src/nm-manager.c | 28 |
12 files changed, 543 insertions, 44 deletions
diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 3f97e28aa3..01dd48c9f8 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -103,6 +103,7 @@ typedef enum { * @NM_DEVICE_TYPE_MODEM: a modem supporting analog telephone, CDMA/EVDO, * GSM/UMTS, or LTE network access protocols * @NM_DEVICE_TYPE_INFINIBAND: an IP-over-Infiniband device + * @NM_DEVICE_TYPE_BOND: a bond master interface * * #NMDeviceType values indicate the type of hardware represented by * an #NMDevice. @@ -118,6 +119,7 @@ typedef enum { NM_DEVICE_TYPE_WIMAX = 7, NM_DEVICE_TYPE_MODEM = 8, NM_DEVICE_TYPE_INFINIBAND = 9, + NM_DEVICE_TYPE_BOND = 10, } NMDeviceType; /** diff --git a/introspection/Makefile.am b/introspection/Makefile.am index bf09a7338b..e6e0e23328 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -11,6 +11,7 @@ EXTRA_DIST = \ nm-device-modem.xml \ nm-device-wimax.xml \ nm-device-infiniband.xml \ + nm-device-bond.xml \ nm-device.xml \ nm-ip4-config.xml \ nm-ip6-config.xml \ diff --git a/introspection/all.xml.in b/introspection/all.xml.in index 64e5fe40db..688ae457a3 100644 --- a/introspection/all.xml.in +++ b/introspection/all.xml.in @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</ <xi:include href="nm-device-olpc-mesh.xml"/> <xi:include href="nm-device-wimax.xml"/> <xi:include href="nm-device-infiniband.xml"/> +<xi:include href="nm-device-bond.xml"/> <xi:include href="nm-wimax-nsp.xml"/> <xi:include href="nm-ip4-config.xml"/> <xi:include href="nm-ip6-config.xml"/> diff --git a/introspection/nm-device-bond.xml b/introspection/nm-device-bond.xml new file mode 100644 index 0000000000..9d200ef8f5 --- /dev/null +++ b/introspection/nm-device-bond.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> + <interface name="org.freedesktop.NetworkManager.Device.Bond"> + + <property name="HwAddress" type="s" access="read"> + <tp:docstring> + Hardware address of the device. + </tp:docstring> + </property> + + <property name="Carrier" type="b" access="read"> + <tp:docstring> + Indicates whether the physical carrier is found (e.g. whether a cable is plugged in or not). + </tp:docstring> + </property> + + <signal name="PropertiesChanged"> + <arg name="properties" type="a{sv}" tp:type="String_Variant_Map"> + <tp:docstring> + A dictionary mapping property names to variant boxed values + </tp:docstring> + </arg> + </signal> + + </interface> +</node> diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 08a2847551..a2b1349b62 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -246,6 +246,11 @@ The device is an IP-capable Infiniband interface. </tp:docstring> </tp:enumvalue> + <tp:enumvalue suffix="BOND" value="10"> + <tp:docstring> + The device is a bond master interface. + </tp:docstring> + </tp:enumvalue> </tp:enum> <tp:flags name="NM_DEVICE_CAP" value-prefix="NM_DEVICE_CAP" type="u"> diff --git a/po/POTFILES.in b/po/POTFILES.in index e1b497ba9c..1fdfd10906 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -21,6 +21,7 @@ src/dns-manager/nm-dns-manager.c src/logging/nm-logging.c src/modem-manager/nm-modem-cdma.c src/modem-manager/nm-modem-gsm.c +src/nm-device-bond.c src/nm-device-bt.c src/nm-device-ethernet.c src/nm-device-infiniband.c diff --git a/src/Makefile.am b/src/Makefile.am index ec7f5568ad..4112c73c10 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,6 +135,8 @@ NetworkManager_SOURCES = \ nm-device-modem.c \ nm-device-infiniband.c \ nm-device-infiniband.h \ + nm-device-bond.c \ + nm-device-bond.h \ nm-wifi-ap.c \ nm-wifi-ap.h \ nm-wifi-ap-utils.c \ @@ -222,6 +224,9 @@ nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml nm-device-olpc-mesh-glue.h: $(top_srcdir)/introspection/nm-device-olpc-mesh.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_olpc_mesh --mode=glib-server --output=$@ $< +nm-device-bond-glue.h: $(top_srcdir)/introspection/nm-device-bond.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_bond --mode=glib-server --output=$@ $< + nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $< @@ -246,6 +251,7 @@ BUILT_SOURCES = \ nm-device-interface-glue.h \ nm-device-ethernet-glue.h \ nm-device-infiniband-glue.h \ + nm-device-bond-glue.h \ nm-device-wifi-glue.h \ nm-device-olpc-mesh-glue.h \ nm-device-bt-glue.h \ diff --git a/src/nm-device-bond.c b/src/nm-device-bond.c new file mode 100644 index 0000000000..c344407115 --- /dev/null +++ b/src/nm-device-bond.c @@ -0,0 +1,407 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * 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 2011 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include <glib.h> +#include <glib/gi18n.h> + +#include <netinet/ether.h> + +#include "nm-device-bond.h" +#include "nm-logging.h" +#include "nm-properties-changed-signal.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-netlink-monitor.h" +#include "nm-enum-types.h" + +#include "nm-device-bond-glue.h" + + +G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE_WIRED) + +#define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) + +#define NM_BOND_ERROR (nm_bond_error_quark ()) + +typedef struct { + int dummy; +} NMDeviceBondPrivate; + +enum { + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + + LAST_PROP +}; + +/******************************************************************/ + +static GQuark +nm_bond_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-bond-error"); + return quark; +} + +/******************************************************************/ + +static void +device_state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + if (new_state == NM_DEVICE_STATE_UNAVAILABLE) { + /* 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); + } +} + +static void +real_update_hw_address (NMDevice *dev) +{ + guint8 *hw_addr, old_addr[NM_UTILS_HWADDR_LEN_MAX]; + int addrtype, addrlen; + + addrtype = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (dev)); + g_assert (addrtype >= 0); + addrlen = nm_utils_hwaddr_len (addrtype); + g_assert (addrlen > 0); + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + memcpy (old_addr, hw_addr, addrlen); + + NM_DEVICE_CLASS (nm_device_bond_parent_class)->update_hw_address (dev); + + hw_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (dev)); + if (memcmp (old_addr, hw_addr, addrlen)) + g_object_notify (G_OBJECT (dev), NM_DEVICE_BOND_HW_ADDRESS); +} + +static guint32 +real_get_generic_capabilities (NMDevice *dev) +{ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NM_SUPPORTED; +} + +static gboolean +match_bond_connection (NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface; + NMSettingBond *s_bond; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { + g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND, + "The connection was not a bond connection."); + return FALSE; + } + + /* Bond connections must specify the virtual interface name */ + iface = nm_connection_get_virtual_iface_name (connection); + if (!iface || strcmp (nm_device_get_iface (device), iface)) { + g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND, + "The bond connection virtual interface name did not match."); + return FALSE; + } + + /* FIXME: match bond properties like mode, etc? */ + + return TRUE; +} + +static NMConnection * +real_get_best_auto_connection (NMDevice *dev, + GSList *connections, + char **specific_object) +{ + GSList *iter; + + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMConnection *connection = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + if ( nm_setting_connection_get_autoconnect (s_con) + && match_bond_connection (dev, connection, NULL)) + return connection; + } + return NULL; +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + return match_bond_connection (device, connection, error); +} + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMSettingBond *s_bond, *tmp; + guint32 i = 0; + char *name; + const GSList *iter; + gboolean found; + + nm_utils_complete_generic (connection, + NM_SETTING_BOND_SETTING_NAME, + existing_connections, + _("Bond connection %d"), + NULL, + TRUE); + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond) { + s_bond = (NMSettingBond *) nm_setting_bond_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bond)); + } + + /* Grab the first name that doesn't exist in either our connections + * or a device on the system. + */ + while (i < 500 && !nm_setting_bond_get_interface_name (s_bond)) { + name = g_strdup_printf ("bond%u", i); + /* check interface names */ + if (nm_netlink_iface_to_index (name) < 0) { + /* check existing bond connections */ + for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = iter->data; + + tmp = nm_connection_get_setting_bond (candidate); + if (tmp && nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) { + if (g_strcmp0 (nm_setting_bond_get_interface_name (tmp), name) == 0) { + found = TRUE; + break; + } + } + } + + if (!found) + g_object_set (G_OBJECT (s_bond), NM_SETTING_BOND_INTERFACE_NAME, name, NULL); + } + + g_free (name); + i++; + } + + return TRUE; +} + +static gboolean +spec_match_list (NMDevice *device, const GSList *specs) +{ + char *hwaddr; + gboolean matched; + + hwaddr = nm_utils_hwaddr_ntoa (nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device)), ARPHRD_ETHER); + matched = nm_match_spec_hwaddr (specs, hwaddr); + g_free (hwaddr); + + return matched; +} + +static gboolean +bond_match_config (NMDevice *self, NMConnection *connection) +{ + NMSettingBond *s_bond; + const char *ifname; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond) + return FALSE; + + /* Interface name */ + ifname = nm_setting_bond_get_interface_name (s_bond); + if (g_strcmp0 (ifname, nm_device_get_ip_iface (self)) != 0) + return FALSE; + + /* MAC address check */ + if (!nm_device_hwaddr_matches (self, connection, FALSE)) + return FALSE; + + return TRUE; +} + +static NMConnection * +connection_match_config (NMDevice *self, const GSList *connections) +{ + const GSList *iter; + GSList *bond_matches; + NMConnection *match; + + /* First narrow @connections down to those that match in their + * NMSettingBond configuration. + */ + bond_matches = NULL; + for (iter = connections; iter; iter = iter->next) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if (!nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) + continue; + if (!bond_match_config (self, candidate)) + continue; + + bond_matches = g_slist_prepend (bond_matches, candidate); + } + + /* Now pass those to the super method, which will check IP config */ + bond_matches = g_slist_reverse (bond_matches); + match = NM_DEVICE_CLASS (nm_device_bond_parent_class)->connection_match_config (self, bond_matches); + g_slist_free (bond_matches); + + return match; +} + +/******************************************************************/ + +NMDevice * +nm_device_bond_new (const char *udi, const char *iface) +{ + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, + NM_DEVICE_UDI, udi, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bonding", + NM_DEVICE_TYPE_DESC, "Bond", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NULL); +} + +static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_device_bond_parent_class)->constructed (object); + + nm_log_dbg (LOGD_HW | LOGD_DEVICE, "(%s): kernel ifindex %d", + nm_device_get_iface (NM_DEVICE (object)), + nm_device_get_ifindex (NM_DEVICE (object))); +} + +static void +nm_device_bond_init (NMDeviceBond * self) +{ + g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), NULL); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + guint8 *current_addr; + + switch (prop_id) { + case PROP_HW_ADDRESS: + current_addr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (object)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (current_addr, ARPHRD_ETHER)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_bond_class_init (NMDeviceBondClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceBondPrivate)); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->set_property = set_property; + + parent_class->get_generic_capabilities = real_get_generic_capabilities; + parent_class->update_hw_address = real_update_hw_address; + parent_class->get_best_auto_connection = real_get_best_auto_connection; + parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; + + parent_class->spec_match_list = spec_match_list; + parent_class->connection_match_config = connection_match_config; + + /* properties */ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, + "Active MAC Address", + "Currently set hardware MAC address", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_BOND_CARRIER, + "Carrier", + "Carrier", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMDeviceBondClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_bond_object_info); + + dbus_g_error_domain_register (NM_BOND_ERROR, NULL, NM_TYPE_BOND_ERROR); +} diff --git a/src/nm-device-bond.h b/src/nm-device-bond.h new file mode 100644 index 0000000000..c05580eed8 --- /dev/null +++ b/src/nm-device-bond.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * 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 NM_DEVICE_BOND_H +#define NM_DEVICE_BOND_H + +#include <glib-object.h> + +#include "nm-device-wired.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type ()) +#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) +#define NM_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BOND)) +#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) +#define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) + +typedef enum { + NM_BOND_ERROR_CONNECTION_NOT_BOND = 0, + NM_BOND_ERROR_CONNECTION_INVALID, + NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, +} NMBondError; + +#define NM_DEVICE_BOND_HW_ADDRESS "hw-address" +#define NM_DEVICE_BOND_CARRIER "carrier" + +typedef struct { + NMDeviceWired parent; +} NMDeviceBond; + +typedef struct { + NMDeviceWiredClass parent; + + /* Signals */ + void (*properties_changed) (NMDeviceBond *device, GHashTable *properties); +} NMDeviceBondClass; + + +GType nm_device_bond_get_type (void); + +NMDevice *nm_device_bond_new (const char *udi, + const char *iface); + +G_END_DECLS + +#endif /* NM_DEVICE_BOND_H */ diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 550bde0dd5..a7eb3e720b 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -68,13 +68,6 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE_WIRED) #define NM_ETHERNET_ERROR (nm_ethernet_error_quark ()) -typedef enum -{ - NM_ETHERNET_TYPE_UNSPEC = 0, - NM_ETHERNET_TYPE_BOND, - NM_ETHERNET_TYPE_VLAN, -} NMEthernetType; - typedef struct Supplicant { NMSupplicantManager *mgr; NMSupplicantInterface *iface; @@ -105,8 +98,6 @@ typedef struct { NMPPPManager *ppp_manager; NMIP4Config *pending_ip4_config; - NMEthernetType type; - /* VLAN stuff */ int vlan_id; int vlan_master_ifindex; @@ -268,13 +259,11 @@ constructor (GType type, // FIXME: Convert this into a no-export property so type can be specified // when the device is created. itype = nm_system_get_iface_type (nm_device_get_ifindex (self), nm_device_get_iface (self)); - if (itype == NM_IFACE_TYPE_BOND) - priv->type = NM_ETHERNET_TYPE_BOND; - else if (itype == NM_IFACE_TYPE_VLAN) { + if (itype == NM_IFACE_TYPE_UNSPEC) { + /* normal ethernet, pass */ + } else if (itype == NM_IFACE_TYPE_VLAN) { char *master_iface; - priv->type = NM_ETHERNET_TYPE_VLAN; - if (!nm_system_get_iface_vlan_info (nm_device_get_ifindex (self), &priv->vlan_master_ifindex, &priv->vlan_id)) { @@ -300,8 +289,9 @@ constructor (GType type, master_iface ? master_iface : "(unknown)", priv->vlan_master_ifindex); g_free (master_iface); - } else - priv->type = NM_ETHERNET_TYPE_UNSPEC; + } else { + g_assert_not_reached (); + } nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", nm_device_get_iface (NM_DEVICE (self)), @@ -334,26 +324,12 @@ device_state_changed (NMDevice *device, NMDeviceStateReason reason, gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - switch (new_state) { case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_FAILED: case NM_DEVICE_STATE_DISCONNECTED: clear_secrets_tries (device); break; - - case NM_DEVICE_STATE_UNAVAILABLE: - switch (priv->type) { - case NM_ETHERNET_TYPE_BOND: - /* 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; - - default: - break; - } default: break; } @@ -631,8 +607,6 @@ match_ethernet_connection (NMDevice *device, NMConnection *connection, if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { /* NOP */ - } else if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { - /* NOP */ } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); @@ -642,7 +616,7 @@ match_ethernet_connection (NMDevice *device, NMConnection *connection, g_assert (s_vlan); g_assert (s_con); - if (priv->type != NM_ETHERNET_TYPE_VLAN) { + if (priv->vlan_id < 0) { g_set_error (error, NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INVALID, "The device was not a VLAN interface."); return FALSE; diff --git a/src/nm-device-wired.c b/src/nm-device-wired.c index 30db74a93a..890612aee2 100644 --- a/src/nm-device-wired.c +++ b/src/nm-device-wired.c @@ -271,6 +271,10 @@ constructor (GType type, } else if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_INFINIBAND) { priv->hw_addr_type = ARPHRD_INFINIBAND; priv->hw_addr_len = INFINIBAND_ALEN; + } else if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_BOND) { + /* We may not know the hardware address type until a slave is added */ + priv->hw_addr_type = ARPHRD_ETHER; + priv->hw_addr_len = ETH_ALEN; } else g_assert_not_reached (); diff --git a/src/nm-manager.c b/src/nm-manager.c index adbd094dc4..6760d978e0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -44,6 +44,7 @@ #include "nm-device-olpc-mesh.h" #include "nm-device-modem.h" #include "nm-device-infiniband.h" +#include "nm-device-bond.h" #include "nm-system.h" #include "nm-properties-changed-signal.h" #include "nm-setting-bluetooth.h" @@ -1054,7 +1055,6 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) char *iface = NULL, *udi; NMDevice *device = NULL; int master_ifindex = -1; - const char *driver = NULL; iface = get_virtual_iface_name (self, connection, &master_ifindex); if (!iface) { @@ -1082,7 +1082,10 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) iface, nm_connection_get_id (connection)); goto out; } - driver = "bonding"; + + udi = get_virtual_iface_placeholder_udi (); + device = nm_device_bond_new (udi, iface); + g_free (udi); } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { g_return_val_if_fail (master_ifindex >= 0, FALSE); @@ -1091,19 +1094,14 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) iface, nm_connection_get_id (connection)); goto out; } - driver = "8021q"; - } - - if (driver) { udi = get_virtual_iface_placeholder_udi (); - device = nm_device_ethernet_new (udi, iface, driver); + device = nm_device_ethernet_new (udi, iface, "8021q"); g_free (udi); - if (device) - add_device (self, device); - else - nm_log_warn (LOGD_DEVICE, "(%s) failed to add virtual interface device", iface); } + if (device) + add_device (self, device); + out: g_free (iface); return device; @@ -2128,6 +2126,12 @@ is_infiniband (GUdevDevice *device) return etype == ARPHRD_INFINIBAND; } +static gboolean +is_bond (int ifindex) +{ + return (nm_system_get_iface_type (ifindex, NULL) == NM_IFACE_TYPE_BOND); +} + static void udev_device_added_cb (NMUdevManager *udev_mgr, GUdevDevice *udev_device, @@ -2180,6 +2184,8 @@ udev_device_added_cb (NMUdevManager *udev_mgr, device = nm_device_wifi_new (sysfs_path, iface, driver); else if (is_infiniband (udev_device)) device = nm_device_infiniband_new (sysfs_path, iface, driver); + else if (is_bond (ifindex)) + device = nm_device_bond_new (sysfs_path, iface); else device = nm_device_ethernet_new (sysfs_path, iface, driver); } |