2020-12-23 22:21:36 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2014-04-07 15:25:09 +02:00
|
|
|
* Copyright (C) 2005 - 2014 Red Hat, Inc.
|
2008-11-03 04:13:42 +00:00
|
|
|
* Copyright (C) 2006 - 2008 Novell, Inc.
|
2005-12-31 08:21:24 +00:00
|
|
|
*/
|
|
|
|
|
|
2021-02-04 18:04:13 +01:00
|
|
|
#include "src/core/nm-default-daemon.h"
|
2014-11-13 10:07:02 -05:00
|
|
|
|
2016-05-16 19:01:37 +02:00
|
|
|
#include "nm-device-ethernet.h"
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <stdlib.h>
|
2008-03-14 20:37:48 +00:00
|
|
|
#include <unistd.h>
|
2017-03-12 15:54:02 +01:00
|
|
|
#include <libudev.h>
|
2020-12-13 16:08:56 +01:00
|
|
|
#include <linux/if_ether.h>
|
2010-06-25 19:49:39 -07:00
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
#include "NetworkManagerUtils.h"
|
2021-08-06 15:17:05 +02:00
|
|
|
#include "NetworkManagerUtils.h"
|
|
|
|
|
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
|
|
|
|
#include "libnm-core-intern/nm-core-internal.h"
|
|
|
|
|
#include "libnm-glib-aux/nm-uuid.h"
|
2021-02-18 08:13:35 +01:00
|
|
|
#include "libnm-platform/nm-platform-utils.h"
|
2021-08-06 15:17:05 +02:00
|
|
|
#include "libnm-platform/nm-platform.h"
|
|
|
|
|
#include "libnm-udev-aux/nm-udev-utils.h"
|
|
|
|
|
#include "nm-act-request.h"
|
2014-09-08 16:11:51 -05:00
|
|
|
#include "nm-config.h"
|
2021-08-06 15:17:05 +02:00
|
|
|
#include "nm-dcb.h"
|
2014-09-08 16:11:51 -05:00
|
|
|
#include "nm-device-ethernet-utils.h"
|
2014-09-10 10:59:40 -05:00
|
|
|
#include "nm-device-factory.h"
|
2021-08-06 15:17:05 +02:00
|
|
|
#include "nm-device-private.h"
|
2020-11-12 21:58:13 +01:00
|
|
|
#include "nm-device-veth.h"
|
2021-08-06 15:17:05 +02:00
|
|
|
#include "nm-manager.h"
|
|
|
|
|
#include "ppp/nm-ppp-mgr.h"
|
|
|
|
|
#include "settings/nm-settings-connection.h"
|
|
|
|
|
#include "settings/nm-settings.h"
|
|
|
|
|
#include "supplicant/nm-supplicant-config.h"
|
|
|
|
|
#include "supplicant/nm-supplicant-interface.h"
|
|
|
|
|
#include "supplicant/nm-supplicant-manager.h"
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2020-11-06 18:22:11 +01:00
|
|
|
#define _NMLOG_DEVICE_TYPE NMDeviceEthernet
|
2014-08-02 15:14:26 +02:00
|
|
|
#include "nm-device-logging.h"
|
2007-02-12 09:23:43 +00:00
|
|
|
|
2016-07-05 13:21:49 +02:00
|
|
|
/*****************************************************************************/
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
#define PPPOE_RECONNECT_DELAY_MSEC 7000
|
|
|
|
|
#define PPPOE_ENCAP_OVERHEAD 8 /* 2 bytes for PPP, 6 for PPPoE */
|
2013-12-09 09:33:13 +01:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
#define SUPPLICANT_LNK_TIMEOUT_SEC 15
|
|
|
|
|
|
2016-07-05 13:21:49 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
typedef enum {
|
|
|
|
|
DCB_WAIT_UNKNOWN = 0,
|
|
|
|
|
/* Ensure carrier is up before enabling DCB */
|
|
|
|
|
DCB_WAIT_CARRIER_PREENABLE_UP,
|
|
|
|
|
/* Wait for carrier down when device starts enabling */
|
|
|
|
|
DCB_WAIT_CARRIER_PRECONFIG_DOWN,
|
|
|
|
|
/* Wait for carrier up when device has finished enabling */
|
|
|
|
|
DCB_WAIT_CARRIER_PRECONFIG_UP,
|
|
|
|
|
/* Wait carrier down when device starts configuring */
|
|
|
|
|
DCB_WAIT_CARRIER_POSTCONFIG_DOWN,
|
|
|
|
|
/* Wait carrier up when device has finished configuring */
|
|
|
|
|
DCB_WAIT_CARRIER_POSTCONFIG_UP,
|
|
|
|
|
} DcbWait;
|
|
|
|
|
|
2016-07-05 13:21:49 +02:00
|
|
|
typedef struct _NMDeviceEthernetPrivate {
|
2020-02-12 14:34:07 +01:00
|
|
|
/* s390 */
|
|
|
|
|
char * subchan1;
|
|
|
|
|
char * subchan2;
|
|
|
|
|
char * subchan3;
|
|
|
|
|
char * subchannels; /* Composite used for checking unmanaged specs */
|
|
|
|
|
char ** subchannels_dbus; /* Array exported on D-Bus */
|
|
|
|
|
char * s390_nettype;
|
|
|
|
|
GHashTable *s390_options;
|
|
|
|
|
|
2013-05-07 16:18:19 -04:00
|
|
|
guint32 speed;
|
2019-11-08 08:36:41 +01:00
|
|
|
gulong carrier_id;
|
2013-05-07 16:18:19 -04:00
|
|
|
|
2020-02-12 10:36:57 +01:00
|
|
|
struct {
|
|
|
|
|
NMSupplicantManager * mgr;
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
NMSupplMgrCreateIfaceHandle *create_handle;
|
2020-02-12 10:36:57 +01:00
|
|
|
NMSupplicantInterface * iface;
|
|
|
|
|
|
|
|
|
|
gulong iface_state_id;
|
|
|
|
|
gulong auth_state_id;
|
|
|
|
|
|
|
|
|
|
guint con_timeout_id;
|
|
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
guint lnk_timeout_id;
|
|
|
|
|
|
|
|
|
|
bool is_associated : 1;
|
2021-08-06 15:17:05 +02:00
|
|
|
bool ready : 1;
|
2020-02-12 14:39:10 +01:00
|
|
|
} supplicant;
|
2008-03-11 16:37:41 +00:00
|
|
|
|
2017-11-24 16:24:40 +01:00
|
|
|
NMActRequestGetSecretsCallId *wired_secrets_id;
|
2016-12-16 14:12:21 +01:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
struct {
|
|
|
|
|
NMPppMgr *ppp_mgr;
|
|
|
|
|
GSource * wait_source;
|
|
|
|
|
gint64 last_pppoe_time_msec;
|
|
|
|
|
} ppp_data;
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
|
|
|
|
/* DCB */
|
|
|
|
|
DcbWait dcb_wait;
|
|
|
|
|
guint dcb_timeout_id;
|
2017-06-02 16:24:31 +02:00
|
|
|
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
guint32 ethtool_prev_speed;
|
|
|
|
|
|
|
|
|
|
NMPlatformLinkDuplexType ethtool_prev_duplex : 3;
|
|
|
|
|
|
2017-06-02 16:24:31 +02:00
|
|
|
bool dcb_handle_carrier_changes : 1;
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
|
|
|
|
|
bool ethtool_prev_set : 1;
|
|
|
|
|
bool ethtool_prev_autoneg : 1;
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
bool stage2_ready_dcb : 1;
|
|
|
|
|
|
2008-06-10 15:54:23 +00:00
|
|
|
} NMDeviceEthernetPrivate;
|
2005-12-31 08:21:24 +00:00
|
|
|
|
2016-07-05 13:43:06 +02:00
|
|
|
NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceEthernet, PROP_SPEED, PROP_S390_SUBCHANNELS, );
|
2007-02-12 09:23:43 +00:00
|
|
|
|
2016-07-05 13:21:49 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE(NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
|
|
|
|
|
|
2020-02-14 10:50:25 +01:00
|
|
|
#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \
|
|
|
|
|
_NM_GET_PRIVATE_PTR(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMDevice)
|
2016-07-05 13:21:49 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2008-03-12 Dan Williams <dcbw@redhat.com>
Move the 'carrier' property from NMDevice to NMDevice8023Ethernet;
convert the libnm-glib NMDevice8023Ethernet to cached properties
* introspection/nm-device-802-3-ethernet.xml
- New 'Carrier' property
- New 'PropertiesChanged' signal
* introspection/nm-device.xml
- Remove 'Carrier' property
- Remove 'CarrierChanged' signal
* src/nm-device-interface.c
src/nm-device-interface.h
- (nm_device_interface_init): remove 'carrier' property and
'carrier-changed' signal
* src/nm-device.c
src/nm-device.h
- (nm_device_get_carrier, nm_device_set_carrier): remove
- (nm_device_activate_stage5_ip_config_commit): don't bother updating
the link here; wired device will handle that
- (handle_dhcp_lease_change): don't bother updating link here
- (get_property, nm_device_class_init): remove carrier property
* src/nm-device-802-11-wireless.c
- (real_update_link, nm_device_802_11_wireless_class_init): remove
real_update_link(); wireless devices don't use carrier at all
- (link_timeout_cb, supplicant_iface_state_cb_handler,
supplicant_iface_connection_state_cb_handler,
supplicant_mgr_state_cb_handler): remove anything to do with carrier
* src/nm-device-802-3-ethernet.c
src/nm-device-802-3-ethernet.h
- (nm_device_802_3_ethernet_carrier_on,
nm_device_802_3_ethernet_carrier_off, constructor): use set_carrier()
instead of nm_device_set_carrier()
- (device_state_changed): update link from sysfs on activation;
replaces real_update_link()
- (real_update_link): remove, replaced by device_state_changed()
- (nm_device_802_3_ethernet_get_carrier, set_carrier): new functions
- (nm_device_802_3_ethernet_get_speed): move up with other getters/setters
- (real_get_generic_capabilities, real_can_interrupt_activation): use
new get_carrier function
- (get_property): add 'carrier' property
- (nm_device_802_3_ethernet_class_init): add 'carrier' property and
hook into property-changed signal helper
* src/NetworkManagerPolicy.c
- (device_carrier_changed): will only ever be called with a wired device
- (device_added): only hook up to carrier-changed for wired devices
* libnm-glib/nm-device.c
libnm-glib/nm-device.h
- (constructor, nm_device_class_init): remove carrier-changed signal
- (device_carrier_changed_proxy): remove; unused
- (nm_device_get_carrier): remove; carrier a property of wired devices
* libnm-glib/nm-device-802-3-ethernet.c
libnm-glib/nm-device-802-3-ethernet.h
- Convert to cached properties like AP and Wireless objects
- (nm_device_802_3_ethernet_get_hw_address): now returns a 'const char *'
instead of a 'char *', return value should not be freed
- (nm_device_802_3_ethernet_get_carrier): return current carrier status
- (constructor): hook into properties-changed helper
- (set_property, get_property): new functions
- (nm_device_802_3_ethernet_class_init): export GObject properties
* test/nm-tool.c
- (detail_device): strdup the wired hardware address too since it's
cached now
* libnm-glib/libnm-glib-test.c
- (dump_wired): strdup the wired hardware address too since it's
cached now
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3428 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-12 16:12:39 +00:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
static void wired_secrets_cancel(NMDeviceEthernet *self);
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2014-04-07 15:25:09 +02:00
|
|
|
static char *
|
|
|
|
|
get_link_basename(const char *parent_path, const char *name, GError **error)
|
|
|
|
|
{
|
2014-04-11 12:46:53 +02:00
|
|
|
char *link_dest, *path;
|
2014-04-07 15:25:09 +02:00
|
|
|
char *result = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:25:09 +02:00
|
|
|
path = g_strdup_printf("%s/%s", parent_path, name);
|
2014-04-11 12:46:53 +02:00
|
|
|
link_dest = g_file_read_link(path, error);
|
|
|
|
|
if (link_dest) {
|
|
|
|
|
result = g_path_get_basename(link_dest);
|
|
|
|
|
g_free(link_dest);
|
|
|
|
|
}
|
2014-04-07 15:25:09 +02:00
|
|
|
g_free(path);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-25 19:49:39 -07:00
|
|
|
static void
|
|
|
|
|
_update_s390_subchannels(NMDeviceEthernet *self)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2017-03-12 15:54:02 +01:00
|
|
|
struct udev_device * dev = NULL;
|
|
|
|
|
struct udev_device * parent = NULL;
|
2016-07-05 14:14:49 +02:00
|
|
|
const char * parent_path, *item;
|
2015-06-15 15:19:28 +02:00
|
|
|
int ifindex;
|
2010-06-25 19:49:39 -07:00
|
|
|
GDir * dir;
|
|
|
|
|
GError * error = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 14:14:49 +02:00
|
|
|
if (priv->subchannels) {
|
|
|
|
|
/* only read the subchannels once. For one, we don't expect them to change
|
|
|
|
|
* on multiple invocations. Second, we didn't implement proper reloading.
|
|
|
|
|
* Proper reloading might also be complicated, because the subchannels are
|
|
|
|
|
* used to match on devices based on a device-spec. Thus, it's not clear
|
|
|
|
|
* what it means to change afterwards. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 12:47:34 +02:00
|
|
|
ifindex = nm_device_get_ifindex((NMDevice *) self);
|
2017-04-18 12:09:02 +02:00
|
|
|
dev = nm_platform_link_get_udev_device(nm_device_get_platform(NM_DEVICE(self)), ifindex);
|
2016-10-10 17:45:27 +00:00
|
|
|
if (!dev)
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-06-25 19:49:39 -07:00
|
|
|
/* Try for the "ccwgroup" parent */
|
2017-03-12 15:54:02 +01:00
|
|
|
parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccwgroup", NULL);
|
2010-06-25 19:49:39 -07:00
|
|
|
if (!parent) {
|
|
|
|
|
/* FIXME: whatever 'lcs' devices' subsystem is here... */
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-03-12 15:54:02 +01:00
|
|
|
/* Not an s390 device */
|
|
|
|
|
return;
|
2010-06-25 19:49:39 -07:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-03-12 15:54:02 +01:00
|
|
|
parent_path = udev_device_get_syspath(parent);
|
2010-06-25 19:49:39 -07:00
|
|
|
dir = g_dir_open(parent_path, 0, &error);
|
|
|
|
|
if (!dir) {
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PLATFORM,
|
|
|
|
|
"update-s390: failed to open directory '%s': %s",
|
2016-02-28 16:25:36 +01:00
|
|
|
parent_path,
|
|
|
|
|
error->message);
|
2010-06-25 19:49:39 -07:00
|
|
|
g_clear_error(&error);
|
2016-07-05 12:47:34 +02:00
|
|
|
return;
|
2010-06-25 19:49:39 -07:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-06-25 19:49:39 -07:00
|
|
|
while ((item = g_dir_read_name(dir))) {
|
2014-04-07 15:25:09 +02:00
|
|
|
if (!strcmp(item, "cdev0")) {
|
|
|
|
|
priv->subchan1 = get_link_basename(parent_path, "cdev0", &error);
|
|
|
|
|
} else if (!strcmp(item, "cdev1")) {
|
|
|
|
|
priv->subchan2 = get_link_basename(parent_path, "cdev1", &error);
|
|
|
|
|
} else if (!strcmp(item, "cdev2")) {
|
|
|
|
|
priv->subchan3 = get_link_basename(parent_path, "cdev2", &error);
|
|
|
|
|
} else if (!strcmp(item, "driver")) {
|
|
|
|
|
priv->s390_nettype = get_link_basename(parent_path, "driver", &error);
|
|
|
|
|
} else if (!strcmp(item, "layer2") || !strcmp(item, "portname")
|
|
|
|
|
|| !strcmp(item, "portno")) {
|
2016-04-14 18:34:45 +02:00
|
|
|
gs_free char *path = NULL, *value = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:25:09 +02:00
|
|
|
path = g_strdup_printf("%s/%s", parent_path, item);
|
2017-04-18 12:09:02 +02:00
|
|
|
value = nm_platform_sysctl_get(nm_device_get_platform(NM_DEVICE(self)),
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(path));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-14 18:34:45 +02:00
|
|
|
if (!strcmp(item, "portname") && !g_strcmp0(value, "no portname required")) {
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
} else if (value && *value) {
|
|
|
|
|
g_hash_table_insert(priv->s390_options, g_strdup(item), value);
|
|
|
|
|
value = NULL;
|
|
|
|
|
} else
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PLATFORM, "update-s390: error reading %s", path);
|
2010-06-25 19:49:39 -07:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:25:09 +02:00
|
|
|
if (error) {
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PLATFORM,
|
|
|
|
|
"update-s390: failed reading sysfs for %s (%s)",
|
|
|
|
|
item,
|
|
|
|
|
error->message);
|
2014-04-07 15:25:09 +02:00
|
|
|
g_clear_error(&error);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
2010-06-25 19:49:39 -07:00
|
|
|
g_dir_close(dir);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-06-25 21:44:01 -07:00
|
|
|
if (priv->subchan3) {
|
|
|
|
|
priv->subchannels =
|
|
|
|
|
g_strdup_printf("%s,%s,%s", priv->subchan1, priv->subchan2, priv->subchan3);
|
|
|
|
|
} else if (priv->subchan2) {
|
|
|
|
|
priv->subchannels = g_strdup_printf("%s,%s", priv->subchan1, priv->subchan2);
|
|
|
|
|
} else
|
|
|
|
|
priv->subchannels = g_strdup(priv->subchan1);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-09-18 22:49:13 +02:00
|
|
|
priv->subchannels_dbus = g_new(char *, 3 + 1);
|
|
|
|
|
priv->subchannels_dbus[0] = g_strdup(priv->subchan1);
|
|
|
|
|
priv->subchannels_dbus[1] = g_strdup(priv->subchan2);
|
|
|
|
|
priv->subchannels_dbus[2] = g_strdup(priv->subchan3);
|
|
|
|
|
priv->subchannels_dbus[3] = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_PLATFORM,
|
|
|
|
|
"update-s390: found s390 '%s' subchannels [%s]",
|
2016-07-05 14:14:49 +02:00
|
|
|
nm_device_get_driver((NMDevice *) self) ?: "(unknown driver)",
|
|
|
|
|
priv->subchannels);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 14:14:49 +02:00
|
|
|
_notify(self, PROP_S390_SUBCHANNELS);
|
2010-06-25 19:49:39 -07:00
|
|
|
}
|
|
|
|
|
|
2011-01-18 18:35:35 -06:00
|
|
|
static void
|
|
|
|
|
device_state_changed(NMDevice * device,
|
|
|
|
|
NMDeviceState new_state,
|
|
|
|
|
NMDeviceState old_state,
|
2012-09-27 12:38:59 -04:00
|
|
|
NMDeviceStateReason reason)
|
2011-01-18 18:35:35 -06:00
|
|
|
{
|
2016-12-16 14:12:21 +01:00
|
|
|
if (new_state > NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
wired_secrets_cancel(NM_DEVICE_ETHERNET(device));
|
2011-01-18 18:35:35 -06:00
|
|
|
}
|
|
|
|
|
|
2006-03-05 Dan Williams <dcbw@redhat.com>
Process netlink messages in device subclasses rather than in
NetworkManager.c. Also add support for recognizing Wireless Events.
* configure.in
- Find GLIB_GENMARSHAL
* src/Makefile.am
- Since we're marshalling custom types for wireless event signals,
we get to create our own marshallers using GLIB_GENMARSHAL
* src/NetworkManager.c
- (nm_monitor_wired_link_state): renamed to nm_monitor_setup
- (nm_monitor_setup): renamed from nm_monitor_wired_link_state, and
cut down somewhat. We no longer process signals here.
- (nm_data_new): create the netlink monitor here, and remove a
useless call to nm_policy_schedule_device_change_check()
- (nm_data_free): get rid of the netlink monitor here
- (nm_device_link_activated, nm_device_link_deactivated): removed
- (main): don't create the netlink monitor here, let nm_data_new
do that. Call nm_policy_schedule_device_change_check() right
before we jump to the mainloop to figure out which device
to use first
* src/NetworkManagerSystem.[ch]
- (nm_system_get_rtnl_index_from_iface, nm_system_get_iface_from_rtnl_index):
convert back and forth from interface names to interface
indexes
* src/nm-device-802-11-wireless.c
- (real_init): connect to wireless-event signals from the netlink
monitor object
- (nm_device_802_11_wireless_event): new function, schedule handler
for wireless event signals from the netlink monitor object. We
want the handler to run in the device's context
- (wireless_event_helper): handle wireless-event signals from netlink
- (nm_device_802_11_wireless_dispose): disconnect wireless-event
signal handler
* src/nm-device-802-11-wireless.h
- remove unused prototype for nm_device_802_11_wireless_new
* src/nm-device-802-3-ethernet.c
- (real_init): new function; set up signal handlers for link events
- (nm_device_802_3_ethernet_link_activated): new function, schedule
handler for netlink link activated events on device's main loop
- (link_activated_helper): when we get a link activated event, set
the device's link to be active
- (nm_device_802_3_ethernet_link_deactivated): new function; schedule
handler for netlink link deactivated events on device's main loop
- (link_deactivated_helper): when we get a link deactivated event, set
the device's link to be inactive
- (nm_device_802_3_ethernet_dispose): disconnect signal handler on
dispose
* src/nm-device-802-3-ethernet.h
- remove unused prototype for nm_device_802_3_ethernet_new
* src/nm-device.[ch]
- (nm_get_device_by_iface_locked): variant of nm_get_device_by_iface
but locks the device list
- (nm_device_set_active_link): a little bit of cleanup and de-indenting
* src/nm-netlink-monitor.[ch]
- (nm_netlink_monitor_class_install_signals): New signal
"wireless-event"
- (nm_netlink_monitor_new): keep reference to NMData so we can get
at the device list
- (nm_netlink_monitor_event_handler): expand for wireless events too
* src/nm-marshal-main.c
- Include generated nm-marshal.c and nm-marshal.h
* src/nm-marshal.list
- List of custom marshal functions
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1555 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-06 01:10:58 +00:00
|
|
|
static void
|
2014-04-07 15:25:09 +02:00
|
|
|
nm_device_ethernet_init(NMDeviceEthernet *self)
|
2006-03-05 Dan Williams <dcbw@redhat.com>
Process netlink messages in device subclasses rather than in
NetworkManager.c. Also add support for recognizing Wireless Events.
* configure.in
- Find GLIB_GENMARSHAL
* src/Makefile.am
- Since we're marshalling custom types for wireless event signals,
we get to create our own marshallers using GLIB_GENMARSHAL
* src/NetworkManager.c
- (nm_monitor_wired_link_state): renamed to nm_monitor_setup
- (nm_monitor_setup): renamed from nm_monitor_wired_link_state, and
cut down somewhat. We no longer process signals here.
- (nm_data_new): create the netlink monitor here, and remove a
useless call to nm_policy_schedule_device_change_check()
- (nm_data_free): get rid of the netlink monitor here
- (nm_device_link_activated, nm_device_link_deactivated): removed
- (main): don't create the netlink monitor here, let nm_data_new
do that. Call nm_policy_schedule_device_change_check() right
before we jump to the mainloop to figure out which device
to use first
* src/NetworkManagerSystem.[ch]
- (nm_system_get_rtnl_index_from_iface, nm_system_get_iface_from_rtnl_index):
convert back and forth from interface names to interface
indexes
* src/nm-device-802-11-wireless.c
- (real_init): connect to wireless-event signals from the netlink
monitor object
- (nm_device_802_11_wireless_event): new function, schedule handler
for wireless event signals from the netlink monitor object. We
want the handler to run in the device's context
- (wireless_event_helper): handle wireless-event signals from netlink
- (nm_device_802_11_wireless_dispose): disconnect wireless-event
signal handler
* src/nm-device-802-11-wireless.h
- remove unused prototype for nm_device_802_11_wireless_new
* src/nm-device-802-3-ethernet.c
- (real_init): new function; set up signal handlers for link events
- (nm_device_802_3_ethernet_link_activated): new function, schedule
handler for netlink link activated events on device's main loop
- (link_activated_helper): when we get a link activated event, set
the device's link to be active
- (nm_device_802_3_ethernet_link_deactivated): new function; schedule
handler for netlink link deactivated events on device's main loop
- (link_deactivated_helper): when we get a link deactivated event, set
the device's link to be inactive
- (nm_device_802_3_ethernet_dispose): disconnect signal handler on
dispose
* src/nm-device-802-3-ethernet.h
- remove unused prototype for nm_device_802_3_ethernet_new
* src/nm-device.[ch]
- (nm_get_device_by_iface_locked): variant of nm_get_device_by_iface
but locks the device list
- (nm_device_set_active_link): a little bit of cleanup and de-indenting
* src/nm-netlink-monitor.[ch]
- (nm_netlink_monitor_class_install_signals): New signal
"wireless-event"
- (nm_netlink_monitor_new): keep reference to NMData so we can get
at the device list
- (nm_netlink_monitor_event_handler): expand for wireless events too
* src/nm-marshal-main.c
- Include generated nm-marshal.c and nm-marshal.h
* src/nm-marshal.list
- List of custom marshal functions
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1555 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-06 01:10:58 +00:00
|
|
|
{
|
2016-07-05 13:21:49 +02:00
|
|
|
NMDeviceEthernetPrivate *priv;
|
|
|
|
|
|
|
|
|
|
priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate);
|
|
|
|
|
self->_priv = priv;
|
|
|
|
|
|
2017-10-13 16:12:35 +02:00
|
|
|
priv->s390_options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
|
2006-03-05 Dan Williams <dcbw@redhat.com>
Process netlink messages in device subclasses rather than in
NetworkManager.c. Also add support for recognizing Wireless Events.
* configure.in
- Find GLIB_GENMARSHAL
* src/Makefile.am
- Since we're marshalling custom types for wireless event signals,
we get to create our own marshallers using GLIB_GENMARSHAL
* src/NetworkManager.c
- (nm_monitor_wired_link_state): renamed to nm_monitor_setup
- (nm_monitor_setup): renamed from nm_monitor_wired_link_state, and
cut down somewhat. We no longer process signals here.
- (nm_data_new): create the netlink monitor here, and remove a
useless call to nm_policy_schedule_device_change_check()
- (nm_data_free): get rid of the netlink monitor here
- (nm_device_link_activated, nm_device_link_deactivated): removed
- (main): don't create the netlink monitor here, let nm_data_new
do that. Call nm_policy_schedule_device_change_check() right
before we jump to the mainloop to figure out which device
to use first
* src/NetworkManagerSystem.[ch]
- (nm_system_get_rtnl_index_from_iface, nm_system_get_iface_from_rtnl_index):
convert back and forth from interface names to interface
indexes
* src/nm-device-802-11-wireless.c
- (real_init): connect to wireless-event signals from the netlink
monitor object
- (nm_device_802_11_wireless_event): new function, schedule handler
for wireless event signals from the netlink monitor object. We
want the handler to run in the device's context
- (wireless_event_helper): handle wireless-event signals from netlink
- (nm_device_802_11_wireless_dispose): disconnect wireless-event
signal handler
* src/nm-device-802-11-wireless.h
- remove unused prototype for nm_device_802_11_wireless_new
* src/nm-device-802-3-ethernet.c
- (real_init): new function; set up signal handlers for link events
- (nm_device_802_3_ethernet_link_activated): new function, schedule
handler for netlink link activated events on device's main loop
- (link_activated_helper): when we get a link activated event, set
the device's link to be active
- (nm_device_802_3_ethernet_link_deactivated): new function; schedule
handler for netlink link deactivated events on device's main loop
- (link_deactivated_helper): when we get a link deactivated event, set
the device's link to be inactive
- (nm_device_802_3_ethernet_dispose): disconnect signal handler on
dispose
* src/nm-device-802-3-ethernet.h
- remove unused prototype for nm_device_802_3_ethernet_new
* src/nm-device.[ch]
- (nm_get_device_by_iface_locked): variant of nm_get_device_by_iface
but locks the device list
- (nm_device_set_active_link): a little bit of cleanup and de-indenting
* src/nm-netlink-monitor.[ch]
- (nm_netlink_monitor_class_install_signals): New signal
"wireless-event"
- (nm_netlink_monitor_new): keep reference to NMData so we can get
at the device list
- (nm_netlink_monitor_event_handler): expand for wireless events too
* src/nm-marshal-main.c
- Include generated nm-marshal.c and nm-marshal.h
* src/nm-marshal.list
- List of custom marshal functions
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1555 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2006-03-06 01:10:58 +00:00
|
|
|
}
|
|
|
|
|
|
2015-04-17 15:15:38 +02:00
|
|
|
static NMDeviceCapabilities
|
2014-08-02 15:14:26 +02:00
|
|
|
get_generic_capabilities(NMDevice *device)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device);
|
2016-12-19 08:20:05 +01:00
|
|
|
int ifindex = nm_device_get_ifindex(device);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-12-19 08:20:05 +01:00
|
|
|
if (ifindex > 0) {
|
2017-04-18 12:09:02 +02:00
|
|
|
if (nm_platform_link_supports_carrier_detect(nm_device_get_platform(device), ifindex))
|
2016-12-19 08:20:05 +01:00
|
|
|
return NM_DEVICE_CAP_CARRIER_DETECT;
|
|
|
|
|
else {
|
|
|
|
|
_LOGI(LOGD_PLATFORM,
|
|
|
|
|
"driver '%s' does not support carrier detection.",
|
|
|
|
|
nm_device_get_driver(device));
|
|
|
|
|
}
|
2013-05-20 15:38:54 -03:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-12-19 08:20:05 +01:00
|
|
|
return NM_DEVICE_CAP_NONE;
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-18 22:49:13 +02:00
|
|
|
static guint32
|
|
|
|
|
_subchannels_count_num(const char *const *array)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!array)
|
|
|
|
|
return 0;
|
|
|
|
|
for (i = 0; array[i]; i++)
|
|
|
|
|
/* NOP */;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
static gboolean
|
|
|
|
|
match_subchans(NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2014-08-21 13:19:53 -04:00
|
|
|
const char *const * subchans;
|
2015-09-18 22:49:13 +02:00
|
|
|
guint32 num1, num2;
|
2010-08-09 17:53:01 -05:00
|
|
|
int i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
*try_mac = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
subchans = nm_setting_wired_get_s390_subchannels(s_wired);
|
2015-09-18 22:49:13 +02:00
|
|
|
num1 = _subchannels_count_num(subchans);
|
|
|
|
|
num2 = _subchannels_count_num((const char *const *) priv->subchannels_dbus);
|
|
|
|
|
/* connection has no subchannels */
|
|
|
|
|
if (num1 == 0)
|
2010-08-09 17:53:01 -05:00
|
|
|
return TRUE;
|
|
|
|
|
/* connection requires subchannels but the device has none */
|
2015-09-18 22:49:13 +02:00
|
|
|
if (num2 == 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
/* number of subchannels differ */
|
|
|
|
|
if (num1 != num2)
|
2010-08-09 17:53:01 -05:00
|
|
|
return FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
/* Make sure each subchannel in the connection is a subchannel of this device */
|
2014-08-21 13:19:53 -04:00
|
|
|
for (i = 0; subchans[i]; i++) {
|
|
|
|
|
const char *candidate = subchans[i];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
if ((priv->subchan1 && !strcmp(priv->subchan1, candidate))
|
|
|
|
|
|| (priv->subchan2 && !strcmp(priv->subchan2, candidate))
|
|
|
|
|
|| (priv->subchan3 && !strcmp(priv->subchan3, candidate)))
|
|
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
return FALSE; /* a subchannel was not found */
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-08-09 17:53:01 -05:00
|
|
|
*try_mac = FALSE;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-07 13:15:20 +01:00
|
|
|
static gboolean
|
2018-06-27 17:00:55 +02:00
|
|
|
check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error)
|
2011-12-07 13:15:20 +01:00
|
|
|
{
|
|
|
|
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMSettingWired * s_wired;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-06-27 17:00:55 +02:00
|
|
|
if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class)
|
|
|
|
|
->check_connection_compatible(device, connection, error))
|
2013-03-07 07:44:36 -05:00
|
|
|
return FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-11-12 21:58:13 +01:00
|
|
|
if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)
|
|
|
|
|
|| (nm_connection_is_type(connection, NM_SETTING_VETH_SETTING_NAME)
|
|
|
|
|
&& NM_IS_DEVICE_VETH(device))) {
|
2018-06-27 17:00:55 +02:00
|
|
|
s_wired = nm_connection_get_setting_wired(connection);
|
|
|
|
|
} else {
|
|
|
|
|
s_wired =
|
|
|
|
|
_nm_connection_check_main_setting(connection, NM_SETTING_WIRED_SETTING_NAME, error);
|
2014-05-30 13:44:53 -05:00
|
|
|
if (!s_wired)
|
2011-12-07 13:15:20 +01:00
|
|
|
return FALSE;
|
2018-06-27 17:00:55 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2011-12-07 13:15:20 +01:00
|
|
|
if (s_wired) {
|
2014-10-03 17:37:26 -05:00
|
|
|
const char * mac, *perm_hw_addr;
|
2011-12-07 13:15:20 +01:00
|
|
|
gboolean try_mac = TRUE;
|
2014-10-22 12:31:31 -04:00
|
|
|
const char *const *mac_blacklist;
|
|
|
|
|
int i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-06-27 17:00:55 +02:00
|
|
|
if (!match_subchans(self, s_wired, &try_mac)) {
|
|
|
|
|
nm_utils_error_set_literal(error,
|
|
|
|
|
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
|
|
|
|
"s390 subchannels don't match");
|
2011-12-07 13:15:20 +01:00
|
|
|
return FALSE;
|
2018-06-27 17:00:55 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-10-13 18:52:12 +02:00
|
|
|
perm_hw_addr = nm_device_get_permanent_hw_address(device);
|
2011-12-07 13:15:20 +01:00
|
|
|
mac = nm_setting_wired_get_mac_address(s_wired);
|
2014-10-03 17:37:26 -05:00
|
|
|
if (perm_hw_addr) {
|
2018-06-27 17:00:55 +02:00
|
|
|
if (try_mac && mac && !nm_utils_hwaddr_matches(mac, -1, perm_hw_addr, -1)) {
|
|
|
|
|
nm_utils_error_set_literal(error,
|
|
|
|
|
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
|
|
|
|
"permanent MAC address doesn't match");
|
2011-12-07 13:15:20 +01:00
|
|
|
return FALSE;
|
2018-06-27 17:00:55 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-10-03 17:37:26 -05:00
|
|
|
/* Check for MAC address blacklist */
|
|
|
|
|
mac_blacklist = nm_setting_wired_get_mac_address_blacklist(s_wired);
|
|
|
|
|
for (i = 0; mac_blacklist[i]; i++) {
|
|
|
|
|
if (!nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)) {
|
2018-06-27 17:00:55 +02:00
|
|
|
nm_utils_error_set_literal(error,
|
|
|
|
|
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
|
|
|
|
"invalid MAC in blacklist");
|
2014-10-03 17:37:26 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-06-27 17:00:55 +02:00
|
|
|
if (nm_utils_hwaddr_matches(mac_blacklist[i], -1, perm_hw_addr, -1)) {
|
|
|
|
|
nm_utils_error_set_literal(error,
|
|
|
|
|
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
|
|
|
|
"permanent MAC address of device blacklisted");
|
2014-10-03 17:37:26 -05:00
|
|
|
return FALSE;
|
2018-06-27 17:00:55 +02:00
|
|
|
}
|
2014-10-03 17:37:26 -05:00
|
|
|
}
|
2018-06-27 17:00:55 +02:00
|
|
|
} else if (mac) {
|
|
|
|
|
nm_utils_error_set_literal(error,
|
|
|
|
|
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
|
|
|
|
"device has no permanent MAC address to match");
|
2014-10-03 17:37:26 -05:00
|
|
|
return FALSE;
|
2018-06-27 17:00:55 +02:00
|
|
|
}
|
2011-12-07 13:15:20 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2011-12-07 13:15:20 +01:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-18 22:19:09 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
/* 802.1X */
|
|
|
|
|
|
|
|
|
|
static void
|
2017-02-14 19:30:21 +01:00
|
|
|
supplicant_interface_release(NMDeviceEthernet *self)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
2008-06-10 15:54:23 +00:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
nm_clear_pointer(&priv->supplicant.create_handle,
|
|
|
|
|
nm_supplicant_manager_create_interface_cancel);
|
|
|
|
|
|
|
|
|
|
nm_clear_g_source(&priv->supplicant.lnk_timeout_id);
|
2016-01-19 13:56:47 +01:00
|
|
|
nm_clear_g_source(&priv->supplicant.con_timeout_id);
|
2016-01-19 13:39:02 +01:00
|
|
|
nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id);
|
2019-07-11 22:13:50 +02:00
|
|
|
nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.auth_state_id);
|
2021-08-06 15:17:05 +02:00
|
|
|
priv->supplicant.ready = FALSE;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
|
|
|
|
if (priv->supplicant.iface) {
|
|
|
|
|
nm_supplicant_interface_disconnect(priv->supplicant.iface);
|
2016-01-19 15:42:24 +01:00
|
|
|
g_clear_object(&priv->supplicant.iface);
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-11 22:13:50 +02:00
|
|
|
static void
|
|
|
|
|
supplicant_auth_state_changed(NMSupplicantInterface *iface,
|
|
|
|
|
GParamSpec * pspec,
|
|
|
|
|
NMDeviceEthernet * self)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
NMSupplicantAuthState state;
|
|
|
|
|
|
|
|
|
|
state = nm_supplicant_interface_get_auth_state(priv->supplicant.iface);
|
|
|
|
|
_LOGD(LOGD_CORE, "supplicant auth state changed to %u", (unsigned) state);
|
|
|
|
|
|
|
|
|
|
if (state == NM_SUPPLICANT_AUTH_STATE_SUCCESS) {
|
|
|
|
|
nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id);
|
|
|
|
|
nm_device_update_dynamic_ip_setup(NM_DEVICE(self));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
wired_auth_is_optional(NMDeviceEthernet *self)
|
|
|
|
|
{
|
|
|
|
|
NMSetting8021x *s_8021x;
|
|
|
|
|
|
|
|
|
|
s_8021x = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_802_1X);
|
|
|
|
|
g_return_val_if_fail(s_8021x, FALSE);
|
|
|
|
|
return nm_setting_802_1x_get_optional(s_8021x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wired_auth_cond_fail(NMDeviceEthernet *self, NMDeviceStateReason reason)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
NMDevice * device = NM_DEVICE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (!wired_auth_is_optional(self)) {
|
|
|
|
|
supplicant_interface_release(self);
|
|
|
|
|
nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason);
|
2019-07-11 22:13:50 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) 802.1X authentication is optional, continuing after a failure");
|
|
|
|
|
|
|
|
|
|
if (NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH))
|
|
|
|
|
nm_device_activate_schedule_stage2_device_config(device, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!priv->supplicant.auth_state_id) {
|
|
|
|
|
priv->supplicant.auth_state_id =
|
|
|
|
|
g_signal_connect(priv->supplicant.iface,
|
|
|
|
|
"notify::" NM_SUPPLICANT_INTERFACE_AUTH_STATE,
|
|
|
|
|
G_CALLBACK(supplicant_auth_state_changed),
|
|
|
|
|
self);
|
|
|
|
|
}
|
2019-07-11 22:13:50 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-13 13:11:51 -06:00
|
|
|
static void
|
|
|
|
|
wired_secrets_cb(NMActRequest * req,
|
2017-11-24 16:24:40 +01:00
|
|
|
NMActRequestGetSecretsCallId *call_id,
|
2015-07-14 16:53:24 +02:00
|
|
|
NMSettingsConnection * connection,
|
2010-12-13 13:11:51 -06:00
|
|
|
GError * error,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
2016-12-16 14:12:21 +01:00
|
|
|
NMDeviceEthernet * self = user_data;
|
|
|
|
|
NMDevice * device = user_data;
|
|
|
|
|
NMDeviceEthernetPrivate *priv;
|
2010-12-13 13:11:51 -06:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
g_return_if_fail(NM_IS_DEVICE_ETHERNET(self));
|
|
|
|
|
g_return_if_fail(NM_IS_ACT_REQUEST(req));
|
|
|
|
|
|
|
|
|
|
priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
g_return_if_fail(priv->wired_secrets_id == call_id);
|
|
|
|
|
|
|
|
|
|
priv->wired_secrets_id = NULL;
|
|
|
|
|
|
|
|
|
|
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
2015-09-03 10:24:09 +02:00
|
|
|
return;
|
|
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
g_return_if_fail(req == nm_device_get_act_request(device));
|
|
|
|
|
g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_NEED_AUTH);
|
2015-07-14 16:53:24 +02:00
|
|
|
g_return_if_fail(nm_act_request_get_settings_connection(req) == connection);
|
2010-12-13 13:11:51 -06:00
|
|
|
|
|
|
|
|
if (error) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGW(LOGD_ETHER, "%s", error->message);
|
2019-07-11 22:13:50 +02:00
|
|
|
wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
2019-08-22 10:43:22 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-11 22:13:50 +02:00
|
|
|
supplicant_interface_release(self);
|
2020-02-28 13:55:40 +01:00
|
|
|
nm_device_activate_schedule_stage1_device_prepare(device, FALSE);
|
2016-12-16 14:12:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wired_secrets_cancel(NMDeviceEthernet *self)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (priv->wired_secrets_id)
|
|
|
|
|
nm_act_request_cancel_secrets(NULL, priv->wired_secrets_id);
|
|
|
|
|
nm_assert(!priv->wired_secrets_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wired_secrets_get_secrets(NMDeviceEthernet * self,
|
|
|
|
|
const char * setting_name,
|
|
|
|
|
NMSecretAgentGetSecretsFlags flags)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
NMActRequest * req;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
wired_secrets_cancel(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
req = nm_device_get_act_request(NM_DEVICE(self));
|
|
|
|
|
g_return_if_fail(NM_IS_ACT_REQUEST(req));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
priv->wired_secrets_id =
|
|
|
|
|
nm_act_request_get_secrets(req, TRUE, setting_name, flags, NULL, wired_secrets_cb, self);
|
|
|
|
|
g_return_if_fail(priv->wired_secrets_id);
|
2010-12-13 13:11:51 -06:00
|
|
|
}
|
|
|
|
|
|
2008-03-18 22:19:09 +00:00
|
|
|
static gboolean
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
supplicant_lnk_timeout_cb(gpointer user_data)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
2008-06-10 15:54:23 +00:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2019-08-28 16:03:02 +02:00
|
|
|
NMDevice * device = NM_DEVICE(self);
|
2008-03-18 22:19:09 +00:00
|
|
|
NMActRequest * req;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMConnection * applied_connection;
|
2008-03-18 22:19:09 +00:00
|
|
|
const char * setting_name;
|
|
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
priv->supplicant.lnk_timeout_id = 0;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2019-08-28 16:03:02 +02:00
|
|
|
req = nm_device_get_act_request(device);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2019-08-28 16:03:02 +02:00
|
|
|
if (nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) {
|
2019-07-11 22:13:50 +02:00
|
|
|
wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disconnect event during initial authentication and credentials
|
|
|
|
|
* ARE checked - we are likely to have wrong key. Ask the user for
|
|
|
|
|
* another one.
|
|
|
|
|
*/
|
2019-08-28 16:03:02 +02:00
|
|
|
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
|
2008-03-18 22:19:09 +00:00
|
|
|
goto time_out;
|
|
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_clear_secrets(NM_ACTIVE_CONNECTION(req));
|
|
|
|
|
|
|
|
|
|
applied_connection = nm_act_request_get_applied_connection(req);
|
|
|
|
|
setting_name = nm_connection_need_secrets(applied_connection, NULL);
|
2008-03-18 22:19:09 +00:00
|
|
|
if (!setting_name)
|
|
|
|
|
goto time_out;
|
|
|
|
|
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) disconnected during authentication, asking for new key.");
|
2019-07-11 22:13:50 +02:00
|
|
|
if (!wired_auth_is_optional(self))
|
|
|
|
|
supplicant_interface_release(self);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2019-08-28 16:03:02 +02:00
|
|
|
nm_device_state_changed(device,
|
|
|
|
|
NM_DEVICE_STATE_NEED_AUTH,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
2016-12-16 14:12:21 +01:00
|
|
|
wired_secrets_get_secrets(self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
|
|
|
|
time_out:
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_ETHER, "link timed out.");
|
2019-07-11 22:13:50 +02:00
|
|
|
wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NMSupplicantConfig *
|
2015-11-18 22:03:00 +01:00
|
|
|
build_supplicant_config(NMDeviceEthernet *self, GError **error)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
2012-01-27 13:04:10 +01:00
|
|
|
const char * con_uuid;
|
2008-07-11 10:28:53 +00:00
|
|
|
NMSupplicantConfig *config = NULL;
|
2008-03-18 22:19:09 +00:00
|
|
|
NMSetting8021x * security;
|
|
|
|
|
NMConnection * connection;
|
2015-09-16 18:22:08 +02:00
|
|
|
guint32 mtu;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_device_get_applied_connection(NM_DEVICE(self));
|
2018-10-22 13:06:27 +02:00
|
|
|
|
|
|
|
|
g_return_val_if_fail(connection, NULL);
|
|
|
|
|
|
2012-01-27 13:04:10 +01:00
|
|
|
con_uuid = nm_connection_get_uuid(connection);
|
2017-04-18 12:09:02 +02:00
|
|
|
mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)),
|
2015-09-16 18:22:08 +02:00
|
|
|
nm_device_get_ifindex(NM_DEVICE(self)));
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2020-01-05 07:33:15 +01:00
|
|
|
config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
security = nm_connection_get_setting_802_1x(connection);
|
2015-11-18 22:03:00 +01:00
|
|
|
if (!nm_supplicant_config_add_setting_8021x(config, security, con_uuid, mtu, TRUE, error)) {
|
|
|
|
|
g_prefix_error(error, "802-1x-setting: ");
|
|
|
|
|
g_clear_object(&config);
|
2008-07-11 10:28:53 +00:00
|
|
|
}
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2008-07-11 10:28:53 +00:00
|
|
|
return config;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
static void
|
|
|
|
|
supplicant_iface_state_is_completed(NMDeviceEthernet *self, NMSupplicantInterfaceState state)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (state == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
|
|
|
|
|
nm_clear_g_source(&priv->supplicant.lnk_timeout_id);
|
|
|
|
|
nm_clear_g_source(&priv->supplicant.con_timeout_id);
|
2021-08-06 15:17:05 +02:00
|
|
|
priv->supplicant.ready = TRUE;
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
|
|
|
|
|
/* If this is the initial association during device activation,
|
2021-08-06 15:17:05 +02:00
|
|
|
* schedule the activation stage again to proceed.
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
*/
|
|
|
|
|
if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_CONFIG) {
|
|
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) Stage 2 of 5 (Device Configure) successful.");
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_device_activate_schedule_stage2_device_config(NM_DEVICE(self), FALSE);
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (!priv->supplicant.lnk_timeout_id && !priv->supplicant.con_timeout_id)
|
|
|
|
|
priv->supplicant.lnk_timeout_id =
|
|
|
|
|
g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-14 19:30:21 +01:00
|
|
|
static void
|
|
|
|
|
supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data)
|
|
|
|
|
{
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
NMDeviceEthernet * self;
|
|
|
|
|
NMDeviceEthernetPrivate *priv;
|
|
|
|
|
|
|
|
|
|
if (nm_utils_error_is_cancelled_or_disposing(error))
|
|
|
|
|
return;
|
2017-02-14 19:30:21 +01:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (error) {
|
2017-02-14 19:30:21 +01:00
|
|
|
supplicant_interface_release(self);
|
|
|
|
|
nm_device_queue_state(NM_DEVICE(self),
|
|
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_assert(!priv->supplicant.lnk_timeout_id);
|
|
|
|
|
nm_assert(!priv->supplicant.is_associated);
|
|
|
|
|
|
|
|
|
|
priv->supplicant.is_associated = TRUE;
|
|
|
|
|
supplicant_iface_state_is_completed(self,
|
|
|
|
|
nm_supplicant_interface_get_state(priv->supplicant.iface));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
supplicant_iface_start(NMDeviceEthernet *self)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
gs_unref_object NMSupplicantConfig *config = NULL;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
config = build_supplicant_config(self, &error);
|
|
|
|
|
if (!config) {
|
|
|
|
|
_LOGE(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) couldn't build security configuration: %s",
|
|
|
|
|
error->message);
|
|
|
|
|
supplicant_interface_release(self);
|
|
|
|
|
nm_device_state_changed(NM_DEVICE(self),
|
|
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
|
|
|
|
return FALSE;
|
2017-02-14 19:30:21 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
nm_supplicant_interface_disconnect(priv->supplicant.iface);
|
|
|
|
|
nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self);
|
|
|
|
|
return TRUE;
|
2017-02-14 19:30:21 +01:00
|
|
|
}
|
|
|
|
|
|
2010-10-06 11:05:21 -05:00
|
|
|
static void
|
|
|
|
|
supplicant_iface_state_cb(NMSupplicantInterface *iface,
|
2017-02-14 01:30:25 +01:00
|
|
|
int new_state_i,
|
|
|
|
|
int old_state_i,
|
2012-09-12 11:58:41 -05:00
|
|
|
int disconnect_reason,
|
2010-10-06 11:05:21 -05:00
|
|
|
gpointer user_data)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
2010-10-06 11:05:21 -05:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
NMDeviceEthernetPrivate * priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2017-02-14 01:30:25 +01:00
|
|
|
NMSupplicantInterfaceState new_state = new_state_i;
|
|
|
|
|
NMSupplicantInterfaceState old_state = old_state_i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"supplicant interface state: %s -> %s",
|
|
|
|
|
nm_supplicant_interface_state_to_string(old_state),
|
|
|
|
|
nm_supplicant_interface_state_to_string(new_state));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
2010-10-06 11:05:21 -05:00
|
|
|
supplicant_interface_release(self);
|
2021-03-09 07:41:00 +01:00
|
|
|
nm_device_state_changed(NM_DEVICE(self),
|
|
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
|
|
|
|
|
if (!supplicant_iface_start(self))
|
|
|
|
|
return;
|
2010-10-06 11:05:21 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (priv->supplicant.is_associated)
|
|
|
|
|
supplicant_iface_state_is_completed(self, new_state);
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
static gboolean
|
2008-06-10 15:54:23 +00:00
|
|
|
handle_auth_or_fail(NMDeviceEthernet *self, NMActRequest *req, gboolean new_secrets)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
|
|
|
|
const char * setting_name;
|
2015-07-14 16:53:24 +02:00
|
|
|
NMConnection *applied_connection;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2017-11-02 10:56:30 +01:00
|
|
|
if (!nm_device_auth_retries_try_next(NM_DEVICE(self)))
|
2020-02-27 16:45:16 +01:00
|
|
|
return FALSE;
|
2017-01-19 17:25:31 +01:00
|
|
|
|
2008-07-11 10:28:53 +00:00
|
|
|
nm_device_state_changed(NM_DEVICE(self),
|
|
|
|
|
NM_DEVICE_STATE_NEED_AUTH,
|
|
|
|
|
NM_DEVICE_STATE_REASON_NONE);
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
nm_active_connection_clear_secrets(NM_ACTIVE_CONNECTION(req));
|
|
|
|
|
|
2017-10-24 11:11:18 +02:00
|
|
|
applied_connection = nm_act_request_get_applied_connection(req);
|
2015-07-14 16:53:24 +02:00
|
|
|
setting_name = nm_connection_need_secrets(applied_connection, NULL);
|
2018-04-12 14:16:25 +02:00
|
|
|
if (!setting_name) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGI(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets.");
|
2020-02-27 16:45:16 +01:00
|
|
|
return FALSE;
|
2018-04-12 13:56:30 +02:00
|
|
|
}
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2019-07-11 22:13:50 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER, "Activation: (ethernet) asking for new secrets");
|
|
|
|
|
|
|
|
|
|
/* Don't tear down supplicant if the authentication is optional
|
|
|
|
|
* because in case of a failure in getting new secrets we want to
|
|
|
|
|
* keep the supplicant alive.
|
|
|
|
|
*/
|
|
|
|
|
if (!wired_auth_is_optional(self))
|
|
|
|
|
supplicant_interface_release(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-04-12 14:16:25 +02:00
|
|
|
wired_secrets_get_secrets(
|
|
|
|
|
self,
|
|
|
|
|
setting_name,
|
|
|
|
|
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
|
|
|
|
|
| (new_secrets ? NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW : 0));
|
2020-02-27 16:45:16 +01:00
|
|
|
return TRUE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
supplicant_connection_timeout_cb(gpointer user_data)
|
|
|
|
|
{
|
2008-06-10 15:54:23 +00:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data);
|
2008-09-25 10:02:28 +00:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2008-03-18 22:19:09 +00:00
|
|
|
NMDevice * device = NM_DEVICE(self);
|
|
|
|
|
NMActRequest * req;
|
2016-03-04 10:15:32 +01:00
|
|
|
NMSettingsConnection * connection;
|
2013-12-11 16:06:35 +01:00
|
|
|
guint64 timestamp = 0;
|
|
|
|
|
gboolean new_secrets = TRUE;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
2008-09-25 10:02:28 +00:00
|
|
|
priv->supplicant.con_timeout_id = 0;
|
|
|
|
|
|
2013-12-11 16:06:35 +01:00
|
|
|
/* Authentication failed; either driver problems, the encryption key is
|
|
|
|
|
* wrong, the passwords or certificates were wrong or the Ethernet switch's
|
|
|
|
|
* port is not configured for 802.1x. */
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_ETHER, "Activation: (ethernet) association took too long.");
|
2008-03-18 22:19:09 +00:00
|
|
|
|
|
|
|
|
req = nm_device_get_act_request(device);
|
2016-03-04 10:15:32 +01:00
|
|
|
connection = nm_act_request_get_settings_connection(req);
|
2013-12-11 16:06:35 +01:00
|
|
|
|
|
|
|
|
/* Ask for new secrets only if we've never activated this connection
|
|
|
|
|
* before. If we've connected before, don't bother the user with dialogs,
|
|
|
|
|
* just retry or fail, and if we never connect the user can fix the
|
|
|
|
|
* password somewhere else. */
|
2016-03-04 10:15:32 +01:00
|
|
|
if (nm_settings_connection_get_timestamp(connection, ×tamp))
|
2013-12-11 16:06:35 +01:00
|
|
|
new_secrets = !timestamp;
|
|
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
if (!handle_auth_or_fail(self, req, new_secrets)) {
|
2019-07-11 22:13:50 +02:00
|
|
|
wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!priv->supplicant.lnk_timeout_id && priv->supplicant.iface) {
|
|
|
|
|
NMSupplicantInterfaceState state;
|
2008-03-18 22:19:09 +00:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
state = nm_supplicant_interface_get_state(priv->supplicant.iface);
|
|
|
|
|
if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
|
2020-04-01 11:56:21 +02:00
|
|
|
&& nm_supplicant_interface_state_is_operational(state))
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
priv->supplicant.lnk_timeout_id =
|
|
|
|
|
g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
static void
|
|
|
|
|
supplicant_interface_create_cb(NMSupplicantManager * supplicant_manager,
|
|
|
|
|
NMSupplMgrCreateIfaceHandle *handle,
|
|
|
|
|
NMSupplicantInterface * iface,
|
|
|
|
|
GError * error,
|
|
|
|
|
gpointer user_data)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
NMDeviceEthernet * self;
|
|
|
|
|
NMDeviceEthernetPrivate *priv;
|
2017-01-19 17:25:29 +01:00
|
|
|
guint timeout;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (nm_utils_error_is_cancelled(error))
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
self = user_data;
|
|
|
|
|
priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
nm_assert(priv->supplicant.create_handle == handle);
|
|
|
|
|
priv->supplicant.create_handle = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
if (error) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGE(LOGD_DEVICE | LOGD_ETHER,
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
"Couldn't initialize supplicant interface: %s",
|
|
|
|
|
error->message);
|
|
|
|
|
supplicant_interface_release(self);
|
|
|
|
|
nm_device_state_changed(NM_DEVICE(self),
|
|
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
|
|
|
|
return;
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
priv->supplicant.iface = g_object_ref(iface);
|
|
|
|
|
priv->supplicant.is_associated = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2008-03-18 22:19:09 +00:00
|
|
|
priv->supplicant.iface_state_id = g_signal_connect(priv->supplicant.iface,
|
2012-09-12 11:28:02 -05:00
|
|
|
NM_SUPPLICANT_INTERFACE_STATE,
|
2010-10-06 11:05:21 -05:00
|
|
|
G_CALLBACK(supplicant_iface_state_cb),
|
|
|
|
|
self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-01-19 17:25:29 +01:00
|
|
|
timeout = nm_device_get_supplicant_timeout(NM_DEVICE(self));
|
|
|
|
|
priv->supplicant.con_timeout_id =
|
|
|
|
|
g_timeout_add_seconds(timeout, supplicant_connection_timeout_cb, self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-04-01 11:56:21 +02:00
|
|
|
if (nm_supplicant_interface_state_is_operational(nm_supplicant_interface_get_state(iface)))
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
supplicant_iface_start(self);
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-10 16:58:10 +02:00
|
|
|
static NMPlatformLinkDuplexType
|
|
|
|
|
link_duplex_to_platform(const char *duplex)
|
|
|
|
|
{
|
|
|
|
|
if (!duplex)
|
2016-11-22 12:59:11 +01:00
|
|
|
return NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
|
2016-09-10 16:58:10 +02:00
|
|
|
if (nm_streq(duplex, "full"))
|
|
|
|
|
return NM_PLATFORM_LINK_DUPLEX_FULL;
|
|
|
|
|
if (nm_streq(duplex, "half"))
|
|
|
|
|
return NM_PLATFORM_LINK_DUPLEX_HALF;
|
2016-11-22 12:59:11 +01:00
|
|
|
g_return_val_if_reached(NM_PLATFORM_LINK_DUPLEX_UNKNOWN);
|
2016-09-10 16:58:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
link_negotiation_set(NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2016-09-10 16:58:10 +02:00
|
|
|
NMSettingWired * s_wired;
|
2016-11-22 12:59:11 +01:00
|
|
|
gboolean autoneg = TRUE;
|
|
|
|
|
gboolean link_autoneg;
|
2021-01-14 10:11:13 +01:00
|
|
|
NMPlatformLinkDuplexType duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
|
|
|
|
|
NMPlatformLinkDuplexType link_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
|
|
|
|
|
guint32 speed = 0;
|
2016-11-22 12:59:11 +01:00
|
|
|
guint32 link_speed;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-10-22 13:06:27 +02:00
|
|
|
s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED);
|
2016-09-10 16:58:10 +02:00
|
|
|
if (s_wired) {
|
|
|
|
|
autoneg = nm_setting_wired_get_auto_negotiate(s_wired);
|
2018-06-12 11:57:54 +02:00
|
|
|
speed = nm_setting_wired_get_speed(s_wired);
|
|
|
|
|
duplex = link_duplex_to_platform(nm_setting_wired_get_duplex(s_wired));
|
2019-08-21 17:14:47 +02:00
|
|
|
if (!autoneg && !speed && !duplex) {
|
2018-06-12 11:57:54 +02:00
|
|
|
_LOGD(LOGD_DEVICE, "set-link: ignore link negotiation");
|
|
|
|
|
return;
|
2016-09-10 16:58:10 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-08-21 17:14:47 +02:00
|
|
|
if (!nm_platform_ethtool_get_link_settings(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device),
|
|
|
|
|
&link_autoneg,
|
|
|
|
|
&link_speed,
|
|
|
|
|
&link_duplex)) {
|
2016-09-10 16:58:10 +02:00
|
|
|
_LOGW(LOGD_DEVICE, "set-link: unable to retrieve link negotiation");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-08-21 17:14:47 +02:00
|
|
|
if (autoneg && !speed && !duplex)
|
2018-06-12 11:57:54 +02:00
|
|
|
_LOGD(LOGD_DEVICE, "set-link: configure auto-negotiation");
|
2016-11-22 12:59:11 +01:00
|
|
|
else {
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
_LOGD(LOGD_DEVICE,
|
2021-08-30 19:27:49 +02:00
|
|
|
"set-link: configure %snegotiation (%u Mbit, %s duplex)",
|
2018-06-12 11:57:54 +02:00
|
|
|
autoneg ? "auto-" : "static ",
|
2021-08-30 19:27:49 +02:00
|
|
|
speed,
|
|
|
|
|
nm_platform_link_duplex_type_to_string(duplex));
|
2016-11-22 12:59:11 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
if (!priv->ethtool_prev_set) {
|
|
|
|
|
/* remember the values we had before setting it. */
|
|
|
|
|
priv->ethtool_prev_autoneg = link_autoneg;
|
2021-08-30 19:24:58 +02:00
|
|
|
if (link_autoneg) {
|
|
|
|
|
/* with autoneg, we only support advertising one speed/duplex. Likewise
|
|
|
|
|
* our nm_platform_ethtool_get_link_settings() can only return the current
|
|
|
|
|
* speed/duplex, but not all the modes that we were advertising.
|
|
|
|
|
*
|
|
|
|
|
* Do the best we can do: remember to re-enable autoneg, but don't restrict
|
|
|
|
|
* the mode. */
|
|
|
|
|
priv->ethtool_prev_speed = 0;
|
|
|
|
|
priv->ethtool_prev_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
|
|
|
|
|
} else {
|
|
|
|
|
priv->ethtool_prev_speed = link_speed;
|
|
|
|
|
priv->ethtool_prev_duplex = link_duplex;
|
|
|
|
|
}
|
|
|
|
|
priv->ethtool_prev_set = TRUE;
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
if (!nm_platform_ethtool_set_link_settings(nm_device_get_platform(device),
|
2016-12-11 22:46:14 +01:00
|
|
|
nm_device_get_ifindex(device),
|
2016-09-10 16:58:10 +02:00
|
|
|
autoneg,
|
|
|
|
|
speed,
|
|
|
|
|
duplex)) {
|
|
|
|
|
_LOGW(LOGD_DEVICE, "set-link: failure to set link negotiation");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-09 09:33:13 +01:00
|
|
|
static gboolean
|
|
|
|
|
pppoe_reconnect_delay(gpointer user_data)
|
|
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_clear_g_source_inst(&priv->ppp_data.wait_source);
|
|
|
|
|
priv->ppp_data.last_pppoe_time_msec = 0;
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGI(LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection...");
|
2020-02-28 13:55:40 +01:00
|
|
|
nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE);
|
2021-08-06 15:17:05 +02:00
|
|
|
return G_SOURCE_CONTINUE;
|
2013-12-09 09:33:13 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-22 14:21:25 +02:00
|
|
|
static NMActStageReturn
|
2019-08-28 16:03:02 +02:00
|
|
|
act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
2010-06-22 14:21:25 +02:00
|
|
|
{
|
2019-08-28 16:03:02 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
2013-12-09 09:33:13 +01:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
if (nm_device_sys_iface_state_is_external_or_assume(device)) {
|
|
|
|
|
if (!priv->ethtool_prev_set && !nm_device_sys_iface_state_is_external(device)) {
|
|
|
|
|
NMSettingWired *s_wired;
|
|
|
|
|
|
|
|
|
|
/* During restart of NetworkManager service we forget the original auto
|
|
|
|
|
* negotiation settings. When taking over a device, remember to reset
|
|
|
|
|
* the "default" during deactivate. */
|
|
|
|
|
s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED);
|
|
|
|
|
if (s_wired
|
|
|
|
|
&& (nm_setting_wired_get_auto_negotiate(s_wired)
|
|
|
|
|
|| nm_setting_wired_get_speed(s_wired)
|
|
|
|
|
|| nm_setting_wired_get_duplex(s_wired))) {
|
|
|
|
|
priv->ethtool_prev_set = TRUE;
|
|
|
|
|
priv->ethtool_prev_autoneg = TRUE;
|
|
|
|
|
priv->ethtool_prev_speed = 0;
|
|
|
|
|
priv->ethtool_prev_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-08-28 16:03:02 +02:00
|
|
|
link_negotiation_set(device);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-08 18:12:37 +02:00
|
|
|
/* If we're re-activating a PPPoE connection a short while after
|
|
|
|
|
* a previous PPPoE connection was torn down, wait a bit to allow the
|
2020-07-01 17:20:40 -04:00
|
|
|
* remote side to handle the disconnection. Otherwise, the peer may
|
2016-09-08 18:12:37 +02:00
|
|
|
* get confused and fail to negotiate the new connection. (rh #1023503)
|
2019-08-21 17:14:47 +02:00
|
|
|
*
|
2020-07-04 11:37:01 +03:00
|
|
|
* FIXME(shutdown): when exiting, we also need to wait before quitting,
|
2019-08-21 17:14:47 +02:00
|
|
|
* at least for additional NM_SHUTDOWN_TIMEOUT_MS seconds because
|
|
|
|
|
* otherwise after restart the device won't work for the first seconds.
|
2016-09-08 18:12:37 +02:00
|
|
|
*/
|
2021-08-06 15:17:05 +02:00
|
|
|
if (priv->ppp_data.last_pppoe_time_msec != 0) {
|
|
|
|
|
gint64 delay =
|
|
|
|
|
nm_utils_get_monotonic_timestamp_msec() - priv->ppp_data.last_pppoe_time_msec;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (delay < PPPOE_RECONNECT_DELAY_MSEC
|
2019-08-28 16:03:02 +02:00
|
|
|
&& nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE)) {
|
2021-08-06 15:17:05 +02:00
|
|
|
if (!priv->ppp_data.wait_source) {
|
2019-08-21 17:14:47 +02:00
|
|
|
_LOGI(LOGD_DEVICE,
|
2021-08-06 15:17:05 +02:00
|
|
|
"delaying PPPoE reconnect for %d.%03d seconds to ensure peer is ready...",
|
|
|
|
|
(int) (delay / 1000),
|
|
|
|
|
(int) (delay % 1000));
|
|
|
|
|
priv->ppp_data.wait_source =
|
|
|
|
|
nm_g_timeout_add_source(delay, pppoe_reconnect_delay, self);
|
2019-08-21 17:14:47 +02:00
|
|
|
}
|
2016-09-08 18:12:37 +02:00
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
2013-12-09 09:33:13 +01:00
|
|
|
}
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_clear_g_source_inst(&priv->ppp_data.wait_source);
|
|
|
|
|
priv->ppp_data.last_pppoe_time_msec = 0;
|
2012-02-28 18:35:30 -06:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-08 18:12:37 +02:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2010-06-22 14:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
2008-03-18 22:19:09 +00:00
|
|
|
static NMActStageReturn
|
2019-11-08 08:36:41 +01:00
|
|
|
supplicant_check_secrets_needed(NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
|
2008-03-18 22:19:09 +00:00
|
|
|
{
|
2013-06-12 10:48:03 -05:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2008-03-18 22:19:09 +00:00
|
|
|
NMConnection * connection;
|
|
|
|
|
NMSetting8021x * security;
|
|
|
|
|
const char * setting_name;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-07-14 16:53:24 +02:00
|
|
|
connection = nm_device_get_applied_connection(NM_DEVICE(self));
|
2017-02-22 17:04:00 +01:00
|
|
|
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
security = nm_connection_get_setting_802_1x(connection);
|
2008-03-18 22:19:09 +00:00
|
|
|
if (!security) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGE(LOGD_DEVICE, "Invalid or missing 802.1X security");
|
2017-02-22 17:04:00 +01:00
|
|
|
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
2020-02-27 16:45:16 +01:00
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-06-12 10:48:03 -05:00
|
|
|
if (!priv->supplicant.mgr)
|
2015-01-06 11:54:27 +01:00
|
|
|
priv->supplicant.mgr = g_object_ref(nm_supplicant_manager_get());
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2008-03-18 22:19:09 +00:00
|
|
|
/* If we need secrets, get them */
|
|
|
|
|
setting_name = nm_connection_need_secrets(connection, NULL);
|
|
|
|
|
if (setting_name) {
|
2008-07-11 10:28:53 +00:00
|
|
|
NMActRequest *req = nm_device_get_act_request(NM_DEVICE(self));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) connection '%s' has security, but secrets are required.",
|
|
|
|
|
nm_connection_get_id(connection));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
if (!handle_auth_or_fail(self, req, FALSE)) {
|
2017-02-22 17:04:00 +01:00
|
|
|
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS);
|
2020-02-27 16:45:16 +01:00
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
_LOGI(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"Activation: (ethernet) connection '%s' requires no security. No secrets needed.",
|
|
|
|
|
nm_connection_get_id(connection));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
supplicant_interface_release(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
supplicant: large rework of wpa_supplicant handling
Avoid GDBusProxy, instead use GDBusConnection directly. I very much
prefer this because that way we have explicit control over what happens
on D-Bus. With GDBusProxy this is hidden under another layer of complex
code. The hardest part when using a D-Bus interface is to manage the
state via an asynchronous medium. GDBusProxy contains state about the
D-Bus interface and duplicate the state that we track. This makes it hard
to reason about things.
Rework creation of NMSupplicantInterface. Previously, a NMSupplicantInterface
had multiple initialization states. In particular, the first state would not
yet tie the interface to a certain D-Bus object path. Instead, NMSupplicantInterface
would try and retry to create the D-Bus object.
Now, NMSupplicantManager has an asynchronous method to create interface
instances. The manager only creates an interface instance after the D-Bus
path is known. That means, a NMSupplicantInterface instance is now
strongly tied to a name-owner and D-Bus path.
It follows that the state of NMSupplicantInterface can only go from STARTING,
via the supplicant states, to DOWN. Never back. That was already previously
the case that the state from DOWN was final and once the 3 initial
states were passed, the interface's state would never go back to the initial
state. Now this is more strict and more formalized. The 3 initialization states
are combined.
I think the tighter state handling simplifies users of NMSupplicantInterface.
See for example "nm-device-ethernet.c". It's still complicated, because handling
state is fundamentally difficult.
NMSupplicantManager will take care to D-Bus activate wpa_supplicant only
when necessary (poke). Previously, creating the manager instance
would always start suppliant service. Now, it's started on demand.
2020-01-21 15:05:16 +01:00
|
|
|
priv->supplicant.create_handle =
|
|
|
|
|
nm_supplicant_manager_create_interface(priv->supplicant.mgr,
|
|
|
|
|
nm_device_get_ifindex(NM_DEVICE(self)),
|
|
|
|
|
NM_SUPPLICANT_DRIVER_WIRED,
|
|
|
|
|
supplicant_interface_create_cb,
|
|
|
|
|
self);
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
2008-03-18 22:19:09 +00:00
|
|
|
}
|
2008-03-11 16:37:41 +00:00
|
|
|
|
2019-11-08 08:36:41 +01:00
|
|
|
static void
|
|
|
|
|
carrier_changed(NMSupplicantInterface *iface, GParamSpec *pspec, NMDeviceEthernet *self)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
NMDeviceStateReason reason;
|
|
|
|
|
NMActStageReturn ret;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
if (!nm_device_has_carrier(NM_DEVICE(self)))
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
_LOGD(LOGD_DEVICE | LOGD_ETHER, "got carrier, initializing supplicant");
|
|
|
|
|
nm_clear_g_signal_handler(self, &priv->carrier_id);
|
|
|
|
|
ret = supplicant_check_secrets_needed(self, &reason);
|
|
|
|
|
if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
|
|
|
|
nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason);
|
2019-11-08 08:36:41 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-11 16:37:41 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void
|
2021-08-06 15:17:05 +02:00
|
|
|
_ppp_mgr_cleanup(NMDeviceEthernet *self)
|
2008-03-11 16:37:41 +00:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_clear_pointer(&priv->ppp_data.ppp_mgr, nm_ppp_mgr_destroy);
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2018-01-08 16:45:43 +01:00
|
|
|
static void
|
2021-08-06 15:17:05 +02:00
|
|
|
_ppp_mgr_stage3_maybe_ready(NMDeviceEthernet *self)
|
2018-01-08 16:45:43 +01:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDevice * device = NM_DEVICE(self);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
int IS_IPv4;
|
2018-01-08 16:45:43 +01:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
|
|
|
|
const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
|
|
|
|
|
const NMPppMgrIPData *ip_data;
|
2018-01-08 16:45:43 +01:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
ip_data = nm_ppp_mgr_get_ip_data(priv->ppp_data.ppp_mgr, addr_family);
|
|
|
|
|
if (ip_data->ip_received)
|
|
|
|
|
nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, ip_data->l3cd);
|
|
|
|
|
}
|
2008-03-11 16:37:41 +00:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr) >= NM_PPP_MGR_STATE_HAVE_IP_CONFIG)
|
|
|
|
|
nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_READY, NULL);
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
static void
|
|
|
|
|
_ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data, gpointer user_data)
|
2008-03-07 Dan Williams <dcbw@redhat.com>
First pass of multiple active device support. Expect bugs.
* src/nm-ip4-config.c
src/nm-ip4-config.h
- (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove;
there are better ways to do this in the named manager
* src/nm-device.c
src/nm-device.h
- (nm_device_can_activate): return whether the device can activate a
connection right now; taking into account things like carrier state
and rfkill state
- (nm_device_get_best_auto_connection): renamed from
nm_device_get_best_connection
- (real_act_stage4_get_ip4_config): MTU stuff is now handled in the
device subclasses themselves, so that each device can override the
MTU from it's NMSetting subclass if needed
- (nm_device_set_ip4_config): set MTU when setting up routes and stuff
in NetworkManagerSystem.c, not here
* src/named-manager/nm-named-manager.c
src/named-manager/nm-named-manager.h
- (nm_named_manager_name_owner_changed,
nm_named_manager_dbus_connection_changed): fix for changes to
rewrite_resolv_conf()
- (compute_nameservers): don't need the NMNamedManager at all, remove
from parameter list
- (merge_one_ip4_config): new function; merge ip4 configs together
- (rewrite_resolv_conf): write out resolv.conf from all the stored
ip4 configs; the VPN config takes precedence, then the best
device config, then the rest of the configs
- (get_domain_for_config): take the NMNamedManager as an argument
to check whether the config is the VPN config
- (add_ip4_config_to_named): fixups for removal of the 'secondary'
attribute from ip4 configs
- (add_all_ip4_configs_to_named): add all the configs in priority order
- (remove_ip4_config_from_named): fix for changes to
get_domain_for_config()
- (nm_named_manager_add_ip4_config): assign the config to the right slot
based on its type; callers must pass in the type now
- (get_last_default_domain): remove, unused
- (nm_named_manager_remove_ip4_config): handle config slots correctly
* src/nm-device-802-11-wireless.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): handle MTU override
* src/nm-device-802-3-ethernet.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): new function; handle MTU override
* src/vpn-manager/nm-vpn-connection.c
- (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary'
attribute on the ip4 config
* src/NetworkManagerPolicy.c
- (nm_policy_auto_get_best_device): remove
- (nm_policy_device_change_check): remove
- (update_default_route): new function; set the default route via
the specified device
- (get_device_priority): new function; return the priority number of
a device type WRT which one should have the default route. Order is
(highest to lowest) wired, wireless, GSM, CDMA.
- (update_routing_and_dns): new function; determine which device should
have the default route, then update the routing table and DNS
- (maybe_auto_activate_device): new function; if a device is now
available for activation, find out what connection it would like to
activate and do it
- (schedule_activate_check): new function; if a device can be activated
now, schedule the activation. Each device may have only one
pending activation at a given time.
- (device_state_changed): if activation was canceled, try again,
possibly with another connection; if the device was activated,
update routing and DNS; if the device was deactivated, try again
with another connection
- (device_carrier_changed): if there is no carrier, deactivate the
device; otherwise schedule an activation check for the device
- (wireless_networks_changed): schedule an activation check for the
device
- (device_added): keep track of the signal handler IDs so they can
be removed when the device goes away
- (device_removed): remove any signal handlers that might be attached
to the device; update routing and DNS
- (schedule_activate_all): new function
- (connections_added, connection_added, connection_updated): when
connections change, schedule all devices for an activation check
- (connection_removed): when a device is deactivated because its
connection was removed, schedule another activation check for it
- (nm_policy_destroy): destroy pending activations and disconnect
all device signal handlers
* src/nm-manager.c
- (nm_manager_activate_device): if the device was already actived,
deactivate it
- (deactivate_old_device): remove
- (connection_added_default_handler, impl_manager_activate_device):
don't deactivate other devices when activating this one
* src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerSuSE.c
src/backends/NetworkManagerDebian.c
- (nm_system_get_mtu): remove; MTU should be provided through the
distro's system settings service plugin instead
- (nm_system_device_add_default_route_via_device): remove
- (nm_system_device_add_default_route_via_device_with_iface): remove
- (nm_system_device_replace_default_route): new function; call
generic implementation
* src/backends/NetworkManagerGeneric.c
src/backends/NetworkManagerGeneric.h
- (nm_generic_device_add_default_route_via_device,
nm_generic_device_add_default_route_via_device_with_iface): remove
- (nm_generic_device_replace_default_route): replace the default route
with the given route via some gateway
* src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
- (nm_system_device_set_from_ip4_config): let the policy handle updates
to routing and DNS; but set the MTU here
- (nm_system_vpn_device_set_from_ip4_config): set the route with the
ip_iface of the active device; use the standard MTU setting function
- (nm_system_set_mtu): remove
- (nm_system_device_set_mtu): consolidate MTU setting code in one place
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-07 19:41:32 +00:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
NMDevice * device = NM_DEVICE(self);
|
|
|
|
|
NMDeviceState device_state;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (callback_data->callback_type != NM_PPP_MGR_CALLBACK_TYPE_STATE_CHANGED)
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
device_state = nm_device_get_state(device);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (callback_data->data.state >= _NM_PPP_MGR_STATE_FAILED_START) {
|
|
|
|
|
if (device_state <= NM_DEVICE_STATE_ACTIVATED)
|
|
|
|
|
nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, callback_data->data.reason);
|
|
|
|
|
return;
|
2017-10-04 15:21:21 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (device_state < NM_DEVICE_STATE_IP_CONFIG) {
|
|
|
|
|
if (callback_data->data.state >= NM_PPP_MGR_STATE_HAVE_IFINDEX) {
|
|
|
|
|
gs_free char *old_name = NULL;
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
|
|
|
|
|
if (!nm_device_take_over_link(device, callback_data->data.ifindex, &old_name, &error)) {
|
|
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PPP,
|
|
|
|
|
"could not take control of link %d: %s",
|
|
|
|
|
callback_data->data.ifindex,
|
|
|
|
|
error->message);
|
|
|
|
|
_ppp_mgr_cleanup(self);
|
|
|
|
|
nm_device_state_changed(device,
|
|
|
|
|
NM_DEVICE_STATE_FAILED,
|
|
|
|
|
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (old_name)
|
|
|
|
|
nm_manager_remove_device(NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_device_activate_schedule_stage2_device_config(device, FALSE);
|
|
|
|
|
}
|
|
|
|
|
return;
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
_ppp_mgr_stage3_maybe_ready(self);
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
|
|
|
|
static void dcb_state(NMDevice *device, gboolean timeout);
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
dcb_carrier_timeout(gpointer user_data)
|
|
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
NMDevice * device = NM_DEVICE(user_data);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
g_return_val_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_timeout_id = 0;
|
|
|
|
|
if (priv->dcb_wait != DCB_WAIT_CARRIER_POSTCONFIG_DOWN) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGW(LOGD_DCB, "DCB: timed out waiting for carrier (step %d)", priv->dcb_wait);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
}
|
|
|
|
|
dcb_state(device, TRUE);
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
dcb_configure(NMDevice *device)
|
|
|
|
|
{
|
2016-07-05 13:21:49 +02:00
|
|
|
NMDeviceEthernet * self = (NMDeviceEthernet *) device;
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
NMSettingDcb * s_dcb;
|
|
|
|
|
GError * error = NULL;
|
|
|
|
|
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
2018-10-22 13:06:27 +02:00
|
|
|
s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(s_dcb, FALSE);
|
|
|
|
|
|
2014-08-02 15:14:26 +02:00
|
|
|
if (!nm_dcb_setup(nm_device_get_iface(device), s_dcb, &error)) {
|
|
|
|
|
_LOGW(LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", error->message);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
g_clear_error(&error);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Pause again just in case the device takes the carrier down when
|
|
|
|
|
* setting specific DCB attributes.
|
|
|
|
|
*/
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "waiting for carrier (postconfig down)");
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_DOWN;
|
|
|
|
|
priv->dcb_timeout_id = g_timeout_add_seconds(3, dcb_carrier_timeout, device);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
dcb_enable(NMDevice *device)
|
|
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
GError * error = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
2014-08-02 15:14:26 +02:00
|
|
|
if (!nm_dcb_enable(nm_device_get_iface(device), TRUE, &error)) {
|
|
|
|
|
_LOGW(LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", error->message);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
g_clear_error(&error);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
/* Pause for 3 seconds after enabling DCB to let the card reconfigure
|
|
|
|
|
* itself. Drivers will often re-initialize internal settings which
|
|
|
|
|
* takes the carrier down for 2 or more seconds. During this time,
|
|
|
|
|
* lldpad will refuse to do anything else with the card since the carrier
|
|
|
|
|
* is down. But NM might get the carrier-down signal long after calling
|
|
|
|
|
* "dcbtool dcb on", so we have to first wait for the carrier to go down.
|
|
|
|
|
*/
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "waiting for carrier (preconfig down)");
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_DOWN;
|
|
|
|
|
priv->dcb_timeout_id = g_timeout_add_seconds(3, dcb_carrier_timeout, device);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcb_state(NMDevice *device, gboolean timeout)
|
|
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
gboolean carrier;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
carrier = nm_platform_link_is_connected(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device));
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() wait %d carrier %d timeout %d", priv->dcb_wait, carrier, timeout);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
switch (priv->dcb_wait) {
|
|
|
|
|
case DCB_WAIT_CARRIER_PREENABLE_UP:
|
|
|
|
|
if (timeout || carrier) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() enabling DCB");
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (!dcb_enable(device)) {
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = FALSE;
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
nm_device_state_changed(device,
|
2014-07-26 21:46:34 +02:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
break;
|
|
|
|
|
case DCB_WAIT_CARRIER_PRECONFIG_DOWN:
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_UP;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (!carrier) {
|
|
|
|
|
/* Wait for the carrier to come back up */
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "waiting for carrier (preconfig up)");
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_timeout_id = g_timeout_add_seconds(5, dcb_carrier_timeout, device);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() preconfig down falling through");
|
2020-02-21 12:56:03 +01:00
|
|
|
/* fall-through */
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
case DCB_WAIT_CARRIER_PRECONFIG_UP:
|
|
|
|
|
if (timeout || carrier) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() preconfig up configuring DCB");
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (!dcb_configure(device)) {
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = FALSE;
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
nm_device_state_changed(device,
|
2014-07-26 21:46:34 +02:00
|
|
|
NM_DEVICE_STATE_FAILED,
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case DCB_WAIT_CARRIER_POSTCONFIG_DOWN:
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_UP;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (!carrier) {
|
|
|
|
|
/* Wait for the carrier to come back up */
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "waiting for carrier (postconfig up)");
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_timeout_id = g_timeout_add_seconds(5, dcb_carrier_timeout, device);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() postconfig down falling through");
|
2020-02-21 12:56:03 +01:00
|
|
|
/* fall-through */
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
case DCB_WAIT_CARRIER_POSTCONFIG_UP:
|
|
|
|
|
if (timeout || carrier) {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "dcb_state() postconfig up starting IP");
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = FALSE;
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_UNKNOWN;
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_device_activate_schedule_stage2_device_config(device, FALSE);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
2015-05-12 14:44:03 +02:00
|
|
|
static gboolean
|
|
|
|
|
wake_on_lan_enable(NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
NMSettingWiredWakeOnLan wol;
|
|
|
|
|
NMSettingWired * s_wired;
|
|
|
|
|
const char * password = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-10-22 13:06:27 +02:00
|
|
|
s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-11-12 21:58:13 +01:00
|
|
|
if (NM_IS_DEVICE_VETH(device))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2015-05-12 14:44:03 +02:00
|
|
|
if (s_wired) {
|
|
|
|
|
wol = nm_setting_wired_get_wake_on_lan(s_wired);
|
|
|
|
|
password = nm_setting_wired_get_wake_on_lan_password(s_wired);
|
|
|
|
|
if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)
|
|
|
|
|
goto found;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-05 09:24:33 +02:00
|
|
|
wol = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
2018-11-14 14:52:21 +01:00
|
|
|
NM_CON_DEFAULT("ethernet.wake-on-lan"),
|
2018-09-05 09:24:33 +02:00
|
|
|
device,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN_NONE,
|
|
|
|
|
G_MAXINT32,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-09-05 09:24:33 +02:00
|
|
|
if (NM_FLAGS_ANY(wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS)
|
|
|
|
|
&& !nm_utils_is_power_of_two(wol)) {
|
|
|
|
|
nm_log_dbg(LOGD_ETHER, "invalid default value %u for wake-on-lan", (guint) wol);
|
|
|
|
|
wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT;
|
2015-05-12 14:44:03 +02:00
|
|
|
}
|
2018-09-05 09:24:33 +02:00
|
|
|
if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)
|
|
|
|
|
goto found;
|
2015-09-21 18:24:07 +02:00
|
|
|
wol = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE;
|
2015-05-12 14:44:03 +02:00
|
|
|
found:
|
2018-09-05 09:24:33 +02:00
|
|
|
return nm_platform_ethtool_set_wake_on_lan(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device),
|
2021-01-08 17:01:45 +01:00
|
|
|
_NM_SETTING_WIRED_WAKE_ON_LAN_CAST(wol),
|
2018-09-05 09:24:33 +02:00
|
|
|
password);
|
2015-05-12 14:44:03 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-05-12 14:44:03 +02:00
|
|
|
|
2008-03-11 16:37:41 +00:00
|
|
|
static NMActStageReturn
|
2017-02-22 17:04:00 +01:00
|
|
|
act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
2008-03-11 16:37:41 +00:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2021-08-06 15:17:05 +02:00
|
|
|
NMConnection * connection;
|
2009-08-17 15:35:02 -05:00
|
|
|
NMSettingConnection * s_con;
|
2008-10-26 17:41:37 +00:00
|
|
|
const char * connection_type;
|
2013-10-04 16:56:34 -05:00
|
|
|
NMSettingDcb * s_dcb;
|
2021-08-06 15:17:05 +02:00
|
|
|
NMActRequest * req;
|
2008-03-11 16:37:41 +00:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
connection = nm_device_get_applied_connection(device);
|
|
|
|
|
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
|
2018-10-22 13:06:27 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
s_con = _nm_connection_get_setting(connection, NM_TYPE_SETTING_CONNECTION);
|
2017-02-22 17:04:00 +01:00
|
|
|
g_return_val_if_fail(s_con, NM_ACT_STAGE_RETURN_FAILURE);
|
2008-03-11 16:37:41 +00:00
|
|
|
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = FALSE;
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
connection_type = nm_setting_connection_get_connection_type(s_con);
|
|
|
|
|
|
|
|
|
|
if (nm_streq(connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
|
|
|
|
|
if (!priv->ppp_data.ppp_mgr) {
|
|
|
|
|
gs_free_error GError *error = NULL;
|
|
|
|
|
NMSettingPppoe * s_pppoe;
|
|
|
|
|
NMSettingPpp * s_ppp;
|
|
|
|
|
|
|
|
|
|
s_ppp = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPP);
|
|
|
|
|
if (s_ppp) {
|
|
|
|
|
guint32 mtu;
|
|
|
|
|
guint32 mru;
|
|
|
|
|
guint32 mxu;
|
|
|
|
|
|
|
|
|
|
mtu = nm_setting_ppp_get_mtu(s_ppp);
|
|
|
|
|
mru = nm_setting_ppp_get_mru(s_ppp);
|
|
|
|
|
mxu = MAX(mru, mtu);
|
|
|
|
|
if (mxu) {
|
|
|
|
|
_LOGD(LOGD_PPP,
|
|
|
|
|
"set MTU to %u (PPP interface MRU %u, MTU %u)",
|
|
|
|
|
mxu + PPPOE_ENCAP_OVERHEAD,
|
|
|
|
|
mru,
|
|
|
|
|
mtu);
|
|
|
|
|
nm_platform_link_set_mtu(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device),
|
|
|
|
|
mxu + PPPOE_ENCAP_OVERHEAD);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req = nm_device_get_act_request(device);
|
|
|
|
|
g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
|
|
|
|
|
s_pppoe = _nm_connection_get_setting(connection, NM_TYPE_SETTING_PPPOE);
|
|
|
|
|
g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
|
|
|
|
|
|
|
|
|
|
priv->ppp_data.ppp_mgr =
|
|
|
|
|
nm_ppp_mgr_start(&((const NMPppMgrConfig){
|
|
|
|
|
.netns = nm_device_get_netns(device),
|
|
|
|
|
.parent_iface = nm_device_get_iface(device),
|
|
|
|
|
.callback = _ppp_mgr_callback,
|
|
|
|
|
.user_data = self,
|
|
|
|
|
.act_req = req,
|
|
|
|
|
.ppp_username = nm_setting_pppoe_get_username(s_pppoe),
|
|
|
|
|
.timeout_secs = 30,
|
|
|
|
|
.baud_override = 0,
|
|
|
|
|
}),
|
|
|
|
|
&error);
|
|
|
|
|
if (!priv->ppp_data.ppp_mgr) {
|
|
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", error->message);
|
|
|
|
|
*out_failure_reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
|
|
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr) < NM_PPP_MGR_STATE_HAVE_IFINDEX)
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-17 15:35:02 -05:00
|
|
|
/* 802.1x has to run before any IP configuration since the 802.1x auth
|
|
|
|
|
* process opens the port up for normal traffic.
|
|
|
|
|
*/
|
2020-02-27 16:45:16 +01:00
|
|
|
if (nm_streq(connection_type, NM_SETTING_WIRED_SETTING_NAME)) {
|
2008-03-18 22:19:09 +00:00
|
|
|
NMSetting8021x *security;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-10-22 13:06:27 +02:00
|
|
|
security = nm_device_get_applied_setting(device, NM_TYPE_SETTING_802_1X);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (security) {
|
2021-08-06 15:17:05 +02:00
|
|
|
/* FIXME: we always return from this. stage2 must be re-entrant, and
|
|
|
|
|
* process all the necessary steps. Just returning for 8021x is wrong. */
|
|
|
|
|
|
|
|
|
|
if (priv->supplicant.ready)
|
|
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
|
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
if (!nm_device_has_carrier(NM_DEVICE(self))) {
|
|
|
|
|
_LOGD(LOGD_DEVICE | LOGD_ETHER,
|
|
|
|
|
"delay supplicant initialization until carrier goes up");
|
|
|
|
|
priv->carrier_id = g_signal_connect(self,
|
|
|
|
|
"notify::" NM_DEVICE_CARRIER,
|
|
|
|
|
G_CALLBACK(carrier_changed),
|
|
|
|
|
self);
|
|
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-02-27 16:45:16 +01:00
|
|
|
return supplicant_check_secrets_needed(self, out_failure_reason);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2015-05-12 14:44:03 +02:00
|
|
|
wake_on_lan_enable(device);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
/* DCB and FCoE setup */
|
2018-10-22 13:06:27 +02:00
|
|
|
s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB);
|
2021-08-06 15:17:05 +02:00
|
|
|
if (!priv->stage2_ready_dcb && s_dcb) {
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
/* lldpad really really wants the carrier to be up */
|
2017-04-18 12:09:02 +02:00
|
|
|
if (nm_platform_link_is_connected(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device))) {
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
if (!dcb_enable(device)) {
|
2017-02-22 17:04:00 +01:00
|
|
|
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2014-08-02 15:14:26 +02:00
|
|
|
_LOGD(LOGD_DCB, "waiting for carrier (preenable up)");
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_CARRIER_PREENABLE_UP;
|
|
|
|
|
priv->dcb_timeout_id = g_timeout_add_seconds(4, dcb_carrier_timeout, device);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = TRUE;
|
2021-08-06 15:17:05 +02:00
|
|
|
return NM_ACT_STAGE_RETURN_POSTPONE;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
return NM_ACT_STAGE_RETURN_SUCCESS;
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
static guint32
|
|
|
|
|
get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force)
|
2009-08-17 15:35:02 -05:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device);
|
2020-11-12 21:58:13 +01:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
/* MTU only set for plain ethernet */
|
|
|
|
|
if (priv->ppp_data.ppp_mgr)
|
|
|
|
|
return 0;
|
2020-11-12 21:58:13 +01:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
return nm_device_get_configured_mtu_for_wired(device, out_source, out_force);
|
|
|
|
|
}
|
2009-08-17 15:35:02 -05:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
static void
|
|
|
|
|
act_stage3_ip_config(NMDevice *device, int addr_family)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
NMPppMgrState ppp_state;
|
2018-10-22 13:06:27 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (!priv->ppp_data.ppp_mgr)
|
|
|
|
|
return;
|
2009-08-17 15:35:02 -05:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
ppp_state = nm_ppp_mgr_get_state(priv->ppp_data.ppp_mgr);
|
2009-08-17 15:35:02 -05:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_assert(NM_IN_SET(ppp_state, NM_PPP_MGR_STATE_HAVE_IFINDEX, NM_PPP_MGR_STATE_HAVE_IP_CONFIG));
|
2009-08-17 15:35:02 -05:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (ppp_state < NM_PPP_MGR_STATE_HAVE_IP_CONFIG) {
|
|
|
|
|
nm_device_devip_set_state(device, AF_UNSPEC, NM_DEVICE_IP_STATE_PENDING, NULL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-03-07 Dan Williams <dcbw@redhat.com>
First pass of multiple active device support. Expect bugs.
* src/nm-ip4-config.c
src/nm-ip4-config.h
- (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove;
there are better ways to do this in the named manager
* src/nm-device.c
src/nm-device.h
- (nm_device_can_activate): return whether the device can activate a
connection right now; taking into account things like carrier state
and rfkill state
- (nm_device_get_best_auto_connection): renamed from
nm_device_get_best_connection
- (real_act_stage4_get_ip4_config): MTU stuff is now handled in the
device subclasses themselves, so that each device can override the
MTU from it's NMSetting subclass if needed
- (nm_device_set_ip4_config): set MTU when setting up routes and stuff
in NetworkManagerSystem.c, not here
* src/named-manager/nm-named-manager.c
src/named-manager/nm-named-manager.h
- (nm_named_manager_name_owner_changed,
nm_named_manager_dbus_connection_changed): fix for changes to
rewrite_resolv_conf()
- (compute_nameservers): don't need the NMNamedManager at all, remove
from parameter list
- (merge_one_ip4_config): new function; merge ip4 configs together
- (rewrite_resolv_conf): write out resolv.conf from all the stored
ip4 configs; the VPN config takes precedence, then the best
device config, then the rest of the configs
- (get_domain_for_config): take the NMNamedManager as an argument
to check whether the config is the VPN config
- (add_ip4_config_to_named): fixups for removal of the 'secondary'
attribute from ip4 configs
- (add_all_ip4_configs_to_named): add all the configs in priority order
- (remove_ip4_config_from_named): fix for changes to
get_domain_for_config()
- (nm_named_manager_add_ip4_config): assign the config to the right slot
based on its type; callers must pass in the type now
- (get_last_default_domain): remove, unused
- (nm_named_manager_remove_ip4_config): handle config slots correctly
* src/nm-device-802-11-wireless.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): handle MTU override
* src/nm-device-802-3-ethernet.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): new function; handle MTU override
* src/vpn-manager/nm-vpn-connection.c
- (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary'
attribute on the ip4 config
* src/NetworkManagerPolicy.c
- (nm_policy_auto_get_best_device): remove
- (nm_policy_device_change_check): remove
- (update_default_route): new function; set the default route via
the specified device
- (get_device_priority): new function; return the priority number of
a device type WRT which one should have the default route. Order is
(highest to lowest) wired, wireless, GSM, CDMA.
- (update_routing_and_dns): new function; determine which device should
have the default route, then update the routing table and DNS
- (maybe_auto_activate_device): new function; if a device is now
available for activation, find out what connection it would like to
activate and do it
- (schedule_activate_check): new function; if a device can be activated
now, schedule the activation. Each device may have only one
pending activation at a given time.
- (device_state_changed): if activation was canceled, try again,
possibly with another connection; if the device was activated,
update routing and DNS; if the device was deactivated, try again
with another connection
- (device_carrier_changed): if there is no carrier, deactivate the
device; otherwise schedule an activation check for the device
- (wireless_networks_changed): schedule an activation check for the
device
- (device_added): keep track of the signal handler IDs so they can
be removed when the device goes away
- (device_removed): remove any signal handlers that might be attached
to the device; update routing and DNS
- (schedule_activate_all): new function
- (connections_added, connection_added, connection_updated): when
connections change, schedule all devices for an activation check
- (connection_removed): when a device is deactivated because its
connection was removed, schedule another activation check for it
- (nm_policy_destroy): destroy pending activations and disconnect
all device signal handlers
* src/nm-manager.c
- (nm_manager_activate_device): if the device was already actived,
deactivate it
- (deactivate_old_device): remove
- (connection_added_default_handler, impl_manager_activate_device):
don't deactivate other devices when activating this one
* src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerSuSE.c
src/backends/NetworkManagerDebian.c
- (nm_system_get_mtu): remove; MTU should be provided through the
distro's system settings service plugin instead
- (nm_system_device_add_default_route_via_device): remove
- (nm_system_device_add_default_route_via_device_with_iface): remove
- (nm_system_device_replace_default_route): new function; call
generic implementation
* src/backends/NetworkManagerGeneric.c
src/backends/NetworkManagerGeneric.h
- (nm_generic_device_add_default_route_via_device,
nm_generic_device_add_default_route_via_device_with_iface): remove
- (nm_generic_device_replace_default_route): replace the default route
with the given route via some gateway
* src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
- (nm_system_device_set_from_ip4_config): let the policy handle updates
to routing and DNS; but set the MTU here
- (nm_system_vpn_device_set_from_ip4_config): set the route with the
ip_iface of the active device; use the standard MTU setting function
- (nm_system_set_mtu): remove
- (nm_system_device_set_mtu): consolidate MTU setting code in one place
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-07 19:41:32 +00:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
_ppp_mgr_stage3_maybe_ready(self);
|
2008-03-07 Dan Williams <dcbw@redhat.com>
First pass of multiple active device support. Expect bugs.
* src/nm-ip4-config.c
src/nm-ip4-config.h
- (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove;
there are better ways to do this in the named manager
* src/nm-device.c
src/nm-device.h
- (nm_device_can_activate): return whether the device can activate a
connection right now; taking into account things like carrier state
and rfkill state
- (nm_device_get_best_auto_connection): renamed from
nm_device_get_best_connection
- (real_act_stage4_get_ip4_config): MTU stuff is now handled in the
device subclasses themselves, so that each device can override the
MTU from it's NMSetting subclass if needed
- (nm_device_set_ip4_config): set MTU when setting up routes and stuff
in NetworkManagerSystem.c, not here
* src/named-manager/nm-named-manager.c
src/named-manager/nm-named-manager.h
- (nm_named_manager_name_owner_changed,
nm_named_manager_dbus_connection_changed): fix for changes to
rewrite_resolv_conf()
- (compute_nameservers): don't need the NMNamedManager at all, remove
from parameter list
- (merge_one_ip4_config): new function; merge ip4 configs together
- (rewrite_resolv_conf): write out resolv.conf from all the stored
ip4 configs; the VPN config takes precedence, then the best
device config, then the rest of the configs
- (get_domain_for_config): take the NMNamedManager as an argument
to check whether the config is the VPN config
- (add_ip4_config_to_named): fixups for removal of the 'secondary'
attribute from ip4 configs
- (add_all_ip4_configs_to_named): add all the configs in priority order
- (remove_ip4_config_from_named): fix for changes to
get_domain_for_config()
- (nm_named_manager_add_ip4_config): assign the config to the right slot
based on its type; callers must pass in the type now
- (get_last_default_domain): remove, unused
- (nm_named_manager_remove_ip4_config): handle config slots correctly
* src/nm-device-802-11-wireless.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): handle MTU override
* src/nm-device-802-3-ethernet.c
- (real_can_activate): new function
- (real_get_best_auto_connection): renamed from real_get_best_connection
- (real_act_stage4_get_ip4_config): new function; handle MTU override
* src/vpn-manager/nm-vpn-connection.c
- (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary'
attribute on the ip4 config
* src/NetworkManagerPolicy.c
- (nm_policy_auto_get_best_device): remove
- (nm_policy_device_change_check): remove
- (update_default_route): new function; set the default route via
the specified device
- (get_device_priority): new function; return the priority number of
a device type WRT which one should have the default route. Order is
(highest to lowest) wired, wireless, GSM, CDMA.
- (update_routing_and_dns): new function; determine which device should
have the default route, then update the routing table and DNS
- (maybe_auto_activate_device): new function; if a device is now
available for activation, find out what connection it would like to
activate and do it
- (schedule_activate_check): new function; if a device can be activated
now, schedule the activation. Each device may have only one
pending activation at a given time.
- (device_state_changed): if activation was canceled, try again,
possibly with another connection; if the device was activated,
update routing and DNS; if the device was deactivated, try again
with another connection
- (device_carrier_changed): if there is no carrier, deactivate the
device; otherwise schedule an activation check for the device
- (wireless_networks_changed): schedule an activation check for the
device
- (device_added): keep track of the signal handler IDs so they can
be removed when the device goes away
- (device_removed): remove any signal handlers that might be attached
to the device; update routing and DNS
- (schedule_activate_all): new function
- (connections_added, connection_added, connection_updated): when
connections change, schedule all devices for an activation check
- (connection_removed): when a device is deactivated because its
connection was removed, schedule another activation check for it
- (nm_policy_destroy): destroy pending activations and disconnect
all device signal handlers
* src/nm-manager.c
- (nm_manager_activate_device): if the device was already actived,
deactivate it
- (deactivate_old_device): remove
- (connection_added_default_handler, impl_manager_activate_device):
don't deactivate other devices when activating this one
* src/backends/NetworkManagerGentoo.c
src/backends/NetworkManagerFrugalware.c
src/backends/NetworkManagerPaldo.c
src/backends/NetworkManagerRedHat.c
src/backends/NetworkManagerSlackware.c
src/backends/NetworkManagerArch.c
src/backends/NetworkManagerSuSE.c
src/backends/NetworkManagerDebian.c
- (nm_system_get_mtu): remove; MTU should be provided through the
distro's system settings service plugin instead
- (nm_system_device_add_default_route_via_device): remove
- (nm_system_device_add_default_route_via_device_with_iface): remove
- (nm_system_device_replace_default_route): new function; call
generic implementation
* src/backends/NetworkManagerGeneric.c
src/backends/NetworkManagerGeneric.h
- (nm_generic_device_add_default_route_via_device,
nm_generic_device_add_default_route_via_device_with_iface): remove
- (nm_generic_device_replace_default_route): replace the default route
with the given route via some gateway
* src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
- (nm_system_device_set_from_ip4_config): let the policy handle updates
to routing and DNS; but set the MTU here
- (nm_system_vpn_device_set_from_ip4_config): set the route with the
ip_iface of the active device; use the standard MTU setting function
- (nm_system_set_mtu): remove
- (nm_system_device_set_mtu): consolidate MTU setting code in one place
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2008-03-07 19:41:32 +00:00
|
|
|
}
|
|
|
|
|
|
2008-03-11 16:37:41 +00:00
|
|
|
static void
|
2012-09-27 12:12:15 -04:00
|
|
|
deactivate(NMDevice *device)
|
2008-03-11 16:37:41 +00:00
|
|
|
{
|
2010-06-24 15:14:53 -07:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2013-10-04 16:56:34 -05:00
|
|
|
NMSettingDcb * s_dcb;
|
|
|
|
|
GError * error = NULL;
|
2021-02-01 13:51:18 +01:00
|
|
|
int ifindex;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_clear_g_source_inst(&priv->ppp_data.wait_source);
|
2019-11-08 08:36:41 +01:00
|
|
|
nm_clear_g_signal_handler(self, &priv->carrier_id);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
_ppp_mgr_cleanup(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2010-06-24 15:14:53 -07:00
|
|
|
supplicant_interface_release(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
priv->dcb_wait = DCB_WAIT_UNKNOWN;
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
2017-06-02 16:24:31 +02:00
|
|
|
priv->dcb_handle_carrier_changes = FALSE;
|
2021-08-06 15:17:05 +02:00
|
|
|
priv->stage2_ready_dcb = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-10-04 16:56:34 -05:00
|
|
|
/* Tear down DCB/FCoE if it was enabled */
|
2018-10-22 13:06:27 +02:00
|
|
|
s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB);
|
2013-10-04 16:56:34 -05:00
|
|
|
if (s_dcb) {
|
|
|
|
|
if (!nm_dcb_cleanup(nm_device_get_iface(device), &error)) {
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGW(LOGD_DEVICE | LOGD_PLATFORM, "failed to disable DCB/FCoE: %s", error->message);
|
2013-10-04 16:56:34 -05:00
|
|
|
g_clear_error(&error);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2013-10-04 16:56:34 -05:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-12-09 09:33:13 +01:00
|
|
|
/* Set last PPPoE connection time */
|
2016-02-11 21:33:15 +01:00
|
|
|
if (nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE))
|
2021-08-06 15:17:05 +02:00
|
|
|
priv->ppp_data.last_pppoe_time_msec = nm_utils_get_monotonic_timestamp_msec();
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-02-01 13:51:18 +01:00
|
|
|
ifindex = nm_device_get_ifindex(device);
|
|
|
|
|
if (ifindex > 0 && priv->ethtool_prev_set) {
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
priv->ethtool_prev_set = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
_LOGD(LOGD_DEVICE,
|
|
|
|
|
"set-link: reset %snegotiation (%u Mbit, %s duplex)",
|
|
|
|
|
priv->ethtool_prev_autoneg ? "auto-" : "static ",
|
|
|
|
|
priv->ethtool_prev_speed,
|
|
|
|
|
nm_platform_link_duplex_type_to_string(priv->ethtool_prev_duplex));
|
|
|
|
|
if (!nm_platform_ethtool_set_link_settings(nm_device_get_platform(device),
|
2021-02-01 13:51:18 +01:00
|
|
|
ifindex,
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
priv->ethtool_prev_autoneg,
|
|
|
|
|
priv->ethtool_prev_speed,
|
|
|
|
|
priv->ethtool_prev_duplex)) {
|
|
|
|
|
_LOGW(LOGD_DEVICE, "set-link: failure to reset link negotiation");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-03-11 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
static gboolean
|
2012-09-27 12:12:15 -04:00
|
|
|
complete_connection(NMDevice * device,
|
|
|
|
|
NMConnection * connection,
|
|
|
|
|
const char * specific_object,
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
NMConnection *const *existing_connections,
|
2012-09-27 12:12:15 -04:00
|
|
|
GError ** error)
|
2011-01-10 23:39:12 -06:00
|
|
|
{
|
|
|
|
|
NMSettingWired *s_wired;
|
libnm, core, cli, tui: fix the capitalization of various types
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
2014-06-26 13:44:36 -04:00
|
|
|
NMSettingPppoe *s_pppoe;
|
2011-01-10 23:39:12 -06:00
|
|
|
|
2021-01-14 14:03:36 +01:00
|
|
|
if (nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_VETH_SETTING_NAME)) {
|
|
|
|
|
NMSettingVeth *s_veth;
|
|
|
|
|
const char * peer_name = NULL;
|
|
|
|
|
const char * con_peer_name = NULL;
|
|
|
|
|
int ifindex;
|
|
|
|
|
|
|
|
|
|
nm_utils_complete_generic(nm_device_get_platform(device),
|
|
|
|
|
connection,
|
|
|
|
|
NM_SETTING_VETH_SETTING_NAME,
|
|
|
|
|
existing_connections,
|
|
|
|
|
NULL,
|
|
|
|
|
_("Veth connection"),
|
|
|
|
|
"veth",
|
|
|
|
|
NULL,
|
|
|
|
|
TRUE);
|
|
|
|
|
|
2021-08-20 18:40:21 +08:00
|
|
|
s_veth = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VETH);
|
2021-01-14 14:03:36 +01:00
|
|
|
|
|
|
|
|
ifindex = nm_device_get_ip_ifindex(device);
|
|
|
|
|
if (ifindex > 0) {
|
|
|
|
|
const NMPlatformLink *pllink;
|
|
|
|
|
|
|
|
|
|
pllink = nm_platform_link_get(nm_device_get_platform(device), ifindex);
|
|
|
|
|
if (pllink && pllink->type == NM_LINK_TYPE_VETH && pllink->parent > 0) {
|
|
|
|
|
pllink = nm_platform_link_get(nm_device_get_platform(device), pllink->parent);
|
|
|
|
|
|
|
|
|
|
if (pllink && pllink->type == NM_LINK_TYPE_VETH) {
|
|
|
|
|
peer_name = pllink->name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!peer_name) {
|
|
|
|
|
nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "cannot find peer for veth device");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
con_peer_name = nm_setting_veth_get_peer(s_veth);
|
|
|
|
|
if (con_peer_name) {
|
|
|
|
|
nm_utils_error_set(error,
|
|
|
|
|
NM_UTILS_ERROR_UNKNOWN,
|
|
|
|
|
"mismatching veth peer \"%s\"",
|
|
|
|
|
con_peer_name);
|
|
|
|
|
return FALSE;
|
|
|
|
|
} else
|
|
|
|
|
g_object_set(s_veth, NM_SETTING_VETH_PEER, peer_name, NULL);
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-05 12:27:47 +01:00
|
|
|
s_pppoe = nm_connection_get_setting_pppoe(connection);
|
2011-01-10 23:39:12 -06:00
|
|
|
|
|
|
|
|
/* We can't telepathically figure out the service name or username, so if
|
|
|
|
|
* those weren't given, we can't complete the connection.
|
|
|
|
|
*/
|
|
|
|
|
if (s_pppoe && !nm_setting_verify(NM_SETTING(s_pppoe), NULL, error))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2021-08-20 18:40:21 +08:00
|
|
|
s_wired = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRED);
|
2019-05-07 10:21:04 +02:00
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
/* Default to an ethernet-only connection, but if a PPPoE setting was given
|
|
|
|
|
* then PPPoE should be our connection type.
|
|
|
|
|
*/
|
2017-04-18 12:09:02 +02:00
|
|
|
nm_utils_complete_generic(
|
|
|
|
|
nm_device_get_platform(device),
|
2016-03-08 13:57:20 +01:00
|
|
|
connection,
|
2011-03-28 10:42:19 -05:00
|
|
|
s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME,
|
2011-01-13 13:28:52 -06:00
|
|
|
existing_connections,
|
2011-02-25 11:58:16 -06:00
|
|
|
NULL,
|
2014-08-25 16:21:59 +02:00
|
|
|
s_pppoe ? _("PPPoE connection") : _("Wired connection"),
|
2014-08-05 17:11:57 -04:00
|
|
|
NULL,
|
2019-05-07 10:21:04 +02:00
|
|
|
nm_setting_wired_get_mac_address(s_wired) ? NULL : nm_device_get_iface(device),
|
2011-02-25 11:58:16 -06:00
|
|
|
s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2011-01-10 23:39:12 -06:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
static NMConnection *
|
|
|
|
|
new_default_connection(NMDevice *self)
|
|
|
|
|
{
|
|
|
|
|
NMConnection * connection;
|
2016-05-16 19:01:37 +02:00
|
|
|
NMSettingsConnection *const *connections;
|
2014-09-08 16:11:51 -05:00
|
|
|
NMSetting * setting;
|
settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).
NMSettingsConnection does a lot of things already:
1) it "is-a" NMDBusObject and exports the API of a connection profile
on D-Bus
2) it interacts with NMSettings and contains functionality
for tracking the profiles.
3) it is the base-class of types like NMSKeyfileConnection and
NMIfcfgConnection. These handle how the profile is persisted
on disk.
4) it implements NMConnection interface, to itself track the
settings of the profile.
3) and 4) would be better implemented via delegation than inheritance.
Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.
Advantages:
- by delegating, there is a clearer separation of what
NMSettingsConnection does. For example, in C we often required
casts from NMSettingsConnection to NMConnection. NMConnection
is a very trivial object with very little logic. When we have
a NMConnection instance at hand, it's good to know that it is
*only* that simple instead of also being an entire
NMSettingsConnection instance.
The main purpose of this patch is to simplify the code by separating
the NMConnection from the NMSettingsConnection. We should generally
be aware whether we handle a NMSettingsConnection or a trivial
NMConnection instance. Now, because NMSettingsConnection no longer
"is-a" NMConnection, this distinction is apparent.
- NMConnection is implemented as an interface and we create
NMSimpleConnection instances whenever we need a real instance.
In GLib, interfaces have a performance overhead, that we needlessly
pay all the time. With this change, we no longer require
NMConnection to be an interface. Thus, in the future we could compile
a version of libnm-core for the daemon, where NMConnection is not an
interface but a GObject implementation akin to NMSimpleConnection.
- In the previous implementation, we cannot treat NMConnection immutable
and copy-on-write.
For example, when NMDevice needs a snapshot of the activated
profile as applied-connection, all it can do is clone the entire
NMSettingsConnection as a NMSimpleConnection.
Likewise, when we get a NMConnection instance and want to keep
a reference to it, we cannot do that, because we never know
who also references and modifies the instance.
By separating NMSettingsConnection we could in the future have
NMConnection immutable and copy-on-write, to avoid all unnecessary
clones.
2018-08-11 11:08:17 +02:00
|
|
|
gs_unref_hashtable GHashTable *existing_ids = NULL;
|
2018-04-19 14:05:52 +02:00
|
|
|
struct udev_device * dev;
|
2016-06-15 17:19:41 +02:00
|
|
|
const char * perm_hw_addr;
|
2019-05-07 11:03:19 +02:00
|
|
|
const char * iface;
|
2018-04-19 14:05:52 +02:00
|
|
|
const char * uprop = "0";
|
2016-04-25 21:27:10 +02:00
|
|
|
gs_free char * defname = NULL;
|
|
|
|
|
gs_free char * uuid = NULL;
|
settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).
NMSettingsConnection does a lot of things already:
1) it "is-a" NMDBusObject and exports the API of a connection profile
on D-Bus
2) it interacts with NMSettings and contains functionality
for tracking the profiles.
3) it is the base-class of types like NMSKeyfileConnection and
NMIfcfgConnection. These handle how the profile is persisted
on disk.
4) it implements NMConnection interface, to itself track the
settings of the profile.
3) and 4) would be better implemented via delegation than inheritance.
Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.
Advantages:
- by delegating, there is a clearer separation of what
NMSettingsConnection does. For example, in C we often required
casts from NMSettingsConnection to NMConnection. NMConnection
is a very trivial object with very little logic. When we have
a NMConnection instance at hand, it's good to know that it is
*only* that simple instead of also being an entire
NMSettingsConnection instance.
The main purpose of this patch is to simplify the code by separating
the NMConnection from the NMSettingsConnection. We should generally
be aware whether we handle a NMSettingsConnection or a trivial
NMConnection instance. Now, because NMSettingsConnection no longer
"is-a" NMConnection, this distinction is apparent.
- NMConnection is implemented as an interface and we create
NMSimpleConnection instances whenever we need a real instance.
In GLib, interfaces have a performance overhead, that we needlessly
pay all the time. With this change, we no longer require
NMConnection to be an interface. Thus, in the future we could compile
a version of libnm-core for the daemon, where NMConnection is not an
interface but a GObject implementation akin to NMSimpleConnection.
- In the previous implementation, we cannot treat NMConnection immutable
and copy-on-write.
For example, when NMDevice needs a snapshot of the activated
profile as applied-connection, all it can do is clone the entire
NMSettingsConnection as a NMSimpleConnection.
Likewise, when we get a NMConnection instance and want to keep
a reference to it, we cannot do that, because we never know
who also references and modifies the instance.
By separating NMSettingsConnection we could in the future have
NMConnection immutable and copy-on-write, to avoid all unnecessary
clones.
2018-08-11 11:08:17 +02:00
|
|
|
guint i, n_connections;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-10-13 18:52:12 +02:00
|
|
|
perm_hw_addr = nm_device_get_permanent_hw_address(self);
|
2019-05-07 11:03:19 +02:00
|
|
|
iface = nm_device_get_iface(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
connection = nm_simple_connection_new();
|
|
|
|
|
setting = nm_setting_connection_new();
|
|
|
|
|
nm_connection_add_setting(connection, setting);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).
NMSettingsConnection does a lot of things already:
1) it "is-a" NMDBusObject and exports the API of a connection profile
on D-Bus
2) it interacts with NMSettings and contains functionality
for tracking the profiles.
3) it is the base-class of types like NMSKeyfileConnection and
NMIfcfgConnection. These handle how the profile is persisted
on disk.
4) it implements NMConnection interface, to itself track the
settings of the profile.
3) and 4) would be better implemented via delegation than inheritance.
Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.
Advantages:
- by delegating, there is a clearer separation of what
NMSettingsConnection does. For example, in C we often required
casts from NMSettingsConnection to NMConnection. NMConnection
is a very trivial object with very little logic. When we have
a NMConnection instance at hand, it's good to know that it is
*only* that simple instead of also being an entire
NMSettingsConnection instance.
The main purpose of this patch is to simplify the code by separating
the NMConnection from the NMSettingsConnection. We should generally
be aware whether we handle a NMSettingsConnection or a trivial
NMConnection instance. Now, because NMSettingsConnection no longer
"is-a" NMConnection, this distinction is apparent.
- NMConnection is implemented as an interface and we create
NMSimpleConnection instances whenever we need a real instance.
In GLib, interfaces have a performance overhead, that we needlessly
pay all the time. With this change, we no longer require
NMConnection to be an interface. Thus, in the future we could compile
a version of libnm-core for the daemon, where NMConnection is not an
interface but a GObject implementation akin to NMSimpleConnection.
- In the previous implementation, we cannot treat NMConnection immutable
and copy-on-write.
For example, when NMDevice needs a snapshot of the activated
profile as applied-connection, all it can do is clone the entire
NMSettingsConnection as a NMSimpleConnection.
Likewise, when we get a NMConnection instance and want to keep
a reference to it, we cannot do that, because we never know
who also references and modifies the instance.
By separating NMSettingsConnection we could in the future have
NMConnection immutable and copy-on-write, to avoid all unnecessary
clones.
2018-08-11 11:08:17 +02:00
|
|
|
connections = nm_settings_get_connections(nm_device_get_settings(self), &n_connections);
|
|
|
|
|
if (n_connections > 0) {
|
|
|
|
|
existing_ids = g_hash_table_new(nm_str_hash, g_str_equal);
|
|
|
|
|
for (i = 0; i < n_connections; i++)
|
|
|
|
|
g_hash_table_add(existing_ids, (char *) nm_settings_connection_get_id(connections[i]));
|
|
|
|
|
}
|
|
|
|
|
defname = nm_device_ethernet_utils_get_default_wired_name(existing_ids);
|
2016-04-25 21:27:10 +02:00
|
|
|
if (!defname)
|
|
|
|
|
return NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-04-25 21:27:10 +02:00
|
|
|
/* Create a stable UUID. The UUID is also the Network_ID for stable-privacy addr-gen-mode,
|
|
|
|
|
* thus when it changes we will also generate different IPv6 addresses. */
|
2021-05-02 21:32:31 +02:00
|
|
|
uuid = nm_uuid_generate_from_strings("default-wired",
|
|
|
|
|
nm_utils_machine_id_str(),
|
|
|
|
|
defname,
|
|
|
|
|
perm_hw_addr ?: iface,
|
|
|
|
|
NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
g_object_set(setting,
|
|
|
|
|
NM_SETTING_CONNECTION_ID,
|
|
|
|
|
defname,
|
|
|
|
|
NM_SETTING_CONNECTION_TYPE,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT,
|
|
|
|
|
TRUE,
|
2015-08-31 16:32:33 +02:00
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN,
|
2014-09-08 16:11:51 -05:00
|
|
|
NM_SETTING_CONNECTION_UUID,
|
|
|
|
|
uuid,
|
|
|
|
|
NM_SETTING_CONNECTION_TIMESTAMP,
|
|
|
|
|
(guint64) time(NULL),
|
2019-05-07 11:03:19 +02:00
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME,
|
|
|
|
|
iface,
|
2014-09-08 16:11:51 -05:00
|
|
|
NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-04-19 14:05:52 +02:00
|
|
|
/* Check if we should create a Link-Local only connection */
|
|
|
|
|
dev = nm_platform_link_get_udev_device(nm_device_get_platform(NM_DEVICE(self)),
|
|
|
|
|
nm_device_get_ip_ifindex(self));
|
|
|
|
|
if (dev)
|
|
|
|
|
uprop = udev_device_get_property_value(dev, "NM_AUTO_DEFAULT_LINK_LOCAL_ONLY");
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-04-23 14:40:14 +02:00
|
|
|
if (_nm_utils_ascii_str_to_bool(uprop, FALSE)) {
|
2018-04-19 14:05:52 +02:00
|
|
|
setting = nm_setting_ip4_config_new();
|
|
|
|
|
g_object_set(setting,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
|
|
|
|
|
NULL);
|
|
|
|
|
nm_connection_add_setting(connection, setting);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-04-19 14:05:52 +02:00
|
|
|
setting = nm_setting_ip6_config_new();
|
|
|
|
|
g_object_set(setting,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL,
|
|
|
|
|
TRUE,
|
|
|
|
|
NULL);
|
|
|
|
|
nm_connection_add_setting(connection, setting);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-09-08 16:11:51 -05:00
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
core: refactor evaluation of device's match-spec
Previously, we would have different functions like
- nm_match_spec_device_type()
- nm_match_spec_hwaddr()
- nm_match_spec_s390_subchannels()
- nm_match_spec_interface_name()
which all would handle one type of match-spec.
So, to get the overall result whether the arguments
match or not, nm_device_spec_match_list() had to stich
them together and iterate the list multiple times.
Refactor the code to have one nm_match_spec_device()
function that gets all relevant paramters.
The upside is:
- the logic how to evaluate the match-spec is all at one place
(match_device_eval()) instead of spread over multiple
functions.
- It requires iterating the list at most twice. Twice, because
we do a fast pre-search for "*".
One downside could be, that we have to pass all 4 arguments
for the evaluation, even if the might no be needed. That is,
because "nm-core-utils.c" shall be independend from NMDevice, it
cannot receive a device instance to get the parameters as needed.
As we would add new match-types, the argument list would grow.
However, all arguments are cached and fetching them from the
device's private data is very cheap.
(cherry picked from commit b957403efd53ff7d826ac7a4f80487032c03824b)
2017-01-20 19:50:25 +01:00
|
|
|
static const char *
|
|
|
|
|
get_s390_subchannels(NMDevice *device)
|
2009-06-11 00:39:12 -04:00
|
|
|
{
|
core: refactor evaluation of device's match-spec
Previously, we would have different functions like
- nm_match_spec_device_type()
- nm_match_spec_hwaddr()
- nm_match_spec_s390_subchannels()
- nm_match_spec_interface_name()
which all would handle one type of match-spec.
So, to get the overall result whether the arguments
match or not, nm_device_spec_match_list() had to stich
them together and iterate the list multiple times.
Refactor the code to have one nm_match_spec_device()
function that gets all relevant paramters.
The upside is:
- the logic how to evaluate the match-spec is all at one place
(match_device_eval()) instead of spread over multiple
functions.
- It requires iterating the list at most twice. Twice, because
we do a fast pre-search for "*".
One downside could be, that we have to pass all 4 arguments
for the evaluation, even if the might no be needed. That is,
because "nm-core-utils.c" shall be independend from NMDevice, it
cannot receive a device instance to get the parameters as needed.
As we would add new match-types, the argument list would grow.
However, all arguments are cached and fetching them from the
device's private data is very cheap.
(cherry picked from commit b957403efd53ff7d826ac7a4f80487032c03824b)
2017-01-20 19:50:25 +01:00
|
|
|
nm_assert(NM_IS_DEVICE_ETHERNET(device));
|
2009-06-11 00:39:12 -04:00
|
|
|
|
2020-02-14 10:50:25 +01:00
|
|
|
return NM_DEVICE_ETHERNET_GET_PRIVATE(device)->subchannels;
|
2009-06-11 00:39:12 -04:00
|
|
|
}
|
|
|
|
|
|
2013-08-22 15:03:30 +02:00
|
|
|
static void
|
|
|
|
|
update_connection(NMDevice *device, NMConnection *connection)
|
2009-08-03 17:15:03 -04:00
|
|
|
{
|
2021-08-20 18:40:21 +08:00
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device);
|
|
|
|
|
NMSettingWired *s_wired = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRED);
|
|
|
|
|
gboolean perm_hw_addr_is_fake;
|
|
|
|
|
const char * perm_hw_addr;
|
|
|
|
|
const char * mac = nm_device_get_hw_address(device);
|
|
|
|
|
const char * mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
|
|
|
|
|
GHashTableIter iter;
|
|
|
|
|
const char * key;
|
|
|
|
|
const char * value;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-15 20:07:45 +01:00
|
|
|
g_object_set(nm_connection_get_setting_connection(connection),
|
|
|
|
|
NM_SETTING_CONNECTION_TYPE,
|
|
|
|
|
nm_connection_get_setting_pppoe(connection) ? NM_SETTING_PPPOE_SETTING_NAME
|
|
|
|
|
: NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-11-06 20:20:58 -06:00
|
|
|
/* If the device reports a permanent address, use that for the MAC address
|
|
|
|
|
* and the current MAC, if different, is the cloned MAC.
|
|
|
|
|
*/
|
2016-10-24 12:50:17 +02:00
|
|
|
perm_hw_addr = nm_device_get_permanent_hw_address_full(device, TRUE, &perm_hw_addr_is_fake);
|
2016-10-13 18:52:12 +02:00
|
|
|
if (perm_hw_addr && !perm_hw_addr_is_fake) {
|
2014-10-03 17:37:26 -05:00
|
|
|
g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-11-06 20:20:58 -06:00
|
|
|
mac_prop = NULL;
|
2014-10-03 17:37:26 -05:00
|
|
|
if (mac && !nm_utils_hwaddr_matches(perm_hw_addr, -1, mac, -1))
|
2013-11-06 20:20:58 -06:00
|
|
|
mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-07-30 10:57:45 -04:00
|
|
|
if (mac_prop && mac && nm_utils_hwaddr_valid(mac, ETH_ALEN))
|
|
|
|
|
g_object_set(s_wired, mac_prop, mac, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-08-22 15:03:30 +02:00
|
|
|
/* We don't set the MTU as we don't know whether it was set explicitly */
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:25:09 +02:00
|
|
|
/* s390 */
|
2015-09-18 22:49:13 +02:00
|
|
|
if (priv->subchannels_dbus)
|
|
|
|
|
g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, priv->subchannels_dbus, NULL);
|
2014-04-07 15:25:09 +02:00
|
|
|
if (priv->s390_nettype)
|
|
|
|
|
g_object_set(s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-04-24 09:24:15 +02:00
|
|
|
_nm_setting_wired_clear_s390_options(s_wired);
|
2014-04-07 15:25:09 +02:00
|
|
|
g_hash_table_iter_init(&iter, priv->s390_options);
|
2021-03-15 20:28:30 +01:00
|
|
|
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value))
|
|
|
|
|
nm_setting_wired_add_s390_option(s_wired, key, value);
|
2009-08-03 17:15:03 -04:00
|
|
|
}
|
|
|
|
|
|
2013-05-07 16:18:19 -04:00
|
|
|
static void
|
2017-06-02 16:30:43 +02:00
|
|
|
link_speed_update(NMDevice *device)
|
2013-05-07 16:18:19 -04:00
|
|
|
{
|
2014-08-02 15:14:26 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2013-05-07 16:18:19 -04:00
|
|
|
guint32 speed;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-04-18 12:09:02 +02:00
|
|
|
if (!nm_platform_ethtool_get_link_settings(nm_device_get_platform(device),
|
|
|
|
|
nm_device_get_ifindex(device),
|
|
|
|
|
NULL,
|
|
|
|
|
&speed,
|
|
|
|
|
NULL))
|
2013-05-07 16:18:19 -04:00
|
|
|
return;
|
|
|
|
|
if (priv->speed == speed)
|
|
|
|
|
return;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2013-05-07 16:18:19 -04:00
|
|
|
priv->speed = speed;
|
2016-10-06 21:28:40 +02:00
|
|
|
_LOGD(LOGD_PLATFORM | LOGD_ETHER, "speed is now %d Mb/s", speed);
|
2017-06-02 16:30:43 +02:00
|
|
|
_notify(self, PROP_SPEED);
|
2013-05-07 16:18:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2017-05-12 16:17:18 +02:00
|
|
|
carrier_changed_notify(NMDevice *device, gboolean carrier)
|
2013-05-07 16:18:19 -04:00
|
|
|
{
|
2017-06-02 16:24:31 +02:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
if (priv->dcb_handle_carrier_changes) {
|
|
|
|
|
nm_assert(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG);
|
|
|
|
|
|
|
|
|
|
if (priv->dcb_timeout_id) {
|
|
|
|
|
_LOGD(LOGD_DCB, "carrier_changed() calling dcb_state()");
|
|
|
|
|
dcb_state(device, FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-07 16:18:19 -04:00
|
|
|
if (carrier)
|
2017-06-02 16:30:43 +02:00
|
|
|
link_speed_update(device);
|
2017-06-02 16:24:31 +02:00
|
|
|
|
2017-05-12 16:17:18 +02:00
|
|
|
NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->carrier_changed_notify(device, carrier);
|
2013-05-07 16:18:19 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-13 16:29:37 -05:00
|
|
|
static void
|
2017-01-02 16:06:51 +01:00
|
|
|
link_changed(NMDevice *device, const NMPlatformLink *pllink)
|
2015-04-13 16:29:37 -05:00
|
|
|
{
|
2017-01-02 15:38:24 +01:00
|
|
|
NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->link_changed(device, pllink);
|
2020-11-12 21:58:13 +01:00
|
|
|
if (!NM_IS_DEVICE_VETH(device) && pllink->initialized)
|
2016-07-05 14:14:49 +02:00
|
|
|
_update_s390_subchannels((NMDeviceEthernet *) device);
|
2015-12-13 22:09:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
|
|
|
|
|
{
|
|
|
|
|
if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->is_available(device, flags))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return !!nm_device_get_initial_hw_address(device);
|
2015-04-13 16:29:37 -05:00
|
|
|
}
|
|
|
|
|
|
2017-03-06 17:47:47 +01:00
|
|
|
static gboolean
|
|
|
|
|
can_reapply_change(NMDevice * device,
|
|
|
|
|
const char *setting_name,
|
|
|
|
|
NMSetting * s_old,
|
|
|
|
|
NMSetting * s_new,
|
|
|
|
|
GHashTable *diffs,
|
|
|
|
|
GError ** error)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceClass *device_class;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-03-06 17:47:47 +01:00
|
|
|
/* Only handle wired setting here, delegate other settings to parent class */
|
|
|
|
|
if (nm_streq(setting_name, NM_SETTING_WIRED_SETTING_NAME)) {
|
|
|
|
|
return nm_device_hash_check_invalid_keys(
|
|
|
|
|
diffs,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
error,
|
2017-03-07 10:27:11 +01:00
|
|
|
NM_SETTING_WIRED_MTU, /* reapplied with IP config */
|
2017-03-06 17:47:47 +01:00
|
|
|
NM_SETTING_WIRED_SPEED,
|
|
|
|
|
NM_SETTING_WIRED_DUPLEX,
|
|
|
|
|
NM_SETTING_WIRED_AUTO_NEGOTIATE,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN,
|
|
|
|
|
NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-03-06 17:47:47 +01:00
|
|
|
device_class = NM_DEVICE_CLASS(nm_device_ethernet_parent_class);
|
|
|
|
|
return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device);
|
2019-10-22 16:55:55 +02:00
|
|
|
NMDeviceState state = nm_device_get_state(device);
|
2017-03-06 17:47:47 +01:00
|
|
|
|
|
|
|
|
NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->reapply_connection(device, con_old, con_new);
|
|
|
|
|
|
|
|
|
|
_LOGD(LOGD_DEVICE, "reapplying wired settings");
|
|
|
|
|
|
2019-10-22 16:55:55 +02:00
|
|
|
if (state >= NM_DEVICE_STATE_PREPARE)
|
|
|
|
|
link_negotiation_set(device);
|
|
|
|
|
if (state >= NM_DEVICE_STATE_CONFIG)
|
|
|
|
|
wake_on_lan_enable(device);
|
2017-03-06 17:47:47 +01:00
|
|
|
}
|
|
|
|
|
|
2007-09-13 18:09:28 +00:00
|
|
|
static void
|
2009-07-07 14:39:08 -04:00
|
|
|
dispose(GObject *object)
|
2007-09-13 18:09:28 +00:00
|
|
|
{
|
2008-09-25 10:02:28 +00:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2007-09-13 18:09:28 +00:00
|
|
|
|
2016-12-16 14:12:21 +01:00
|
|
|
wired_secrets_cancel(self);
|
|
|
|
|
|
2016-01-19 15:42:24 +01:00
|
|
|
supplicant_interface_release(self);
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_clear_g_source_inst(&priv->ppp_data.wait_source);
|
2013-12-09 09:33:13 +01:00
|
|
|
|
2016-07-05 13:26:00 +02:00
|
|
|
nm_clear_g_source(&priv->dcb_timeout_id);
|
dcb: separate DCB enable/disable and wait for carrier changes (rh #799241) (rh #1081991)
Non-git-master versions of lldpad refuse to touch a device that doesn't
have a carrier. And when enabling/disabling DCB, the kernel driver will
reconfigure itself and may turn carrier off for a few seconds. So we
must ensure that before enabling/disabling DCB, the carrier is already
on. Next we must ensure that *after* enabling/disabling DCB, the
carrier is back on before doing further DCB setup.
There's a race condition between enabling/disabling DCB and receiving
the carrier event in NetworkManager that has to be handled carefully.
Because the carrier may not yet be down after the dcbtool call to
enable/disable DCB returns, we need to wait for a couple seconds for
the carrier to go down, and then again for it to come back up.
Otherwise we might see the still-on carrier, proceed with DCB setup,
and the carrier finally goes down halfway through the setup, which
will fail the operations with "DCB not enabled, link down, or DCB
not supported" errors from lldpad.
2014-03-27 13:49:50 -05:00
|
|
|
|
2019-11-08 08:36:41 +01:00
|
|
|
nm_clear_g_signal_handler(self, &priv->carrier_id);
|
|
|
|
|
|
2008-06-10 15:54:23 +00:00
|
|
|
G_OBJECT_CLASS(nm_device_ethernet_parent_class)->dispose(object);
|
2007-09-13 18:09:28 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-07 15:34:10 +02:00
|
|
|
static void
|
|
|
|
|
finalize(GObject *object)
|
|
|
|
|
{
|
|
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:34:10 +02:00
|
|
|
g_clear_object(&priv->supplicant.mgr);
|
|
|
|
|
g_free(priv->subchan1);
|
|
|
|
|
g_free(priv->subchan2);
|
|
|
|
|
g_free(priv->subchan3);
|
|
|
|
|
g_free(priv->subchannels);
|
2015-09-18 22:49:13 +02:00
|
|
|
g_strfreev(priv->subchannels_dbus);
|
2014-04-07 15:34:10 +02:00
|
|
|
g_free(priv->s390_nettype);
|
|
|
|
|
g_hash_table_destroy(priv->s390_options);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2014-04-07 15:34:10 +02:00
|
|
|
G_OBJECT_CLASS(nm_device_ethernet_parent_class)->finalize(object);
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-12 09:23:43 +00:00
|
|
|
static void
|
|
|
|
|
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
2009-09-14 12:54:09 -07:00
|
|
|
NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object);
|
|
|
|
|
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2007-02-12 09:23:43 +00:00
|
|
|
switch (prop_id) {
|
|
|
|
|
case PROP_SPEED:
|
2013-05-07 16:18:19 -04:00
|
|
|
g_value_set_uint(value, priv->speed);
|
2007-02-12 09:23:43 +00:00
|
|
|
break;
|
2015-09-18 22:49:13 +02:00
|
|
|
case PROP_S390_SUBCHANNELS:
|
|
|
|
|
g_value_set_boxed(value, priv->subchannels_dbus);
|
|
|
|
|
break;
|
2007-02-12 09:23:43 +00:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-11 00:39:12 -04:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-12-31 08:21:24 +00:00
|
|
|
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
static const NMDBusInterfaceInfoExtended interface_info_device_wired = {
|
|
|
|
|
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
|
|
|
|
|
NM_DBUS_INTERFACE_DEVICE_WIRED,
|
|
|
|
|
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
|
2021-05-12 18:18:57 +02:00
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PermHwAddress",
|
|
|
|
|
"s",
|
|
|
|
|
NM_DEVICE_PERM_HW_ADDRESS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Speed", "u", NM_DEVICE_ETHERNET_SPEED),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("S390Subchannels",
|
|
|
|
|
"as",
|
|
|
|
|
NM_DEVICE_ETHERNET_S390_SUBCHANNELS),
|
|
|
|
|
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ),
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
};
|
|
|
|
|
|
2005-12-31 08:21:24 +00:00
|
|
|
static void
|
2008-06-10 15:54:23 +00:00
|
|
|
nm_device_ethernet_class_init(NMDeviceEthernetClass *klass)
|
2005-12-31 08:21:24 +00:00
|
|
|
{
|
|
|
|
|
GObjectClass * object_class = G_OBJECT_CLASS(klass);
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
|
2018-07-10 07:45:35 +02:00
|
|
|
NMDeviceClass * device_class = NM_DEVICE_CLASS(klass);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2008-06-10 15:54:23 +00:00
|
|
|
g_type_class_add_private(object_class, sizeof(NMDeviceEthernetPrivate));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2009-07-07 14:39:08 -04:00
|
|
|
object_class->dispose = dispose;
|
2014-04-07 15:34:10 +02:00
|
|
|
object_class->finalize = finalize;
|
2007-02-12 09:23:43 +00:00
|
|
|
object_class->get_property = get_property;
|
2009-06-11 00:39:12 -04:00
|
|
|
object_class->set_property = set_property;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.
Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.
This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.
This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.
Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.
Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.
Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.
Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.
Numbers (for contrib/rpm --without debug on x86_64):
- the patch changes the code size of NetworkManager by
- 2809360 bytes
+ 2537528 bytes (-9.7%)
- Runtime measurements are harder because there is a large variance
during testing. In other words, the numbers are not reproducible.
Currently, the implementation performs no caching of GVariants at all,
but it would be rather simple to add it, if that turns out to be
useful.
Anyway, without strong claim, it seems that the new form tends to
perform slightly better. That would be no surprise.
$ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .; done)
- real 1m39.355s
+ real 1m37.432s
$ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
- real 0m26.843s
+ real 0m25.281s
- Regarding RSS size, just looking at the processes in similar
conditions, doesn't give a large difference. On my system they
consume about 19MB RSS. It seems that the new version has a
slightly smaller RSS size.
- 19356 RSS
+ 18660 RSS
2018-02-26 13:51:52 +01:00
|
|
|
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_wired);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-10 09:26:42 +02:00
|
|
|
device_class->connection_type_supported = NM_SETTING_WIRED_SETTING_NAME;
|
|
|
|
|
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_ETHERNET);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-10 07:45:35 +02:00
|
|
|
device_class->get_generic_capabilities = get_generic_capabilities;
|
|
|
|
|
device_class->check_connection_compatible = check_connection_compatible;
|
|
|
|
|
device_class->complete_connection = complete_connection;
|
|
|
|
|
device_class->new_default_connection = new_default_connection;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
device: reset original autoneg/speed/duplex setting on deactivate
The autoneg/speed ethtool settings are important. If they are wrong,
the device might not get any carrier. Having no carrier means that
you may be unable to activate a profile (because depending on
configuration, carrier is required to activate a profile).
Since activating profiles are the means to configure the link settings
in NetworkManager, and activating a profile can be hampered by wrong link
settings, it's important to reset the "correct" settings, when deactivating
a profile.
"Correct" in this case means to restore the settings that were present
before NM changed the settings. Presumably, these are the right once.
Beyond that, in the future it might make sense to support configuring
the default link settings per device. So that NM will always restore a
defined, configured, working state. The problem is that per-device
settings currently are only available via NetworkManager.conf, which
is rather inflexible.
Also, when you restart NetworkManager service, it leaves the interface
up but forgets the previous setting. That possibly could be fixed by
persisting the previous link state in /run. However, it's not
implemented yet.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/356
https://bugzilla.redhat.com/show_bug.cgi?id=1807171
2020-05-27 13:50:40 +02:00
|
|
|
device_class->act_stage1_prepare_also_for_external_or_assume = TRUE;
|
2018-07-10 07:45:35 +02:00
|
|
|
device_class->act_stage1_prepare = act_stage1_prepare;
|
2019-08-22 09:57:55 +02:00
|
|
|
device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE;
|
2018-07-10 07:45:35 +02:00
|
|
|
device_class->act_stage2_config = act_stage2_config;
|
2021-08-06 15:17:05 +02:00
|
|
|
device_class->act_stage3_ip_config = act_stage3_ip_config;
|
2018-07-10 07:45:35 +02:00
|
|
|
device_class->get_configured_mtu = get_configured_mtu;
|
|
|
|
|
device_class->deactivate = deactivate;
|
|
|
|
|
device_class->get_s390_subchannels = get_s390_subchannels;
|
|
|
|
|
device_class->update_connection = update_connection;
|
|
|
|
|
device_class->carrier_changed_notify = carrier_changed_notify;
|
|
|
|
|
device_class->link_changed = link_changed;
|
|
|
|
|
device_class->is_available = is_available;
|
|
|
|
|
device_class->can_reapply_change = can_reapply_change;
|
|
|
|
|
device_class->reapply_connection = reapply_connection;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-07-10 07:45:35 +02:00
|
|
|
device_class->state_changed = device_state_changed;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 13:43:06 +02:00
|
|
|
obj_properties[PROP_SPEED] = g_param_spec_uint(NM_DEVICE_ETHERNET_SPEED,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
0,
|
|
|
|
|
G_MAXUINT32,
|
|
|
|
|
0,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 13:43:06 +02:00
|
|
|
obj_properties[PROP_S390_SUBCHANNELS] =
|
|
|
|
|
g_param_spec_boxed(NM_DEVICE_ETHERNET_S390_SUBCHANNELS,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_TYPE_STRV,
|
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-07-05 13:43:06 +02:00
|
|
|
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
2005-12-31 08:21:24 +00:00
|
|
|
}
|
2014-09-10 10:59:40 -05:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2014-09-10 10:59:40 -05:00
|
|
|
|
2016-10-07 17:00:59 +02:00
|
|
|
#define NM_TYPE_ETHERNET_DEVICE_FACTORY (nm_ethernet_device_factory_get_type())
|
|
|
|
|
#define NM_ETHERNET_DEVICE_FACTORY(obj) \
|
|
|
|
|
(G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_ETHERNET_DEVICE_FACTORY, NMEthernetDeviceFactory))
|
2014-09-10 10:59:40 -05:00
|
|
|
|
|
|
|
|
static NMDevice *
|
2014-09-05 08:50:02 -05:00
|
|
|
create_device(NMDeviceFactory * factory,
|
|
|
|
|
const char * iface,
|
2016-01-10 15:13:20 +01:00
|
|
|
const NMPlatformLink *plink,
|
2014-09-05 08:50:02 -05:00
|
|
|
NMConnection * connection,
|
|
|
|
|
gboolean * out_ignore)
|
2014-09-10 10:59:40 -05:00
|
|
|
{
|
2020-11-12 15:57:06 +01:00
|
|
|
return g_object_new(NM_TYPE_DEVICE_ETHERNET,
|
|
|
|
|
NM_DEVICE_IFACE,
|
|
|
|
|
iface,
|
|
|
|
|
NM_DEVICE_TYPE_DESC,
|
|
|
|
|
"Ethernet",
|
|
|
|
|
NM_DEVICE_DEVICE_TYPE,
|
|
|
|
|
NM_DEVICE_TYPE_ETHERNET,
|
|
|
|
|
NM_DEVICE_LINK_TYPE,
|
|
|
|
|
NM_LINK_TYPE_ETHERNET,
|
|
|
|
|
NULL);
|
2014-09-10 10:59:40 -05:00
|
|
|
}
|
|
|
|
|
|
2017-06-30 17:51:04 +02:00
|
|
|
static gboolean
|
|
|
|
|
match_connection(NMDeviceFactory *factory, NMConnection *connection)
|
|
|
|
|
{
|
|
|
|
|
const char * type = nm_connection_get_connection_type(connection);
|
|
|
|
|
NMSettingPppoe *s_pppoe;
|
|
|
|
|
|
|
|
|
|
if (nm_streq(type, NM_SETTING_WIRED_SETTING_NAME))
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
nm_assert(nm_streq(type, NM_SETTING_PPPOE_SETTING_NAME));
|
|
|
|
|
s_pppoe = nm_connection_get_setting_pppoe(connection);
|
|
|
|
|
|
|
|
|
|
return !nm_setting_pppoe_get_parent(s_pppoe);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 14:17:30 -05:00
|
|
|
NM_DEVICE_FACTORY_DEFINE_INTERNAL(
|
|
|
|
|
ETHERNET,
|
|
|
|
|
Ethernet,
|
|
|
|
|
ethernet,
|
|
|
|
|
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_ETHERNET)
|
|
|
|
|
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_PPPOE_SETTING_NAME),
|
2016-10-07 16:05:43 +02:00
|
|
|
factory_class->create_device = create_device;
|
2017-06-30 17:51:04 +02:00
|
|
|
factory_class->match_connection = match_connection;);
|