1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2007 - 2008 Novell, Inc.
19 * Copyright 2007 - 2012 Red Hat, Inc.
22 #include "nm-default.h"
26 #include "nm-setting-connection.h"
27 #include "nm-setting-wired.h"
28 #include "nm-setting-pppoe.h"
31 #include "nm-device-ethernet.h"
32 #include "nm-device-private.h"
33 #include "nm-object-private.h"
35 G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
37 #define NM_DEVICE_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate))
41 char *perm_hw_address;
44 char **s390_subchannels;
45 } NMDeviceEthernetPrivate;
53 PROP_S390_SUBCHANNELS,
59 * nm_device_ethernet_get_hw_address:
60 * @device: a #NMDeviceEthernet
62 * Gets the active hardware (MAC) address of the #NMDeviceEthernet
64 * Returns: the active hardware address. This is the internal string used by the
65 * device, and must not be modified.
68 nm_device_ethernet_get_hw_address (NMDeviceEthernet *device)
70 g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
72 return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->hw_address;
76 * nm_device_ethernet_get_permanent_hw_address:
77 * @device: a #NMDeviceEthernet
79 * Gets the permanent hardware (MAC) address of the #NMDeviceEthernet
81 * Returns: the permanent hardware address. This is the internal string used by the
82 * device, and must not be modified.
85 nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device)
87 g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
89 return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->perm_hw_address;
93 * nm_device_ethernet_get_speed:
94 * @device: a #NMDeviceEthernet
96 * Gets the speed of the #NMDeviceEthernet.
98 * Returns: the speed of the device
101 nm_device_ethernet_get_speed (NMDeviceEthernet *device)
103 g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), 0);
105 return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->speed;
109 * nm_device_ethernet_get_carrier:
110 * @device: a #NMDeviceEthernet
112 * Whether the device has carrier.
114 * Returns: %TRUE if the device has carrier
117 nm_device_ethernet_get_carrier (NMDeviceEthernet *device)
119 g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), FALSE);
121 return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->carrier;
125 * nm_device_ethernet_get_s390_subchannels:
126 * @device: a #NMDeviceEthernet
128 * Return the list of s390 subchannels if the device supports them.
130 * Returns: (transfer none) (element-type utf8): array of strings, each specifying
131 * one subchannel the s390 device uses to communicate to the host.
136 nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device)
138 g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
140 return (const char * const *) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->s390_subchannels;
144 _subchannels_count_num (const char * const *array)
150 for (i = 0; array[i]; i++)
156 match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac)
158 NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
159 const char * const *subchans;
165 subchans = nm_setting_wired_get_s390_subchannels (s_wired);
166 num1 = _subchannels_count_num (subchans);
167 num2 = _subchannels_count_num ((const char * const *) priv->s390_subchannels);
168 /* connection has no subchannels */
171 /* connection requires subchannels but the device has none */
174 /* number of subchannels differ */
178 /* Make sure each subchannel in the connection is a subchannel of this device */
179 for (i = 0; subchans[i]; i++) {
180 const char *candidate = subchans[i];
181 gboolean found = FALSE;
183 for (j = 0; priv->s390_subchannels[j]; j++) {
184 if (!g_strcmp0 (priv->s390_subchannels[j], candidate))
188 return FALSE; /* a subchannel was not found */
196 connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
198 NMSettingWired *s_wired;
200 if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_compatible (device, connection, error))
203 if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) {
205 } else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) {
206 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
207 _("The connection was not an Ethernet or PPPoE connection."));
211 s_wired = nm_connection_get_setting_wired (connection);
212 /* Wired setting optional for PPPoE */
214 const char *perm_addr, *s_mac;
215 gboolean try_mac = TRUE;
216 const char * const *mac_blacklist;
219 /* Check s390 subchannels */
220 if (!match_subchans (NM_DEVICE_ETHERNET (device), s_wired, &try_mac)) {
221 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
222 _("The connection and device differ in S390 subchannels."));
226 /* Check MAC address */
227 perm_addr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
228 s_mac = nm_setting_wired_get_mac_address (s_wired);
230 if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) {
231 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
232 _("Invalid device MAC address."));
235 if (try_mac && s_mac && !nm_utils_hwaddr_matches (s_mac, -1, perm_addr, -1)) {
236 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
237 _("The MACs of the device and the connection do not match."));
241 /* Check for MAC address blacklist */
242 mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
243 for (i = 0; mac_blacklist[i]; i++) {
244 if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
245 g_warn_if_reached ();
246 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
247 _("Invalid MAC in the blacklist: %s."), mac_blacklist[i]);
251 if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_addr, -1)) {
252 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
253 _("Device MAC (%s) is blacklisted by the connection."), perm_addr);
264 get_setting_type (NMDevice *device)
266 return NM_TYPE_SETTING_WIRED;
270 get_hw_address (NMDevice *device)
272 return nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device));
275 /***********************************************************/
278 nm_device_ethernet_init (NMDeviceEthernet *device)
280 _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_ETHERNET);
284 init_dbus (NMObject *object)
286 NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
287 const NMPropertiesInfo property_info[] = {
288 { NM_DEVICE_ETHERNET_HW_ADDRESS, &priv->hw_address },
289 { NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, &priv->perm_hw_address },
290 { NM_DEVICE_ETHERNET_SPEED, &priv->speed },
291 { NM_DEVICE_ETHERNET_CARRIER, &priv->carrier },
292 { NM_DEVICE_ETHERNET_S390_SUBCHANNELS, &priv->s390_subchannels },
296 NM_OBJECT_CLASS (nm_device_ethernet_parent_class)->init_dbus (object);
298 _nm_object_register_properties (object,
299 NM_DBUS_INTERFACE_DEVICE_WIRED,
304 finalize (GObject *object)
306 NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
308 g_free (priv->hw_address);
309 g_free (priv->perm_hw_address);
310 g_strfreev (priv->s390_subchannels);
312 G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object);
316 get_property (GObject *object,
321 NMDeviceEthernet *device = NM_DEVICE_ETHERNET (object);
322 NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
325 case PROP_HW_ADDRESS:
326 g_value_set_string (value, nm_device_ethernet_get_hw_address (device));
328 case PROP_PERM_HW_ADDRESS:
329 g_value_set_string (value, nm_device_ethernet_get_permanent_hw_address (device));
332 g_value_set_uint (value, nm_device_ethernet_get_speed (device));
335 g_value_set_boolean (value, nm_device_ethernet_get_carrier (device));
337 case PROP_S390_SUBCHANNELS:
338 g_value_set_boxed (value, priv->s390_subchannels);
341 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
347 nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
349 GObjectClass *object_class = G_OBJECT_CLASS (eth_class);
350 NMObjectClass *nm_object_class = NM_OBJECT_CLASS (eth_class);
351 NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class);
353 g_type_class_add_private (eth_class, sizeof (NMDeviceEthernetPrivate));
355 _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIRED);
357 /* virtual methods */
358 object_class->finalize = finalize;
359 object_class->get_property = get_property;
361 nm_object_class->init_dbus = init_dbus;
363 device_class->connection_compatible = connection_compatible;
364 device_class->get_setting_type = get_setting_type;
365 device_class->get_hw_address = get_hw_address;
370 * NMDeviceEthernet:hw-address:
372 * The active hardware (MAC) address of the device.
374 g_object_class_install_property
375 (object_class, PROP_HW_ADDRESS,
376 g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS, "", "",
379 G_PARAM_STATIC_STRINGS));
382 * NMDeviceEthernet:perm-hw-address:
384 * The permanent hardware (MAC) address of the device.
386 g_object_class_install_property
387 (object_class, PROP_PERM_HW_ADDRESS,
388 g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "",
391 G_PARAM_STATIC_STRINGS));
394 * NMDeviceEthernet:speed:
396 * The speed of the device.
398 g_object_class_install_property
399 (object_class, PROP_SPEED,
400 g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "",
403 G_PARAM_STATIC_STRINGS));
406 * NMDeviceEthernet:carrier:
408 * Whether the device has carrier.
410 g_object_class_install_property
411 (object_class, PROP_CARRIER,
412 g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER, "", "",
415 G_PARAM_STATIC_STRINGS));
418 * NMDeviceEthernet:s390-subchannels:
420 * Identifies subchannels of this network device used for
421 * communication with z/VM or s390 host.
425 g_object_class_install_property
426 (object_class, PROP_S390_SUBCHANNELS,
427 g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "",
430 G_PARAM_STATIC_STRINGS));