From aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 5 Oct 2020 22:27:18 +0200 Subject: New upstream version 1.27.90 --- src/devices/adsl/nm-atm-manager.c | 373 +- src/devices/adsl/nm-device-adsl.c | 1068 +- src/devices/adsl/nm-device-adsl.h | 25 +- src/devices/bluetooth/nm-bluez-common.h | 16 +- src/devices/bluetooth/nm-bluez-manager.c | 4616 ++-- src/devices/bluetooth/nm-bluez-manager.h | 59 +- src/devices/bluetooth/nm-bluez5-dun.c | 1368 +- src/devices/bluetooth/nm-bluez5-dun.h | 39 +- src/devices/bluetooth/nm-bt-error.c | 5 +- src/devices/bluetooth/nm-bt-error.h | 17 +- src/devices/bluetooth/nm-device-bt.c | 2162 +- src/devices/bluetooth/nm-device-bt.h | 55 +- src/devices/bluetooth/tests/nm-bt-test.c | 275 +- src/devices/nm-acd-manager.c | 694 +- src/devices/nm-acd-manager.h | 31 +- src/devices/nm-device-6lowpan.c | 453 +- src/devices/nm-device-6lowpan.h | 21 +- src/devices/nm-device-bond.c | 1106 +- src/devices/nm-device-bond.h | 20 +- src/devices/nm-device-bridge.c | 1948 +- src/devices/nm-device-bridge.h | 26 +- src/devices/nm-device-dummy.c | 216 +- src/devices/nm-device-dummy.h | 21 +- src/devices/nm-device-ethernet-utils.c | 26 +- src/devices/nm-device-ethernet-utils.h | 6 +- src/devices/nm-device-ethernet.c | 3296 +-- src/devices/nm-device-ethernet.h | 30 +- src/devices/nm-device-factory.c | 593 +- src/devices/nm-device-factory.h | 348 +- src/devices/nm-device-generic.c | 286 +- src/devices/nm-device-generic.h | 24 +- src/devices/nm-device-infiniband.c | 732 +- src/devices/nm-device-infiniband.h | 22 +- src/devices/nm-device-ip-tunnel.c | 2204 +- src/devices/nm-device-ip-tunnel.h | 22 +- src/devices/nm-device-logging.h | 58 +- src/devices/nm-device-macsec.c | 1662 +- src/devices/nm-device-macsec.h | 45 +- src/devices/nm-device-macvlan.c | 958 +- src/devices/nm-device-macvlan.h | 21 +- src/devices/nm-device-ppp.c | 495 +- src/devices/nm-device-ppp.h | 20 +- src/devices/nm-device-private.h | 240 +- src/devices/nm-device-tun.c | 868 +- src/devices/nm-device-tun.h | 20 +- src/devices/nm-device-veth.c | 202 +- src/devices/nm-device-veth.h | 20 +- src/devices/nm-device-vlan.c | 1024 +- src/devices/nm-device-vlan.h | 28 +- src/devices/nm-device-vrf.c | 520 +- src/devices/nm-device-vrf.h | 22 +- src/devices/nm-device-vxlan.c | 1326 +- src/devices/nm-device-vxlan.h | 21 +- src/devices/nm-device-wireguard.c | 3281 +-- src/devices/nm-device-wireguard.h | 28 +- src/devices/nm-device-wpan.c | 353 +- src/devices/nm-device-wpan.h | 20 +- src/devices/nm-device.c | 30353 +++++++++++----------- src/devices/nm-device.h | 1275 +- src/devices/nm-lldp-listener.c | 1765 +- src/devices/nm-lldp-listener.h | 32 +- src/devices/ovs/nm-device-ovs-bridge.c | 122 +- src/devices/ovs/nm-device-ovs-bridge.h | 22 +- src/devices/ovs/nm-device-ovs-interface.c | 536 +- src/devices/ovs/nm-device-ovs-interface.h | 23 +- src/devices/ovs/nm-device-ovs-port.c | 244 +- src/devices/ovs/nm-device-ovs-port.h | 22 +- src/devices/ovs/nm-ovs-factory.c | 377 +- src/devices/ovs/nm-ovsdb.c | 3040 ++- src/devices/ovs/nm-ovsdb.h | 53 +- src/devices/team/nm-device-team.c | 1763 +- src/devices/team/nm-device-team.h | 24 +- src/devices/team/nm-team-factory.c | 62 +- src/devices/tests/test-acd.c | 339 +- src/devices/tests/test-lldp.c | 1678 +- src/devices/wifi/nm-device-iwd.c | 4428 ++-- src/devices/wifi/nm-device-iwd.h | 35 +- src/devices/wifi/nm-device-olpc-mesh.c | 738 +- src/devices/wifi/nm-device-olpc-mesh.h | 24 +- src/devices/wifi/nm-device-wifi-p2p.c | 1787 +- src/devices/wifi/nm-device-wifi-p2p.h | 39 +- src/devices/wifi/nm-device-wifi.c | 6237 ++--- src/devices/wifi/nm-device-wifi.h | 42 +- src/devices/wifi/nm-iwd-manager.c | 1491 +- src/devices/wifi/nm-iwd-manager.h | 64 +- src/devices/wifi/nm-wifi-ap.c | 1558 +- src/devices/wifi/nm-wifi-ap.h | 137 +- src/devices/wifi/nm-wifi-common.c | 250 +- src/devices/wifi/nm-wifi-common.h | 14 +- src/devices/wifi/nm-wifi-factory.c | 193 +- src/devices/wifi/nm-wifi-p2p-peer.c | 853 +- src/devices/wifi/nm-wifi-p2p-peer.h | 121 +- src/devices/wifi/nm-wifi-utils.c | 1647 +- src/devices/wifi/nm-wifi-utils.h | 38 +- src/devices/wifi/tests/test-devices-wifi.c | 2553 +- src/devices/wwan/nm-device-modem.c | 1434 +- src/devices/wwan/nm-device-modem.h | 29 +- src/devices/wwan/nm-modem-broadband.c | 2610 +- src/devices/wwan/nm-modem-broadband.h | 24 +- src/devices/wwan/nm-modem-manager.c | 1202 +- src/devices/wwan/nm-modem-manager.h | 32 +- src/devices/wwan/nm-modem-ofono.c | 2076 +- src/devices/wwan/nm-modem-ofono.h | 22 +- src/devices/wwan/nm-modem.c | 3090 +-- src/devices/wwan/nm-modem.h | 394 +- src/devices/wwan/nm-service-providers.c | 702 +- src/devices/wwan/nm-service-providers.h | 28 +- src/devices/wwan/nm-wwan-factory.c | 159 +- src/devices/wwan/tests/test-service-providers.c | 156 +- 109 files changed, 55686 insertions(+), 53686 deletions(-) (limited to 'src/devices') diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index 46d74a07..8e9f555d 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2013 Red Hat, Inc. */ @@ -16,253 +16,256 @@ /*****************************************************************************/ -#define NM_TYPE_ATM_MANAGER (nm_atm_manager_get_type ()) -#define NM_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ATM_MANAGER, NMAtmManager)) -#define NM_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) -#define NM_IS_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ATM_MANAGER)) -#define NM_IS_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ATM_MANAGER)) -#define NM_ATM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) +#define NM_TYPE_ATM_MANAGER (nm_atm_manager_get_type()) +#define NM_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_ATM_MANAGER, NMAtmManager)) +#define NM_ATM_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) +#define NM_IS_ATM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_ATM_MANAGER)) +#define NM_IS_ATM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_ATM_MANAGER)) +#define NM_ATM_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_ATM_MANAGER, NMAtmManagerClass)) typedef struct { - NMUdevClient *udev_client; - GSList *devices; + NMUdevClient *udev_client; + GSList * devices; } NMAtmManagerPrivate; typedef struct { - NMDeviceFactory parent; - NMAtmManagerPrivate _priv; + NMDeviceFactory parent; + NMAtmManagerPrivate _priv; } NMAtmManager; typedef struct { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; } NMAtmManagerClass; -static GType nm_atm_manager_get_type (void); +static GType nm_atm_manager_get_type(void); -G_DEFINE_TYPE (NMAtmManager, nm_atm_manager, NM_TYPE_DEVICE_FACTORY); +G_DEFINE_TYPE(NMAtmManager, nm_atm_manager, NM_TYPE_DEVICE_FACTORY); -#define NM_ATM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMAtmManager, NM_IS_ATM_MANAGER) +#define NM_ATM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMAtmManager, NM_IS_ATM_MANAGER) /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_ADSL_SETTING_NAME) -); +NM_DEVICE_FACTORY_DECLARE_TYPES( + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_ADSL_SETTING_NAME)); G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - return (NMDeviceFactory *) g_object_new (NM_TYPE_ATM_MANAGER, NULL); + return (NMDeviceFactory *) g_object_new(NM_TYPE_ATM_MANAGER, NULL); } /*****************************************************************************/ static gboolean -dev_get_attrs (struct udev_device *udev_device, - const char **out_path, - char **out_driver) +dev_get_attrs(struct udev_device *udev_device, const char **out_path, char **out_driver) { - struct udev_device *parent = NULL; - const char *driver, *path; - - g_return_val_if_fail (udev_device != NULL, FALSE); - g_return_val_if_fail (out_path != NULL, FALSE); - g_return_val_if_fail (out_driver != NULL, FALSE); - - path = udev_device_get_syspath (udev_device); - if (!path) { - nm_log_warn (LOGD_PLATFORM, "couldn't determine device path; ignoring..."); - return FALSE; - } - - driver = udev_device_get_driver (udev_device); - if (!driver) { - /* Try the parent */ - parent = udev_device_get_parent (udev_device); - if (parent) - driver = udev_device_get_driver (parent); - } - - *out_path = path; - *out_driver = g_strdup (driver); - - return TRUE; + struct udev_device *parent = NULL; + const char * driver, *path; + + g_return_val_if_fail(udev_device != NULL, FALSE); + g_return_val_if_fail(out_path != NULL, FALSE); + g_return_val_if_fail(out_driver != NULL, FALSE); + + path = udev_device_get_syspath(udev_device); + if (!path) { + nm_log_warn(LOGD_PLATFORM, "couldn't determine device path; ignoring..."); + return FALSE; + } + + driver = udev_device_get_driver(udev_device); + if (!driver) { + /* Try the parent */ + parent = udev_device_get_parent(udev_device); + if (parent) + driver = udev_device_get_driver(parent); + } + + *out_path = path; + *out_driver = g_strdup(driver); + + return TRUE; } static void -device_destroyed (gpointer user_data, GObject *dead) +device_destroyed(gpointer user_data, GObject *dead) { - NMAtmManager *self = NM_ATM_MANAGER (user_data); - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + NMAtmManager * self = NM_ATM_MANAGER(user_data); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE(self); - priv->devices = g_slist_remove (priv->devices, dead); + priv->devices = g_slist_remove(priv->devices, dead); } static void -adsl_add (NMAtmManager *self, struct udev_device *udev_device) +adsl_add(NMAtmManager *self, struct udev_device *udev_device) { - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); - const char *ifname, *sysfs_path = NULL; - char *driver = NULL; - gs_free char *atm_index_path = NULL; - int atm_index; - NMDevice *device; - - g_return_if_fail (udev_device != NULL); - - ifname = udev_device_get_sysname (udev_device); - if (!ifname) { - nm_log_warn (LOGD_PLATFORM, "failed to get device's interface name"); - return; - } - - nm_log_dbg (LOGD_PLATFORM, "(%s): found ATM device", ifname); - - atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex", - NM_ASSERT_VALID_PATH_COMPONENT (ifname)); - atm_index = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, - NMP_SYSCTL_PATHID_ABSOLUTE (atm_index_path), - 10, 0, G_MAXINT, - -1); - if (atm_index < 0) { - nm_log_warn (LOGD_PLATFORM, "(%s): failed to get ATM index", ifname); - return; - } - - if (!dev_get_attrs (udev_device, &sysfs_path, &driver)) { - nm_log_warn (LOGD_PLATFORM, "(%s): failed to get ATM attributes", ifname); - return; - } - - g_assert (sysfs_path); - - device = nm_device_adsl_new (sysfs_path, ifname, driver, atm_index); - g_assert (device); - - priv->devices = g_slist_prepend (priv->devices, device); - g_object_weak_ref (G_OBJECT (device), device_destroyed, self); - - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); - g_object_unref (device); - - g_free (driver); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE(self); + const char * ifname, *sysfs_path = NULL; + char * driver = NULL; + gs_free char * atm_index_path = NULL; + int atm_index; + NMDevice * device; + + g_return_if_fail(udev_device != NULL); + + ifname = udev_device_get_sysname(udev_device); + if (!ifname) { + nm_log_warn(LOGD_PLATFORM, "failed to get device's interface name"); + return; + } + + nm_log_dbg(LOGD_PLATFORM, "(%s): found ATM device", ifname); + + atm_index_path = + g_strdup_printf("/sys/class/atm/%s/atmindex", NM_ASSERT_VALID_PATH_COMPONENT(ifname)); + atm_index = (int) nm_platform_sysctl_get_int_checked(NM_PLATFORM_GET, + NMP_SYSCTL_PATHID_ABSOLUTE(atm_index_path), + 10, + 0, + G_MAXINT, + -1); + if (atm_index < 0) { + nm_log_warn(LOGD_PLATFORM, "(%s): failed to get ATM index", ifname); + return; + } + + if (!dev_get_attrs(udev_device, &sysfs_path, &driver)) { + nm_log_warn(LOGD_PLATFORM, "(%s): failed to get ATM attributes", ifname); + return; + } + + g_assert(sysfs_path); + + device = nm_device_adsl_new(sysfs_path, ifname, driver, atm_index); + g_assert(device); + + priv->devices = g_slist_prepend(priv->devices, device); + g_object_weak_ref(G_OBJECT(device), device_destroyed, self); + + g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref(device); + + g_free(driver); } static void -adsl_remove (NMAtmManager *self, struct udev_device *udev_device) +adsl_remove(NMAtmManager *self, struct udev_device *udev_device) { - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); - const char *iface = udev_device_get_sysname (udev_device); - GSList *iter; - - nm_log_dbg (LOGD_PLATFORM, "(%s): removing ATM device", iface); - - for (iter = priv->devices; iter; iter = iter->next) { - NMDevice *device = iter->data; - - /* Match 'iface' not 'ip_iface' to the ATM device instead of the - * NAS bridge interface or PPPoE interface. - */ - if (g_strcmp0 (nm_device_get_iface (device), iface) != 0) - continue; - - g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); - priv->devices = g_slist_remove (priv->devices, device); - g_signal_emit_by_name (device, NM_DEVICE_REMOVED); - break; - } + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE(self); + const char * iface = udev_device_get_sysname(udev_device); + GSList * iter; + + nm_log_dbg(LOGD_PLATFORM, "(%s): removing ATM device", iface); + + for (iter = priv->devices; iter; iter = iter->next) { + NMDevice *device = iter->data; + + /* Match 'iface' not 'ip_iface' to the ATM device instead of the + * NAS bridge interface or PPPoE interface. + */ + if (g_strcmp0(nm_device_get_iface(device), iface) != 0) + continue; + + g_object_weak_unref(G_OBJECT(iter->data), device_destroyed, self); + priv->devices = g_slist_remove(priv->devices, device); + g_signal_emit_by_name(device, NM_DEVICE_REMOVED); + break; + } } static void -start (NMDeviceFactory *factory) +start(NMDeviceFactory *factory) { - NMAtmManager *self = NM_ATM_MANAGER (factory); - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); - struct udev_enumerate *enumerate; - struct udev_list_entry *devices; - - enumerate = nm_udev_client_enumerate_new (priv->udev_client); - udev_enumerate_add_match_is_initialized (enumerate); - udev_enumerate_scan_devices (enumerate); - devices = udev_enumerate_get_list_entry (enumerate); - for (; devices; devices = udev_list_entry_get_next (devices)) { - struct udev_device *udevice; - - udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate), - udev_list_entry_get_name (devices)); - if (udevice) { - adsl_add (self, udevice); - udev_device_unref (udevice); - } - } - udev_enumerate_unref (enumerate); + NMAtmManager * self = NM_ATM_MANAGER(factory); + NMAtmManagerPrivate * priv = NM_ATM_MANAGER_GET_PRIVATE(self); + struct udev_enumerate * enumerate; + struct udev_list_entry *devices; + + enumerate = nm_udev_client_enumerate_new(priv->udev_client); + udev_enumerate_add_match_is_initialized(enumerate); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + for (; devices; devices = udev_list_entry_get_next(devices)) { + struct udev_device *udevice; + + udevice = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), + udev_list_entry_get_name(devices)); + if (udevice) { + adsl_add(self, udevice); + udev_device_unref(udevice); + } + } + udev_enumerate_unref(enumerate); } static void -handle_uevent (NMUdevClient *client, - struct udev_device *device, - gpointer user_data) +handle_uevent(NMUdevClient *client, struct udev_device *device, gpointer user_data) { - NMAtmManager *self = NM_ATM_MANAGER (user_data); - const char *subsys; - const char *ifindex; - guint64 seqnum; - const char *action; - - action = udev_device_get_action (device); - - g_return_if_fail (action != NULL); - - /* A bit paranoid */ - subsys = udev_device_get_subsystem (device); - g_return_if_fail (!g_strcmp0 (subsys, "atm")); - - ifindex = udev_device_get_property_value (device, "IFINDEX"); - seqnum = udev_device_get_seqnum (device); - nm_log_dbg (LOGD_PLATFORM, "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT, - action, subsys, udev_device_get_sysname (device), ifindex ?: "unknown", seqnum); - - if (!strcmp (action, "add")) - adsl_add (self, device); - else if (!strcmp (action, "remove")) - adsl_remove (self, device); + NMAtmManager *self = NM_ATM_MANAGER(user_data); + const char * subsys; + const char * ifindex; + guint64 seqnum; + const char * action; + + action = udev_device_get_action(device); + + g_return_if_fail(action != NULL); + + /* A bit paranoid */ + subsys = udev_device_get_subsystem(device); + g_return_if_fail(!g_strcmp0(subsys, "atm")); + + ifindex = udev_device_get_property_value(device, "IFINDEX"); + seqnum = udev_device_get_seqnum(device); + nm_log_dbg(LOGD_PLATFORM, + "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT, + action, + subsys, + udev_device_get_sysname(device), + ifindex ?: "unknown", + seqnum); + + if (!strcmp(action, "add")) + adsl_add(self, device); + else if (!strcmp(action, "remove")) + adsl_remove(self, device); } /*****************************************************************************/ static void -nm_atm_manager_init (NMAtmManager *self) +nm_atm_manager_init(NMAtmManager *self) { - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE(self); - priv->udev_client = nm_udev_client_new ((const char *[]) {"atm", NULL }, - handle_uevent, self); + priv->udev_client = nm_udev_client_new((const char *[]){"atm", NULL}, handle_uevent, self); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMAtmManager *self = NM_ATM_MANAGER (object); - NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); - GSList *iter; + NMAtmManager * self = NM_ATM_MANAGER(object); + NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE(self); + GSList * iter; - for (iter = priv->devices; iter; iter = iter->next) - g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); - nm_clear_pointer (&priv->devices, g_slist_free); + for (iter = priv->devices; iter; iter = iter->next) + g_object_weak_unref(G_OBJECT(iter->data), device_destroyed, self); + nm_clear_pointer(&priv->devices, g_slist_free); - priv->udev_client = nm_udev_client_unref (priv->udev_client); + priv->udev_client = nm_udev_client_unref(priv->udev_client); - G_OBJECT_CLASS (nm_atm_manager_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_atm_manager_parent_class)->dispose(object); } static void -nm_atm_manager_class_init (NMAtmManagerClass *klass) +nm_atm_manager_class_init(NMAtmManagerClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - factory_class->get_supported_types = get_supported_types; - factory_class->start = start; + factory_class->get_supported_types = get_supported_types; + factory_class->start = start; } diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 8f7cba22..32615623 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Pantelis Koukousoulas */ @@ -24,677 +24,697 @@ #include "nm-utils.h" #include "devices/nm-device-logging.h" -_LOG_DECLARE_SELF (NMDeviceAdsl); +_LOG_DECLARE_SELF(NMDeviceAdsl); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_ATM_INDEX, -); +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_ATM_INDEX, ); typedef struct { - guint carrier_poll_id; - int atm_index; - - /* PPP */ - NMPPPManager *ppp_manager; - - /* RFC 2684 bridging (PPPoE over ATM) */ - int brfd; - int nas_ifindex; - char * nas_ifname; - guint nas_update_id; - guint nas_update_count; + guint carrier_poll_id; + int atm_index; + + /* PPP */ + NMPPPManager *ppp_manager; + + /* RFC 2684 bridging (PPPoE over ATM) */ + int brfd; + int nas_ifindex; + char *nas_ifname; + guint nas_update_id; + guint nas_update_count; } NMDeviceAdslPrivate; struct _NMDeviceAdsl { - NMDevice parent; - NMDeviceAdslPrivate _priv; + NMDevice parent; + NMDeviceAdslPrivate _priv; }; struct _NMDeviceAdslClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) -#define NM_DEVICE_ADSL_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceAdsl, NM_IS_DEVICE_ADSL, NMDevice) +#define NM_DEVICE_ADSL_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceAdsl, NM_IS_DEVICE_ADSL, NMDevice) /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return ( NM_DEVICE_CAP_CARRIER_DETECT - | NM_DEVICE_CAP_NONSTANDARD_CARRIER - | NM_DEVICE_CAP_IS_NON_KERNEL); + return (NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER + | NM_DEVICE_CAP_IS_NON_KERNEL); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingAdsl *s_adsl; - const char *protocol; + NMSettingAdsl *s_adsl; + const char * protocol; - if (!NM_DEVICE_CLASS (nm_device_adsl_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_adsl_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - s_adsl = nm_connection_get_setting_adsl (connection); + s_adsl = nm_connection_get_setting_adsl(connection); - protocol = nm_setting_adsl_get_protocol (s_adsl); - if (nm_streq0 (protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM)) { - /* FIXME: we don't yet support IPoATM */ - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IPoATM protocol is not yet supported"); - return FALSE; - } + protocol = nm_setting_adsl_get_protocol(s_adsl); + if (nm_streq0(protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM)) { + /* FIXME: we don't yet support IPoATM */ + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPoATM protocol is not yet supported"); + return FALSE; + } - return TRUE; + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingAdsl *s_adsl; - - /* - * We can't telepathically figure out the username, so if - * it wasn't given, we can't complete the connection. - */ - s_adsl = nm_connection_get_setting_adsl (connection); - if (s_adsl && !nm_setting_verify (NM_SETTING (s_adsl), NULL, error)) - return FALSE; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_ADSL_SETTING_NAME, - existing_connections, - NULL, - _("ADSL connection"), - NULL, - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; + NMSettingAdsl *s_adsl; + + /* + * We can't telepathically figure out the username, so if + * it wasn't given, we can't complete the connection. + */ + s_adsl = nm_connection_get_setting_adsl(connection); + if (s_adsl && !nm_setting_verify(NM_SETTING(s_adsl), NULL, error)) + return FALSE; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_ADSL_SETTING_NAME, + existing_connections, + NULL, + _("ADSL connection"), + NULL, + NULL, + FALSE); /* No IPv6 yet by default */ + return TRUE; } /*****************************************************************************/ static gboolean -br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) +br2684_assign_vcc(NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - struct sockaddr_atmpvc addr; - struct atm_backend_br2684 be; - struct atm_qos qos; - int errsv, err, bufsize = 8192; - const char *encapsulation; - gboolean is_llc; - - g_return_val_if_fail (priv->brfd == -1, FALSE); - g_return_val_if_fail (priv->nas_ifname != NULL, FALSE); - - priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); - if (priv->brfd < 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); - priv->brfd = -1; - return FALSE; - } - - err = setsockopt (priv->brfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof (bufsize)); - if (err != 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to set SNDBUF option (%d)", errsv); - goto error; - } - - /* QoS */ - memset (&qos, 0, sizeof (qos)); - qos.aal = ATM_AAL5; - qos.txtp.traffic_class = ATM_UBR; - qos.txtp.max_sdu = 1524; - qos.txtp.pcr = ATM_MAX_PCR; - qos.rxtp = qos.txtp; - - err = setsockopt (priv->brfd, SOL_ATM, SO_ATMQOS, &qos, sizeof (qos)); - if (err != 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to set QoS (%d)", errsv); - goto error; - } - - encapsulation = nm_setting_adsl_get_encapsulation (s_adsl); - - /* VPI/VCI */ - memset (&addr, 0, sizeof (addr)); - addr.sap_family = AF_ATMPVC; - addr.sap_addr.itf = priv->atm_index; - addr.sap_addr.vpi = (guint16) nm_setting_adsl_get_vpi (s_adsl); - addr.sap_addr.vci = (int) nm_setting_adsl_get_vci (s_adsl); - - _LOGD (LOGD_ADSL, "assigning address %d.%d.%d encapsulation %s", - priv->atm_index, addr.sap_addr.vpi, addr.sap_addr.vci, - encapsulation ?: "(none)"); - - err = connect (priv->brfd, (struct sockaddr*) &addr, sizeof (addr)); - if (err != 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to set VPI/VCI (%d)", errsv); - goto error; - } - - /* And last attach the VCC to the interface */ - is_llc = (g_strcmp0 (encapsulation, "llc") == 0); - - memset (&be, 0, sizeof (be)); - be.backend_num = ATM_BACKEND_BR2684; - be.ifspec.method = BR2684_FIND_BYIFNAME; - nm_utils_ifname_cpy (be.ifspec.spec.ifname, priv->nas_ifname); - be.fcs_in = BR2684_FCSIN_NO; - be.fcs_out = BR2684_FCSOUT_NO; - be.encaps = is_llc ? BR2684_ENCAPS_LLC : BR2684_ENCAPS_VC; - err = ioctl (priv->brfd, ATM_SETBACKEND, &be); - if (err != 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to attach VCC (%d)", errsv); - goto error; - } - - return TRUE; + NMDeviceAdslPrivate * priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + struct sockaddr_atmpvc addr; + struct atm_backend_br2684 be; + struct atm_qos qos; + int errsv, err, bufsize = 8192; + const char * encapsulation; + gboolean is_llc; + + g_return_val_if_fail(priv->brfd == -1, FALSE); + g_return_val_if_fail(priv->nas_ifname != NULL, FALSE); + + priv->brfd = socket(PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); + if (priv->brfd < 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); + priv->brfd = -1; + return FALSE; + } + + err = setsockopt(priv->brfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); + if (err != 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to set SNDBUF option (%d)", errsv); + goto error; + } + + /* QoS */ + memset(&qos, 0, sizeof(qos)); + qos.aal = ATM_AAL5; + qos.txtp.traffic_class = ATM_UBR; + qos.txtp.max_sdu = 1524; + qos.txtp.pcr = ATM_MAX_PCR; + qos.rxtp = qos.txtp; + + err = setsockopt(priv->brfd, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)); + if (err != 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to set QoS (%d)", errsv); + goto error; + } + + encapsulation = nm_setting_adsl_get_encapsulation(s_adsl); + + /* VPI/VCI */ + memset(&addr, 0, sizeof(addr)); + addr.sap_family = AF_ATMPVC; + addr.sap_addr.itf = priv->atm_index; + addr.sap_addr.vpi = (guint16) nm_setting_adsl_get_vpi(s_adsl); + addr.sap_addr.vci = (int) nm_setting_adsl_get_vci(s_adsl); + + _LOGD(LOGD_ADSL, + "assigning address %d.%d.%d encapsulation %s", + priv->atm_index, + addr.sap_addr.vpi, + addr.sap_addr.vci, + encapsulation ?: "(none)"); + + err = connect(priv->brfd, (struct sockaddr *) &addr, sizeof(addr)); + if (err != 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to set VPI/VCI (%d)", errsv); + goto error; + } + + /* And last attach the VCC to the interface */ + is_llc = (g_strcmp0(encapsulation, "llc") == 0); + + memset(&be, 0, sizeof(be)); + be.backend_num = ATM_BACKEND_BR2684; + be.ifspec.method = BR2684_FIND_BYIFNAME; + nm_utils_ifname_cpy(be.ifspec.spec.ifname, priv->nas_ifname); + be.fcs_in = BR2684_FCSIN_NO; + be.fcs_out = BR2684_FCSOUT_NO; + be.encaps = is_llc ? BR2684_ENCAPS_LLC : BR2684_ENCAPS_VC; + err = ioctl(priv->brfd, ATM_SETBACKEND, &be); + if (err != 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to attach VCC (%d)", errsv); + goto error; + } + + return TRUE; error: - nm_close (priv->brfd); - priv->brfd = -1; - return FALSE; + nm_close(priv->brfd); + priv->brfd = -1; + return FALSE; } static void -link_changed_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *info, - int change_type_i, - NMDeviceAdsl *self) +link_changed_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *info, + int change_type_i, + NMDeviceAdsl * self) { - const NMPlatformSignalChangeType change_type = change_type_i; - - if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - - /* This only gets called for PPPoE connections and "nas" interfaces */ - - if ( priv->nas_ifindex > 0 - && ifindex == priv->nas_ifindex) { - /* NAS device went away for some reason; kill the connection */ - _LOGD (LOGD_ADSL, "br2684 interface disappeared"); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BR2684_FAILED); - } - } + const NMPlatformSignalChangeType change_type = change_type_i; + + if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + + /* This only gets called for PPPoE connections and "nas" interfaces */ + + if (priv->nas_ifindex > 0 && ifindex == priv->nas_ifindex) { + /* NAS device went away for some reason; kill the connection */ + _LOGD(LOGD_ADSL, "br2684 interface disappeared"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BR2684_FAILED); + } + } } static gboolean -pppoe_vcc_config (NMDeviceAdsl *self) +pppoe_vcc_config(NMDeviceAdsl *self) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMSettingAdsl *s_adsl; + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMSettingAdsl * s_adsl; - s_adsl = nm_device_get_applied_setting (device, NM_TYPE_SETTING_ADSL); + s_adsl = nm_device_get_applied_setting(device, NM_TYPE_SETTING_ADSL); - g_return_val_if_fail (s_adsl, FALSE); + g_return_val_if_fail(s_adsl, FALSE); - /* Set up the VCC */ - if (!br2684_assign_vcc (self, s_adsl)) - return FALSE; + /* Set up the VCC */ + if (!br2684_assign_vcc(self, s_adsl)) + return FALSE; - /* Watch for the 'nas' interface going away */ - g_signal_connect (nm_device_get_platform (device), NM_PLATFORM_SIGNAL_LINK_CHANGED, - G_CALLBACK (link_changed_cb), - self); + /* Watch for the 'nas' interface going away */ + g_signal_connect(nm_device_get_platform(device), + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(link_changed_cb), + self); - _LOGD (LOGD_ADSL, "ATM setup successful"); + _LOGD(LOGD_ADSL, "ATM setup successful"); - /* otherwise we're good for stage3 */ - nm_platform_link_set_up (nm_device_get_platform (device), priv->nas_ifindex, NULL); + /* otherwise we're good for stage3 */ + nm_platform_link_set_up(nm_device_get_platform(device), priv->nas_ifindex, NULL); - return TRUE; + return TRUE; } static gboolean -nas_update_cb (gpointer user_data) +nas_update_cb(gpointer user_data) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - - nm_assert (priv->nas_ifname); - - priv->nas_update_count++; - - nm_assert (priv->nas_ifindex <= 0); - priv->nas_ifindex = nm_platform_link_get_ifindex (nm_device_get_platform (device), priv->nas_ifname); - if (priv->nas_ifindex <= 0) { - if (priv->nas_update_count <= 10) { - /* Keep waiting for it to appear */ - return G_SOURCE_CONTINUE; - } - priv->nas_update_id = 0; - _LOGW (LOGD_ADSL, "failed to find br2684 interface %s ifindex after timeout", priv->nas_ifname); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BR2684_FAILED); - return G_SOURCE_REMOVE; - } - - priv->nas_update_id = 0; - _LOGD (LOGD_ADSL, "using br2684 iface '%s' index %d", priv->nas_ifname, priv->nas_ifindex); - - if (!pppoe_vcc_config (self)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BR2684_FAILED); - return G_SOURCE_REMOVE; - } - - nm_device_activate_schedule_stage2_device_config (device, TRUE); - return G_SOURCE_REMOVE; + NMDeviceAdsl * self = NM_DEVICE_ADSL(user_data); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + + nm_assert(priv->nas_ifname); + + priv->nas_update_count++; + + nm_assert(priv->nas_ifindex <= 0); + priv->nas_ifindex = + nm_platform_link_get_ifindex(nm_device_get_platform(device), priv->nas_ifname); + if (priv->nas_ifindex <= 0) { + if (priv->nas_update_count <= 10) { + /* Keep waiting for it to appear */ + return G_SOURCE_CONTINUE; + } + priv->nas_update_id = 0; + _LOGW(LOGD_ADSL, + "failed to find br2684 interface %s ifindex after timeout", + priv->nas_ifname); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BR2684_FAILED); + return G_SOURCE_REMOVE; + } + + priv->nas_update_id = 0; + _LOGD(LOGD_ADSL, "using br2684 iface '%s' index %d", priv->nas_ifname, priv->nas_ifindex); + + if (!pppoe_vcc_config(self)) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BR2684_FAILED); + return G_SOURCE_REMOVE; + } + + nm_device_activate_schedule_stage2_device_config(device, TRUE); + return G_SOURCE_REMOVE; } static gboolean -br2684_create_iface (NMDeviceAdsl *self) +br2684_create_iface(NMDeviceAdsl *self) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - struct atm_newif_br2684 ni; - nm_auto_close int fd = -1; - int err, errsv; - guint num = 0; - - if (nm_clear_g_source (&priv->nas_update_id)) - nm_assert_not_reached (); - - fd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); - if (fd < 0) { - errsv = errno; - _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); - return FALSE; - } - - memset (&ni, 0, sizeof (ni)); - ni.backend_num = ATM_BACKEND_BR2684; - ni.media = BR2684_MEDIA_ETHERNET; - ni.mtu = 1500; - - /* Loop attempting to create an interface that doesn't exist yet. The - * kernel can create one for us automatically, but due to API issues it - * cannot return that name to us. Since we want to know the name right - * away, just brute-force it. - */ - while (TRUE) { - memset (&ni.ifname, 0, sizeof (ni.ifname)); - g_snprintf (ni.ifname, sizeof (ni.ifname), "nas%u", num++); - - err = ioctl (fd, ATM_NEWBACKENDIF, &ni); - if (err != 0) { - errsv = errno; - if (errsv == EEXIST) - continue; - - _LOGW (LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); - return FALSE; - } - - nm_utils_strdup_reset (&priv->nas_ifname, ni.ifname); - _LOGD (LOGD_ADSL, "waiting for br2684 iface '%s' to appear", priv->nas_ifname); - priv->nas_update_count = 0; - priv->nas_update_id = g_timeout_add (100, nas_update_cb, self); - return TRUE; - } + NMDeviceAdslPrivate * priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + struct atm_newif_br2684 ni; + nm_auto_close int fd = -1; + int err, errsv; + guint num = 0; + + if (nm_clear_g_source(&priv->nas_update_id)) + nm_assert_not_reached(); + + fd = socket(PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); + if (fd < 0) { + errsv = errno; + _LOGE(LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); + return FALSE; + } + + memset(&ni, 0, sizeof(ni)); + ni.backend_num = ATM_BACKEND_BR2684; + ni.media = BR2684_MEDIA_ETHERNET; + ni.mtu = 1500; + + /* Loop attempting to create an interface that doesn't exist yet. The + * kernel can create one for us automatically, but due to API issues it + * cannot return that name to us. Since we want to know the name right + * away, just brute-force it. + */ + while (TRUE) { + memset(&ni.ifname, 0, sizeof(ni.ifname)); + g_snprintf(ni.ifname, sizeof(ni.ifname), "nas%u", num++); + + err = ioctl(fd, ATM_NEWBACKENDIF, &ni); + if (err != 0) { + errsv = errno; + if (errsv == EEXIST) + continue; + + _LOGW(LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); + return FALSE; + } + + nm_utils_strdup_reset(&priv->nas_ifname, ni.ifname); + _LOGD(LOGD_ADSL, "waiting for br2684 iface '%s' to appear", priv->nas_ifname); + priv->nas_update_count = 0; + priv->nas_update_id = g_timeout_add(100, nas_update_cb, self); + return TRUE; + } } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (device); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - NMSettingAdsl *s_adsl; - const char *protocol; - - s_adsl = nm_device_get_applied_setting (device, NM_TYPE_SETTING_ADSL); - - g_return_val_if_fail (s_adsl, NM_ACT_STAGE_RETURN_FAILURE); - - protocol = nm_setting_adsl_get_protocol (s_adsl); - _LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol); - - if (nm_streq0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)) { - /* PPPoA doesn't need anything special */ - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - if (nm_streq0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { - /* PPPoE needs RFC2684 bridging before we can do PPP over it */ - if (priv->nas_ifindex <= 0) { - if (priv->nas_update_id == 0) { - if (!br2684_create_iface (self)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_BR2684_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - return NM_ACT_STAGE_RETURN_POSTPONE; - } - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - _LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol); - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceAdsl * self = NM_DEVICE_ADSL(device); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + NMSettingAdsl * s_adsl; + const char * protocol; + + s_adsl = nm_device_get_applied_setting(device, NM_TYPE_SETTING_ADSL); + + g_return_val_if_fail(s_adsl, NM_ACT_STAGE_RETURN_FAILURE); + + protocol = nm_setting_adsl_get_protocol(s_adsl); + _LOGD(LOGD_ADSL, "using ADSL protocol '%s'", protocol); + + if (nm_streq0(protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)) { + /* PPPoA doesn't need anything special */ + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + if (nm_streq0(protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { + /* PPPoE needs RFC2684 bridging before we can do PPP over it */ + if (priv->nas_ifindex <= 0) { + if (priv->nas_update_id == 0) { + if (!br2684_create_iface(self)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_BR2684_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + return NM_ACT_STAGE_RETURN_POSTPONE; + } + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + _LOGW(LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol); + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) +ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - - switch (status) { - case NM_PPP_STATUS_DISCONNECT: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); - break; - case NM_PPP_STATUS_DEAD: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); - break; - default: - break; - } + NMDevice *device = NM_DEVICE(user_data); + + switch (status) { + case NM_PPP_STATUS_DISCONNECT: + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT); + break; + case NM_PPP_STATUS_DEAD: + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); + break; + default: + break; + } } static void -ppp_ifindex_set (NMPPPManager *ppp_manager, - int ifindex, - const char *iface, - gpointer user_data) +ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - if (!nm_device_set_ip_ifindex (device, ifindex)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } + if (!nm_device_set_ip_ifindex(device, ifindex)) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } } static void -ppp_ip4_config (NMPPPManager *ppp_manager, - NMIP4Config *config, - gpointer user_data) +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - /* Ignore PPP IP4 events that come in after initial configuration */ - if (nm_device_activate_ip4_state_in_conf (device)) - nm_device_activate_schedule_ip_config_result (device, AF_INET, NM_IP_CONFIG_CAST (config)); + /* Ignore PPP IP4 events that come in after initial configuration */ + if (nm_device_activate_ip4_state_in_conf(device)) + nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config)); } static NMActStageReturn -act_stage3_ip4_config_start (NMDevice *device, - NMIP4Config **out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip4_config_start(NMDevice * device, + NMIP4Config ** out_config, + NMDeviceStateReason *out_failure_reason) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (device); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - NMSettingAdsl *s_adsl; - NMActRequest *req; - GError *err = NULL; - const char *ppp_iface; - - req = nm_device_get_act_request (device); - - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - s_adsl = nm_device_get_applied_setting (device, NM_TYPE_SETTING_ADSL); - - g_return_val_if_fail (s_adsl, NM_ACT_STAGE_RETURN_FAILURE); - - /* PPPoE uses the NAS interface, not the ATM interface */ - if (nm_streq0 (nm_setting_adsl_get_protocol (s_adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE)) { - nm_assert (priv->nas_ifname); - ppp_iface = priv->nas_ifname; - - _LOGD (LOGD_ADSL, "starting PPPoE on br2684 interface %s", priv->nas_ifname); - } else { - ppp_iface = nm_device_get_iface (device); - _LOGD (LOGD_ADSL, "starting PPPoA"); - } - - priv->ppp_manager = nm_ppp_manager_create (ppp_iface, &err); - - if (priv->ppp_manager) { - nm_ppp_manager_set_route_parameters (priv->ppp_manager, - nm_device_get_route_table (device, AF_INET), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_table (device, AF_INET6), - nm_device_get_route_metric (device, AF_INET6)); - } - - if ( !priv->ppp_manager - || !nm_ppp_manager_start (priv->ppp_manager, req, - nm_setting_adsl_get_username (s_adsl), - 30, 0, &err)) { - _LOGW (LOGD_ADSL, "PPP failed to start: %s", err->message); - g_error_free (err); - - g_clear_object (&priv->ppp_manager); - - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, - G_CALLBACK (ppp_state_changed), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, - G_CALLBACK (ppp_ifindex_set), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, - G_CALLBACK (ppp_ip4_config), - self); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDeviceAdsl * self = NM_DEVICE_ADSL(device); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + NMSettingAdsl * s_adsl; + NMActRequest * req; + GError * err = NULL; + const char * ppp_iface; + + req = nm_device_get_act_request(device); + + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + s_adsl = nm_device_get_applied_setting(device, NM_TYPE_SETTING_ADSL); + + g_return_val_if_fail(s_adsl, NM_ACT_STAGE_RETURN_FAILURE); + + /* PPPoE uses the NAS interface, not the ATM interface */ + if (nm_streq0(nm_setting_adsl_get_protocol(s_adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE)) { + nm_assert(priv->nas_ifname); + ppp_iface = priv->nas_ifname; + + _LOGD(LOGD_ADSL, "starting PPPoE on br2684 interface %s", priv->nas_ifname); + } else { + ppp_iface = nm_device_get_iface(device); + _LOGD(LOGD_ADSL, "starting PPPoA"); + } + + priv->ppp_manager = nm_ppp_manager_create(ppp_iface, &err); + + if (priv->ppp_manager) { + nm_ppp_manager_set_route_parameters(priv->ppp_manager, + nm_device_get_route_table(device, AF_INET), + nm_device_get_route_metric(device, AF_INET), + nm_device_get_route_table(device, AF_INET6), + nm_device_get_route_metric(device, AF_INET6)); + } + + if (!priv->ppp_manager + || !nm_ppp_manager_start(priv->ppp_manager, + req, + nm_setting_adsl_get_username(s_adsl), + 30, + 0, + &err)) { + _LOGW(LOGD_ADSL, "PPP failed to start: %s", err->message); + g_error_free(err); + + g_clear_object(&priv->ppp_manager); + + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, + G_CALLBACK(ppp_state_changed), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, + G_CALLBACK(ppp_ifindex_set), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, + G_CALLBACK(ppp_ip4_config), + self); + return NM_ACT_STAGE_RETURN_POSTPONE; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - if (addr_family == AF_INET) - return act_stage3_ip4_config_start (device, (NMIP4Config **) out_config, out_failure_reason); + if (addr_family == AF_INET) + return act_stage3_ip4_config_start(device, (NMIP4Config **) out_config, out_failure_reason); - return NM_DEVICE_CLASS (nm_device_adsl_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_adsl_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static void -adsl_cleanup (NMDeviceAdsl *self) +adsl_cleanup(NMDeviceAdsl *self) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - - if (priv->ppp_manager) { - g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_state_changed), self); - g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_ip4_config), self); - nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL); - g_clear_object (&priv->ppp_manager); - } - - g_signal_handlers_disconnect_by_func (nm_device_get_platform (NM_DEVICE (self)), G_CALLBACK (link_changed_cb), self); - - nm_close (priv->brfd); - priv->brfd = -1; - - nm_clear_g_source (&priv->nas_update_id); - - /* FIXME: kernel has no way of explicitly deleting the 'nasX' interface yet, - * so it gets leaked. It does get destroyed when it's no longer in use, - * but we have no control over that. - */ - priv->nas_ifindex = 0; - nm_clear_g_free (&priv->nas_ifname); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); + + if (priv->ppp_manager) { + g_signal_handlers_disconnect_by_func(priv->ppp_manager, + G_CALLBACK(ppp_state_changed), + self); + g_signal_handlers_disconnect_by_func(priv->ppp_manager, G_CALLBACK(ppp_ip4_config), self); + nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); + g_clear_object(&priv->ppp_manager); + } + + g_signal_handlers_disconnect_by_func(nm_device_get_platform(NM_DEVICE(self)), + G_CALLBACK(link_changed_cb), + self); + + nm_close(priv->brfd); + priv->brfd = -1; + + nm_clear_g_source(&priv->nas_update_id); + + /* FIXME: kernel has no way of explicitly deleting the 'nasX' interface yet, + * so it gets leaked. It does get destroyed when it's no longer in use, + * but we have no control over that. + */ + priv->nas_ifindex = 0; + nm_clear_g_free(&priv->nas_ifname); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - adsl_cleanup (NM_DEVICE_ADSL (device)); + adsl_cleanup(NM_DEVICE_ADSL(device)); } /*****************************************************************************/ static gboolean -carrier_update_cb (gpointer user_data) +carrier_update_cb(gpointer user_data) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data); - int carrier; - char *path; - - path = g_strdup_printf ("/sys/class/atm/%s/carrier", - NM_ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); - carrier = (int) nm_platform_sysctl_get_int_checked (nm_device_get_platform (NM_DEVICE (self)), NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 0, 1, -1); - g_free (path); - - if (carrier != -1) - nm_device_set_carrier (NM_DEVICE (self), carrier); - return TRUE; + NMDeviceAdsl *self = NM_DEVICE_ADSL(user_data); + int carrier; + char * path; + + path = g_strdup_printf("/sys/class/atm/%s/carrier", + NM_ASSERT_VALID_PATH_COMPONENT(nm_device_get_iface(NM_DEVICE(self)))); + carrier = (int) nm_platform_sysctl_get_int_checked(nm_device_get_platform(NM_DEVICE(self)), + NMP_SYSCTL_PATHID_ABSOLUTE(path), + 10, + 0, + 1, + -1); + g_free(path); + + if (carrier != -1) + nm_device_set_carrier(NM_DEVICE(self), carrier); + return TRUE; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - switch (prop_id) { - case PROP_ATM_INDEX: - g_value_set_int (value, NM_DEVICE_ADSL_GET_PRIVATE (object)->atm_index); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_ATM_INDEX: + g_value_set_int(value, NM_DEVICE_ADSL_GET_PRIVATE(object)->atm_index); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - switch (prop_id) { - case PROP_ATM_INDEX: - /* construct-only */ - NM_DEVICE_ADSL_GET_PRIVATE (object)->atm_index = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_ATM_INDEX: + /* construct-only */ + NM_DEVICE_ADSL_GET_PRIVATE(object)->atm_index = g_value_get_int(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_adsl_init (NMDeviceAdsl *self) -{ -} +nm_device_adsl_init(NMDeviceAdsl *self) +{} static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceAdsl *self = NM_DEVICE_ADSL (object); - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + NMDeviceAdsl * self = NM_DEVICE_ADSL(object); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE(self); - G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_device_adsl_parent_class)->constructed(object); - priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, self); + priv->carrier_poll_id = g_timeout_add_seconds(5, carrier_update_cb, self); - _LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index); + _LOGD(LOGD_ADSL, "ATM device index %d", priv->atm_index); - g_return_if_fail (priv->atm_index >= 0); + g_return_if_fail(priv->atm_index >= 0); } NMDevice * -nm_device_adsl_new (const char *udi, - const char *iface, - const char *driver, - int atm_index) +nm_device_adsl_new(const char *udi, const char *iface, const char *driver, int atm_index) { - g_return_val_if_fail (udi != NULL, NULL); - g_return_val_if_fail (atm_index >= 0, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ADSL, - NM_DEVICE_UDI, udi, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, driver, - NM_DEVICE_ADSL_ATM_INDEX, atm_index, - NM_DEVICE_TYPE_DESC, "ADSL", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ADSL, - NULL); + g_return_val_if_fail(udi != NULL, NULL); + g_return_val_if_fail(atm_index >= 0, NULL); + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_ADSL, + NM_DEVICE_UDI, + udi, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_DRIVER, + driver, + NM_DEVICE_ADSL_ATM_INDEX, + atm_index, + NM_DEVICE_TYPE_DESC, + "ADSL", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_ADSL, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - adsl_cleanup (NM_DEVICE_ADSL (object)); + adsl_cleanup(NM_DEVICE_ADSL(object)); - nm_clear_g_source (&NM_DEVICE_ADSL_GET_PRIVATE (object)->carrier_poll_id); + nm_clear_g_source(&NM_DEVICE_ADSL_GET_PRIVATE(object)->carrier_poll_id); - G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_adsl_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_adsl = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_ADSL, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_ADSL, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", + "b", + NM_DEVICE_CARRIER), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_adsl_class_init (NMDeviceAdslClass *klass) +nm_device_adsl_class_init(NMDeviceAdslClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - object_class->constructed = constructed; - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_adsl); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_adsl); - device_class->connection_type_check_compatible = NM_SETTING_ADSL_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_ADSL_SETTING_NAME; - device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->deactivate = deactivate; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->deactivate = deactivate; - obj_properties[PROP_ATM_INDEX] = - g_param_spec_int (NM_DEVICE_ADSL_ATM_INDEX, "", "", - -1, G_MAXINT, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ATM_INDEX] = + g_param_spec_int(NM_DEVICE_ADSL_ATM_INDEX, + "", + "", + -1, + G_MAXINT, + -1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/adsl/nm-device-adsl.h b/src/devices/adsl/nm-device-adsl.h index 84176fae..95740830 100644 --- a/src/devices/adsl/nm-device-adsl.h +++ b/src/devices/adsl/nm-device-adsl.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Author: Pantelis Koukousoulas * Copyright (C) 2009 - 2011 Red Hat Inc. @@ -9,23 +9,22 @@ #include "devices/nm-device.h" -#define NM_TYPE_DEVICE_ADSL (nm_device_adsl_get_type ()) -#define NM_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdsl)) -#define NM_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) -#define NM_IS_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_ADSL)) -#define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ADSL)) -#define NM_DEVICE_ADSL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) +#define NM_TYPE_DEVICE_ADSL (nm_device_adsl_get_type()) +#define NM_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdsl)) +#define NM_DEVICE_ADSL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) +#define NM_IS_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_ADSL)) +#define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_ADSL)) +#define NM_DEVICE_ADSL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) #define NM_DEVICE_ADSL_ATM_INDEX "atm-index" -typedef struct _NMDeviceAdsl NMDeviceAdsl; +typedef struct _NMDeviceAdsl NMDeviceAdsl; typedef struct _NMDeviceAdslClass NMDeviceAdslClass; -GType nm_device_adsl_get_type (void); +GType nm_device_adsl_get_type(void); -NMDevice *nm_device_adsl_new (const char *udi, - const char *iface, - const char *driver, - int atm_index); +NMDevice *nm_device_adsl_new(const char *udi, const char *iface, const char *driver, int atm_index); #endif /* NM_DEVICE_ADSL_H */ diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index ade4434b..e70ec3f7 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -9,16 +9,16 @@ #define BLUETOOTH_CONNECT_DUN "dun" #define BLUETOOTH_CONNECT_NAP "nap" -#define NM_BLUEZ_SERVICE "org.bluez" +#define NM_BLUEZ_SERVICE "org.bluez" -#define NM_BLUEZ_MANAGER_PATH "/" +#define NM_BLUEZ_MANAGER_PATH "/" -#define NM_BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1" -#define NM_BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1" -#define NM_BLUEZ5_NETWORK_INTERFACE "org.bluez.Network1" +#define NM_BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1" +#define NM_BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1" +#define NM_BLUEZ5_NETWORK_INTERFACE "org.bluez.Network1" #define NM_BLUEZ5_NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1" -#define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" +#define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" #define NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED "network-server-added" -#endif /* NM_BLUEZ_COMMON_H */ +#endif /* NM_BLUEZ_COMMON_H */ diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 0bbac4c4..df0bcbbb 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - 2014 Red Hat, Inc. */ @@ -29,2883 +29,2867 @@ /*****************************************************************************/ #if WITH_BLUEZ5_DUN -#define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_DUN + #define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_DUN #else -#define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_NONE + #define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_NONE #endif #define _NM_BT_CAPABILITY_SUPPORTED (NM_BT_CAPABILITY_NAP | _NM_BT_CAPABILITY_SUPPORTED_DUN) typedef struct { - const char *bdaddr; - CList lst_head; - NMBluetoothCapabilities bt_type:8; - char bdaddr_data[]; + const char * bdaddr; + CList lst_head; + NMBluetoothCapabilities bt_type : 8; + char bdaddr_data[]; } ConnDataHead; typedef struct { - NMSettingsConnection *sett_conn; - ConnDataHead *cdata_hd; - CList lst; + NMSettingsConnection *sett_conn; + ConnDataHead * cdata_hd; + CList lst; } ConnDataElem; typedef struct { - GCancellable *ext_cancellable; - GCancellable *int_cancellable; - NMBtVTableRegisterCallback callback; - gpointer callback_user_data; - gulong ext_cancelled_id; + GCancellable * ext_cancellable; + GCancellable * int_cancellable; + NMBtVTableRegisterCallback callback; + gpointer callback_user_data; + gulong ext_cancelled_id; } NetworkServerRegisterReqData; typedef struct { - GCancellable *ext_cancellable; - GCancellable *int_cancellable; - NMBluezManagerConnectCb callback; - gpointer callback_user_data; - char *device_name; - gulong ext_cancelled_id; - guint timeout_id; - guint timeout_wait_connect_id; + GCancellable * ext_cancellable; + GCancellable * int_cancellable; + NMBluezManagerConnectCb callback; + gpointer callback_user_data; + char * device_name; + gulong ext_cancelled_id; + guint timeout_id; + guint timeout_wait_connect_id; } DeviceConnectReqData; typedef struct { - const char *object_path; - - NMBluezManager *self; - - /* Fields name with "d_" prefix are purely cached values from BlueZ's - * ObjectManager D-Bus interface. There is no logic whatsoever about - * them. - */ - - CList process_change_lst; - - struct { - char *address; - } d_adapter; - - struct { - char *address; - char *name; - char *adapter; - } d_device; - - struct { - char *interface; - } d_network; - - struct { - CList lst; - char *adapter_address; - NMDevice *device_br; - NetworkServerRegisterReqData *r_req_data; - } x_network_server; - - struct { - NMSettingsConnection *panu_connection; - NMDeviceBt *device_bt; - DeviceConnectReqData *c_req_data; - NMBluez5DunContext *connect_dun_context; - gulong device_bt_signal_id; - } x_device; - - /* indicate whether the D-Bus object has the particular D-Bus interface. */ - bool d_has_adapter_iface:1; - bool d_has_device_iface:1; - bool d_has_network_iface:1; - bool d_has_network_server_iface:1; - - /* cached D-Bus properties for Device1 ("d_device*"). */ - NMBluetoothCapabilities d_device_capabilities:6; - bool d_device_connected:1; - bool d_device_paired:1; - - /* cached D-Bus properties for Network1 ("d_network*"). */ - bool d_network_connected:1; - - /* cached D-Bus properties for Adapter1 ("d_adapter*"). */ - bool d_adapter_powered:1; - - /* properties related to device ("x_device*"). */ - NMBluetoothCapabilities x_device_connect_bt_type:6; - bool x_device_is_usable:1; - bool x_device_is_connected:1; - - bool x_device_panu_connection_allow_create:1; - - /* flag to remember last time when we checked wether the object - * was a suitable adapter that is usable to a device. */ - bool was_usable_adapter_for_device_before:1; - - char _object_path_intern[]; + const char *object_path; + + NMBluezManager *self; + + /* Fields name with "d_" prefix are purely cached values from BlueZ's + * ObjectManager D-Bus interface. There is no logic whatsoever about + * them. + */ + + CList process_change_lst; + + struct { + char *address; + } d_adapter; + + struct { + char *address; + char *name; + char *adapter; + } d_device; + + struct { + char *interface; + } d_network; + + struct { + CList lst; + char * adapter_address; + NMDevice * device_br; + NetworkServerRegisterReqData *r_req_data; + } x_network_server; + + struct { + NMSettingsConnection *panu_connection; + NMDeviceBt * device_bt; + DeviceConnectReqData *c_req_data; + NMBluez5DunContext * connect_dun_context; + gulong device_bt_signal_id; + } x_device; + + /* indicate whether the D-Bus object has the particular D-Bus interface. */ + bool d_has_adapter_iface : 1; + bool d_has_device_iface : 1; + bool d_has_network_iface : 1; + bool d_has_network_server_iface : 1; + + /* cached D-Bus properties for Device1 ("d_device*"). */ + NMBluetoothCapabilities d_device_capabilities : 6; + bool d_device_connected : 1; + bool d_device_paired : 1; + + /* cached D-Bus properties for Network1 ("d_network*"). */ + bool d_network_connected : 1; + + /* cached D-Bus properties for Adapter1 ("d_adapter*"). */ + bool d_adapter_powered : 1; + + /* properties related to device ("x_device*"). */ + NMBluetoothCapabilities x_device_connect_bt_type : 6; + bool x_device_is_usable : 1; + bool x_device_is_connected : 1; + + bool x_device_panu_connection_allow_create : 1; + + /* flag to remember last time when we checked wether the object + * was a suitable adapter that is usable to a device. */ + bool was_usable_adapter_for_device_before : 1; + + char _object_path_intern[]; } BzDBusObj; typedef struct { - NMManager *manager; - NMSettings *settings; + NMManager * manager; + NMSettings *settings; - GDBusConnection *dbus_connection; + GDBusConnection *dbus_connection; - NMBtVTableNetworkServer vtable_network_server; + NMBtVTableNetworkServer vtable_network_server; - GCancellable *name_owner_get_cancellable; - GCancellable *get_managed_objects_cancellable; + GCancellable *name_owner_get_cancellable; + GCancellable *get_managed_objects_cancellable; - GHashTable *bzobjs; + GHashTable *bzobjs; - char *name_owner; + char *name_owner; - GHashTable *conn_data_heads; - GHashTable *conn_data_elems; + GHashTable *conn_data_heads; + GHashTable *conn_data_elems; - CList network_server_lst_head; + CList network_server_lst_head; - CList process_change_lst_head; + CList process_change_lst_head; - guint name_owner_changed_id; + guint name_owner_changed_id; - guint managed_objects_changed_id; + guint managed_objects_changed_id; - guint properties_changed_id; + guint properties_changed_id; - guint process_change_idle_id; + guint process_change_idle_id; - bool settings_registered:1; + bool settings_registered : 1; } NMBluezManagerPrivate; struct _NMBluezManager { - NMDeviceFactory parent; - NMBluezManagerPrivate _priv; + NMDeviceFactory parent; + NMBluezManagerPrivate _priv; }; struct _NMBluezManagerClass { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; }; -G_DEFINE_TYPE (NMBluezManager, nm_bluez_manager, NM_TYPE_DEVICE_FACTORY); +G_DEFINE_TYPE(NMBluezManager, nm_bluez_manager, NM_TYPE_DEVICE_FACTORY); -#define NM_BLUEZ_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMBluezManager, NM_IS_BLUEZ_MANAGER) +#define NM_BLUEZ_MANAGER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMBluezManager, NM_IS_BLUEZ_MANAGER) /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BNEP) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BLUETOOTH_SETTING_NAME) -) +NM_DEVICE_FACTORY_DECLARE_TYPES(NM_DEVICE_FACTORY_DECLARE_LINK_TYPES( + NM_LINK_TYPE_BNEP) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_BLUETOOTH_SETTING_NAME)) G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - return (NMDeviceFactory *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL); + return (NMDeviceFactory *) g_object_new(NM_TYPE_BLUEZ_MANAGER, NULL); } /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_BT -#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "bluez", __VA_ARGS__) +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "bluez", __VA_ARGS__) /*****************************************************************************/ static NMBluetoothCapabilities -convert_uuids_to_capabilities (const char *const*strv) +convert_uuids_to_capabilities(const char *const *strv) { - NMBluetoothCapabilities capabilities = NM_BT_CAPABILITY_NONE; + NMBluetoothCapabilities capabilities = NM_BT_CAPABILITY_NONE; - if (strv) { - for (; strv[0]; strv++) { - gs_free char *s_part1 = NULL; - const char *str = strv[0]; - const char *s; + if (strv) { + for (; strv[0]; strv++) { + gs_free char *s_part1 = NULL; + const char * str = strv[0]; + const char * s; - s = strchr (str, '-'); - if (!s) - continue; + s = strchr(str, '-'); + if (!s) + continue; - s_part1 = g_strndup (str, s - str); - switch (_nm_utils_ascii_str_to_int64 (s_part1, 16, 0, G_MAXINT, -1)) { - case 0x1103: - capabilities |= NM_BT_CAPABILITY_DUN; - break; - case 0x1116: - capabilities |= NM_BT_CAPABILITY_NAP; - break; - default: - break; - } - } - } + s_part1 = g_strndup(str, s - str); + switch (_nm_utils_ascii_str_to_int64(s_part1, 16, 0, G_MAXINT, -1)) { + case 0x1103: + capabilities |= NM_BT_CAPABILITY_DUN; + break; + case 0x1116: + capabilities |= NM_BT_CAPABILITY_NAP; + break; + default: + break; + } + } + } - return capabilities; + return capabilities; } /*****************************************************************************/ -static void _cleanup_for_name_owner (NMBluezManager *self); -static void _connect_disconnect (NMBluezManager *self, - BzDBusObj *bzobj, - const char *reason); -static gboolean _bzobjs_network_server_is_usable (const BzDBusObj *bzobj, - gboolean require_powered); -static gboolean _bzobjs_is_dead (const BzDBusObj *bzobj); -static gboolean _bzobjs_device_is_usable (const BzDBusObj *bzobj, - BzDBusObj **out_adapter_bzobj, - gboolean *out_create_panu_connection); -static gboolean _bzobjs_adapter_is_usable_for_device (const BzDBusObj *bzobj); -static ConnDataHead *_conn_track_find_head (NMBluezManager *self, - NMBluetoothCapabilities bt_type, - const char *bdaddr); -static void _process_change_idle_schedule (NMBluezManager *self, - BzDBusObj *bzobj); -static void _network_server_unregister_bridge (NMBluezManager *self, - BzDBusObj *bzobj, - const char *reason); -static gboolean _connect_timeout_wait_connected_cb (gpointer user_data); +static void _cleanup_for_name_owner(NMBluezManager *self); +static void _connect_disconnect(NMBluezManager *self, BzDBusObj *bzobj, const char *reason); +static gboolean _bzobjs_network_server_is_usable(const BzDBusObj *bzobj, gboolean require_powered); +static gboolean _bzobjs_is_dead(const BzDBusObj *bzobj); +static gboolean _bzobjs_device_is_usable(const BzDBusObj *bzobj, + BzDBusObj ** out_adapter_bzobj, + gboolean * out_create_panu_connection); +static gboolean _bzobjs_adapter_is_usable_for_device(const BzDBusObj *bzobj); +static ConnDataHead * +_conn_track_find_head(NMBluezManager *self, NMBluetoothCapabilities bt_type, const char *bdaddr); +static void _process_change_idle_schedule(NMBluezManager *self, BzDBusObj *bzobj); +static void +_network_server_unregister_bridge(NMBluezManager *self, BzDBusObj *bzobj, const char *reason); +static gboolean _connect_timeout_wait_connected_cb(gpointer user_data); /*****************************************************************************/ static void -_dbus_call_complete_cb_nop (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_dbus_call_complete_cb_nop(GObject *source_object, GAsyncResult *res, gpointer user_data) { - /* we don't do anything at all. The only reason to register this - * callback is so that GDBusConnection keeps the cancellable alive - * long enough until the call completes. - * - * Note that this cancellable in turn is registered via - * nm_shutdown_wait_obj_register_*(), to block shutdown until - * we are done. */ + /* we don't do anything at all. The only reason to register this + * callback is so that GDBusConnection keeps the cancellable alive + * long enough until the call completes. + * + * Note that this cancellable in turn is registered via + * nm_shutdown_wait_obj_register_*(), to block shutdown until + * we are done. */ } /*****************************************************************************/ static void -_network_server_register_req_data_complete (NetworkServerRegisterReqData *r_req_data, - GError *error) +_network_server_register_req_data_complete(NetworkServerRegisterReqData *r_req_data, GError *error) { - nm_clear_g_signal_handler (r_req_data->ext_cancellable, &r_req_data->ext_cancelled_id); + nm_clear_g_signal_handler(r_req_data->ext_cancellable, &r_req_data->ext_cancelled_id); - nm_clear_g_cancellable (&r_req_data->int_cancellable); + nm_clear_g_cancellable(&r_req_data->int_cancellable); - if (r_req_data->callback) { - gs_free_error GError *error_cancelled = NULL; + if (r_req_data->callback) { + gs_free_error GError *error_cancelled = NULL; - if (g_cancellable_set_error_if_cancelled (r_req_data->ext_cancellable, &error_cancelled)) - error = error_cancelled; + if (g_cancellable_set_error_if_cancelled(r_req_data->ext_cancellable, &error_cancelled)) + error = error_cancelled; - r_req_data->callback (error, r_req_data->callback_user_data); - } + r_req_data->callback(error, r_req_data->callback_user_data); + } - g_object_unref (r_req_data->ext_cancellable); - nm_g_slice_free (r_req_data); + g_object_unref(r_req_data->ext_cancellable); + nm_g_slice_free(r_req_data); } static void -_device_connect_req_data_complete (DeviceConnectReqData *c_req_data, - NMBluezManager *self, - const char *device_name, - GError *error) +_device_connect_req_data_complete(DeviceConnectReqData *c_req_data, + NMBluezManager * self, + const char * device_name, + GError * error) { - nm_assert ((!!device_name) != (!!error)); + nm_assert((!!device_name) != (!!error)); - nm_clear_g_signal_handler (c_req_data->ext_cancellable, &c_req_data->ext_cancelled_id); + nm_clear_g_signal_handler(c_req_data->ext_cancellable, &c_req_data->ext_cancelled_id); - nm_clear_g_cancellable (&c_req_data->int_cancellable); - nm_clear_g_source (&c_req_data->timeout_id); - nm_clear_g_source (&c_req_data->timeout_wait_connect_id); + nm_clear_g_cancellable(&c_req_data->int_cancellable); + nm_clear_g_source(&c_req_data->timeout_id); + nm_clear_g_source(&c_req_data->timeout_wait_connect_id); - if (c_req_data->callback) { - gs_free_error GError *error_cancelled = NULL; + if (c_req_data->callback) { + gs_free_error GError *error_cancelled = NULL; - if (g_cancellable_set_error_if_cancelled (c_req_data->ext_cancellable, &error_cancelled)) { - error = error_cancelled; - device_name = NULL; - } + if (g_cancellable_set_error_if_cancelled(c_req_data->ext_cancellable, &error_cancelled)) { + error = error_cancelled; + device_name = NULL; + } - c_req_data->callback (self, TRUE, device_name, error, c_req_data->callback_user_data); - } + c_req_data->callback(self, TRUE, device_name, error, c_req_data->callback_user_data); + } - g_object_unref (c_req_data->ext_cancellable); - nm_clear_g_free (&c_req_data->device_name); - nm_g_slice_free (c_req_data); + g_object_unref(c_req_data->ext_cancellable); + nm_clear_g_free(&c_req_data->device_name); + nm_g_slice_free(c_req_data); } /*****************************************************************************/ static BzDBusObj * -_bz_dbus_obj_new (NMBluezManager *self, - const char *object_path) +_bz_dbus_obj_new(NMBluezManager *self, const char *object_path) { - BzDBusObj *bzobj; - gsize l; + BzDBusObj *bzobj; + gsize l; - nm_assert (NM_IS_BLUEZ_MANAGER (self)); + nm_assert(NM_IS_BLUEZ_MANAGER(self)); - l = strlen (object_path) + 1; + l = strlen(object_path) + 1; - bzobj = g_malloc (sizeof (BzDBusObj) + l); - *bzobj = (BzDBusObj) { - .object_path = bzobj->_object_path_intern, - .self = self, - .x_network_server.lst = C_LIST_INIT (bzobj->x_network_server.lst), - .process_change_lst = C_LIST_INIT (bzobj->process_change_lst), - .x_device_panu_connection_allow_create = TRUE, - }; - memcpy (bzobj->_object_path_intern, object_path, l); + bzobj = g_malloc(sizeof(BzDBusObj) + l); + *bzobj = (BzDBusObj){ + .object_path = bzobj->_object_path_intern, + .self = self, + .x_network_server.lst = C_LIST_INIT(bzobj->x_network_server.lst), + .process_change_lst = C_LIST_INIT(bzobj->process_change_lst), + .x_device_panu_connection_allow_create = TRUE, + }; + memcpy(bzobj->_object_path_intern, object_path, l); - return bzobj; + return bzobj; } static void -_bz_dbus_obj_free (BzDBusObj *bzobj) +_bz_dbus_obj_free(BzDBusObj *bzobj) { - nm_assert (bzobj); - nm_assert (NM_IS_BLUEZ_MANAGER (bzobj->self)); - nm_assert (!bzobj->x_network_server.device_br); - nm_assert (!bzobj->x_network_server.r_req_data); - nm_assert (!bzobj->x_device.c_req_data); + nm_assert(bzobj); + nm_assert(NM_IS_BLUEZ_MANAGER(bzobj->self)); + nm_assert(!bzobj->x_network_server.device_br); + nm_assert(!bzobj->x_network_server.r_req_data); + nm_assert(!bzobj->x_device.c_req_data); - c_list_unlink_stale (&bzobj->process_change_lst); - c_list_unlink_stale (&bzobj->x_network_server.lst); - g_free (bzobj->x_network_server.adapter_address); - g_free (bzobj->d_adapter.address); - g_free (bzobj->d_network.interface); - g_free (bzobj->d_device.address); - g_free (bzobj->d_device.name); - g_free (bzobj->d_device.adapter); - g_free (bzobj); + c_list_unlink_stale(&bzobj->process_change_lst); + c_list_unlink_stale(&bzobj->x_network_server.lst); + g_free(bzobj->x_network_server.adapter_address); + g_free(bzobj->d_adapter.address); + g_free(bzobj->d_network.interface); + g_free(bzobj->d_device.address); + g_free(bzobj->d_device.name); + g_free(bzobj->d_device.adapter); + g_free(bzobj); } /*****************************************************************************/ static const char * -_bzobj_to_string (const BzDBusObj *bzobj, char *buf, gsize len) -{ - char *buf0 = buf; - const char *prefix = ""; - gboolean device_is_usable; - gboolean create_panu_connection = FALSE; - gboolean network_server_is_usable; - char sbuf_cap[100]; - - if (len > 0) - buf[0] = '\0'; - - if (bzobj->d_has_adapter_iface) { - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append_str (&buf, &len, "Adapter1 {"); - if (bzobj->d_adapter.address) { - nm_utils_strbuf_append (&buf, &len, " d.address: \"%s\"", bzobj->d_adapter.address); - if (bzobj->d_adapter_powered) - nm_utils_strbuf_append_str (&buf, &len, ","); - } - if (bzobj->d_adapter_powered) - nm_utils_strbuf_append (&buf, &len, " d.powered: 1"); - nm_utils_strbuf_append_str (&buf, &len, " }"); - } - - if (bzobj->d_has_device_iface) { - const char *prefix1 = ""; - - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append_str (&buf, &len, "Device1 {"); - if (bzobj->d_device.address) { - nm_utils_strbuf_append (&buf, &len, "%s d.address: \"%s\"", prefix1, bzobj->d_device.address); - prefix1 = ","; - } - if (bzobj->d_device.name) { - nm_utils_strbuf_append (&buf, &len, "%s d.name: \"%s\"", prefix1, bzobj->d_device.name); - prefix1 = ","; - } - if (bzobj->d_device.adapter) { - nm_utils_strbuf_append (&buf, &len, "%s d.adapter: \"%s\"", prefix1, bzobj->d_device.adapter); - prefix1 = ","; - } - if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { - nm_utils_strbuf_append (&buf, &len, "%s d.capabilities: \"%s\"", - prefix1, - nm_bluetooth_capability_to_string (bzobj->d_device_capabilities, sbuf_cap, sizeof (sbuf_cap))); - prefix1 = ","; - } - if (bzobj->d_device_connected) { - nm_utils_strbuf_append (&buf, &len, "%s d.connected: 1", prefix1); - prefix1 = ","; - } - if (bzobj->d_device_paired) { - nm_utils_strbuf_append (&buf, &len, "%s d.paired: 1", prefix1); - prefix1 = ","; - } - nm_utils_strbuf_append_str (&buf, &len, " }"); - } - - network_server_is_usable = _bzobjs_network_server_is_usable (bzobj, TRUE); - - if ( bzobj->d_has_network_server_iface - || network_server_is_usable != (!c_list_is_empty (&bzobj->x_network_server.lst)) - || !c_list_is_empty (&bzobj->x_network_server.lst) - || !nm_streq0 (bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, bzobj->x_network_server.adapter_address) - || bzobj->x_network_server.device_br - || bzobj->x_network_server.r_req_data) { - - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - - nm_utils_strbuf_append (&buf, &len, "NetworkServer1 { "); - - if (!bzobj->d_has_network_server_iface) - nm_utils_strbuf_append (&buf, &len, " has-d-iface: 0, "); - - if (network_server_is_usable != (!c_list_is_empty (&bzobj->x_network_server.lst))) - nm_utils_strbuf_append (&buf, &len, "usable: %d, used: %d", !!network_server_is_usable, !network_server_is_usable); - else if (network_server_is_usable) - nm_utils_strbuf_append (&buf, &len, "used: 1"); - else - nm_utils_strbuf_append (&buf, &len, "usable: 0"); - - if (!nm_streq0 (bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, bzobj->x_network_server.adapter_address)) { - if (bzobj->x_network_server.adapter_address) - nm_utils_strbuf_append (&buf, &len, ", adapter-address: \"%s\"", bzobj->x_network_server.adapter_address); - else - nm_utils_strbuf_append (&buf, &len, ", adapter-address: "); - } - - if (bzobj->x_network_server.device_br) - nm_utils_strbuf_append (&buf, &len, ", bridge-device: 1"); - - if (bzobj->x_network_server.r_req_data) - nm_utils_strbuf_append (&buf, &len, ", register-in-progress: 1"); - - nm_utils_strbuf_append_str (&buf, &len, " }"); - } - - device_is_usable = _bzobjs_device_is_usable (bzobj, NULL, &create_panu_connection); - - if ( bzobj->d_has_network_iface - || bzobj->d_network.interface - || bzobj->d_network_connected - || create_panu_connection - || bzobj->x_device.panu_connection - || device_is_usable != bzobj->x_device_is_usable - || bzobj->x_device.device_bt - || bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE - || bzobj->x_device.connect_dun_context - || bzobj->x_device.c_req_data - || bzobj->x_device_is_connected != bzobj->d_network_connected) { - - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append_str (&buf, &len, "Network1 {"); - if (bzobj->d_network.interface) - nm_utils_strbuf_append (&buf, &len, " d.interface: \"%s\", ", bzobj->d_network.interface); - if (bzobj->d_network_connected) - nm_utils_strbuf_append (&buf, &len, " d.connected: %d, ", !!bzobj->d_network_connected); - if (!bzobj->d_has_network_iface) - nm_utils_strbuf_append (&buf, &len, " has-d-iface: 0, "); - if (device_is_usable != bzobj->x_device_is_usable) - nm_utils_strbuf_append (&buf, &len, " usable: %d, used: %d", !!device_is_usable, !device_is_usable); - else if (device_is_usable) - nm_utils_strbuf_append (&buf, &len, " used: 1"); - else - nm_utils_strbuf_append (&buf, &len, " usable: 0"); - - if (create_panu_connection) - nm_utils_strbuf_append (&buf, &len, ", create-panu-connection: 1"); - - if (bzobj->x_device.panu_connection) - nm_utils_strbuf_append (&buf, &len, ", has-panu-connection: 1"); - - if (bzobj->x_device.device_bt) - nm_utils_strbuf_append (&buf, &len, ", has-device: 1"); - - if ( bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE - || bzobj->x_device.connect_dun_context) { - nm_utils_strbuf_append (&buf, &len, ", connect: %s%s", - nm_bluetooth_capability_to_string (bzobj->x_device_connect_bt_type, sbuf_cap, sizeof (sbuf_cap)), - bzobj->x_device.connect_dun_context ? ",with-dun-context" : ""); - } - - if (bzobj->x_device.c_req_data) - nm_utils_strbuf_append (&buf, &len, ", connecting: 1"); - - if (bzobj->x_device_is_connected != bzobj->d_network_connected) - nm_utils_strbuf_append (&buf, &len, ", connected: %d", !!bzobj->x_device_is_connected); - - nm_utils_strbuf_append_str (&buf, &len, " }"); - } - - if (_bzobjs_is_dead (bzobj)) { - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append_str (&buf, &len, "dead: 1"); - } - - if (!c_list_is_empty (&bzobj->process_change_lst)) { - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append (&buf, &len, "change-pending-on-idle: 1"); - } - - if (_bzobjs_adapter_is_usable_for_device (bzobj) != bzobj->was_usable_adapter_for_device_before) { - nm_utils_strbuf_append_str (&buf, &len, prefix); - prefix = ", "; - nm_utils_strbuf_append (&buf, &len, "change-usable-adapter-for-device: 1"); - } - - return buf0; -} - -#define _LOG_bzobj(bzobj, context) \ - G_STMT_START { \ - const BzDBusObj *const _bzobj = (bzobj); \ - char _buf[500]; \ - \ - _LOGT ("change %-21s %s : { %s }", \ - (context), \ - _bzobj->object_path, \ - _bzobj_to_string (_bzobj, _buf, sizeof (_buf))); \ - } G_STMT_END +_bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) +{ + char * buf0 = buf; + const char *prefix = ""; + gboolean device_is_usable; + gboolean create_panu_connection = FALSE; + gboolean network_server_is_usable; + char sbuf_cap[100]; + + if (len > 0) + buf[0] = '\0'; + + if (bzobj->d_has_adapter_iface) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append_str(&buf, &len, "Adapter1 {"); + if (bzobj->d_adapter.address) { + nm_utils_strbuf_append(&buf, &len, " d.address: \"%s\"", bzobj->d_adapter.address); + if (bzobj->d_adapter_powered) + nm_utils_strbuf_append_str(&buf, &len, ","); + } + if (bzobj->d_adapter_powered) + nm_utils_strbuf_append(&buf, &len, " d.powered: 1"); + nm_utils_strbuf_append_str(&buf, &len, " }"); + } + + if (bzobj->d_has_device_iface) { + const char *prefix1 = ""; + + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append_str(&buf, &len, "Device1 {"); + if (bzobj->d_device.address) { + nm_utils_strbuf_append(&buf, + &len, + "%s d.address: \"%s\"", + prefix1, + bzobj->d_device.address); + prefix1 = ","; + } + if (bzobj->d_device.name) { + nm_utils_strbuf_append(&buf, &len, "%s d.name: \"%s\"", prefix1, bzobj->d_device.name); + prefix1 = ","; + } + if (bzobj->d_device.adapter) { + nm_utils_strbuf_append(&buf, + &len, + "%s d.adapter: \"%s\"", + prefix1, + bzobj->d_device.adapter); + prefix1 = ","; + } + if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { + nm_utils_strbuf_append(&buf, + &len, + "%s d.capabilities: \"%s\"", + prefix1, + nm_bluetooth_capability_to_string(bzobj->d_device_capabilities, + sbuf_cap, + sizeof(sbuf_cap))); + prefix1 = ","; + } + if (bzobj->d_device_connected) { + nm_utils_strbuf_append(&buf, &len, "%s d.connected: 1", prefix1); + prefix1 = ","; + } + if (bzobj->d_device_paired) { + nm_utils_strbuf_append(&buf, &len, "%s d.paired: 1", prefix1); + prefix1 = ","; + } + nm_utils_strbuf_append_str(&buf, &len, " }"); + } + + network_server_is_usable = _bzobjs_network_server_is_usable(bzobj, TRUE); + + if (bzobj->d_has_network_server_iface + || network_server_is_usable != (!c_list_is_empty(&bzobj->x_network_server.lst)) + || !c_list_is_empty(&bzobj->x_network_server.lst) + || !nm_streq0(bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, + bzobj->x_network_server.adapter_address) + || bzobj->x_network_server.device_br || bzobj->x_network_server.r_req_data) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + + nm_utils_strbuf_append(&buf, &len, "NetworkServer1 { "); + + if (!bzobj->d_has_network_server_iface) + nm_utils_strbuf_append(&buf, &len, " has-d-iface: 0, "); + + if (network_server_is_usable != (!c_list_is_empty(&bzobj->x_network_server.lst))) + nm_utils_strbuf_append(&buf, + &len, + "usable: %d, used: %d", + !!network_server_is_usable, + !network_server_is_usable); + else if (network_server_is_usable) + nm_utils_strbuf_append(&buf, &len, "used: 1"); + else + nm_utils_strbuf_append(&buf, &len, "usable: 0"); + + if (!nm_streq0(bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, + bzobj->x_network_server.adapter_address)) { + if (bzobj->x_network_server.adapter_address) + nm_utils_strbuf_append(&buf, + &len, + ", adapter-address: \"%s\"", + bzobj->x_network_server.adapter_address); + else + nm_utils_strbuf_append(&buf, &len, ", adapter-address: "); + } + + if (bzobj->x_network_server.device_br) + nm_utils_strbuf_append(&buf, &len, ", bridge-device: 1"); + + if (bzobj->x_network_server.r_req_data) + nm_utils_strbuf_append(&buf, &len, ", register-in-progress: 1"); + + nm_utils_strbuf_append_str(&buf, &len, " }"); + } + + device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, &create_panu_connection); + + if (bzobj->d_has_network_iface || bzobj->d_network.interface || bzobj->d_network_connected + || create_panu_connection || bzobj->x_device.panu_connection + || device_is_usable != bzobj->x_device_is_usable || bzobj->x_device.device_bt + || bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE + || bzobj->x_device.connect_dun_context || bzobj->x_device.c_req_data + || bzobj->x_device_is_connected != bzobj->d_network_connected) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append_str(&buf, &len, "Network1 {"); + if (bzobj->d_network.interface) + nm_utils_strbuf_append(&buf, + &len, + " d.interface: \"%s\", ", + bzobj->d_network.interface); + if (bzobj->d_network_connected) + nm_utils_strbuf_append(&buf, &len, " d.connected: %d, ", !!bzobj->d_network_connected); + if (!bzobj->d_has_network_iface) + nm_utils_strbuf_append(&buf, &len, " has-d-iface: 0, "); + if (device_is_usable != bzobj->x_device_is_usable) + nm_utils_strbuf_append(&buf, + &len, + " usable: %d, used: %d", + !!device_is_usable, + !device_is_usable); + else if (device_is_usable) + nm_utils_strbuf_append(&buf, &len, " used: 1"); + else + nm_utils_strbuf_append(&buf, &len, " usable: 0"); + + if (create_panu_connection) + nm_utils_strbuf_append(&buf, &len, ", create-panu-connection: 1"); + + if (bzobj->x_device.panu_connection) + nm_utils_strbuf_append(&buf, &len, ", has-panu-connection: 1"); + + if (bzobj->x_device.device_bt) + nm_utils_strbuf_append(&buf, &len, ", has-device: 1"); + + if (bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE + || bzobj->x_device.connect_dun_context) { + nm_utils_strbuf_append( + &buf, + &len, + ", connect: %s%s", + nm_bluetooth_capability_to_string(bzobj->x_device_connect_bt_type, + sbuf_cap, + sizeof(sbuf_cap)), + bzobj->x_device.connect_dun_context ? ",with-dun-context" : ""); + } + + if (bzobj->x_device.c_req_data) + nm_utils_strbuf_append(&buf, &len, ", connecting: 1"); + + if (bzobj->x_device_is_connected != bzobj->d_network_connected) + nm_utils_strbuf_append(&buf, &len, ", connected: %d", !!bzobj->x_device_is_connected); + + nm_utils_strbuf_append_str(&buf, &len, " }"); + } + + if (_bzobjs_is_dead(bzobj)) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append_str(&buf, &len, "dead: 1"); + } + + if (!c_list_is_empty(&bzobj->process_change_lst)) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append(&buf, &len, "change-pending-on-idle: 1"); + } + + if (_bzobjs_adapter_is_usable_for_device(bzobj) + != bzobj->was_usable_adapter_for_device_before) { + nm_utils_strbuf_append_str(&buf, &len, prefix); + prefix = ", "; + nm_utils_strbuf_append(&buf, &len, "change-usable-adapter-for-device: 1"); + } + + return buf0; +} + +#define _LOG_bzobj(bzobj, context) \ + G_STMT_START \ + { \ + const BzDBusObj *const _bzobj = (bzobj); \ + char _buf[500]; \ + \ + _LOGT("change %-21s %s : { %s }", \ + (context), \ + _bzobj->object_path, \ + _bzobj_to_string(_bzobj, _buf, sizeof(_buf))); \ + } \ + G_STMT_END static gboolean -_bzobjs_is_dead (const BzDBusObj *bzobj) +_bzobjs_is_dead(const BzDBusObj *bzobj) { - return !bzobj->d_has_adapter_iface - && !bzobj->d_has_device_iface - && !bzobj->d_has_network_iface - && !bzobj->d_has_network_server_iface - && c_list_is_empty (&bzobj->process_change_lst); + return !bzobj->d_has_adapter_iface && !bzobj->d_has_device_iface && !bzobj->d_has_network_iface + && !bzobj->d_has_network_server_iface && c_list_is_empty(&bzobj->process_change_lst); } static BzDBusObj * -_bzobjs_get (NMBluezManager *self, const char *object_path) +_bzobjs_get(NMBluezManager *self, const char *object_path) { - return g_hash_table_lookup (NM_BLUEZ_MANAGER_GET_PRIVATE (self)->bzobjs, &object_path); + return g_hash_table_lookup(NM_BLUEZ_MANAGER_GET_PRIVATE(self)->bzobjs, &object_path); } static BzDBusObj * -_bzobjs_add (NMBluezManager *self, - const char *object_path) +_bzobjs_add(NMBluezManager *self, const char *object_path) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - BzDBusObj *bzobj; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + BzDBusObj * bzobj; - bzobj = _bz_dbus_obj_new (self, object_path); - if (!g_hash_table_add (priv->bzobjs, bzobj)) - nm_assert_not_reached (); - return bzobj; + bzobj = _bz_dbus_obj_new(self, object_path); + if (!g_hash_table_add(priv->bzobjs, bzobj)) + nm_assert_not_reached(); + return bzobj; } static void -_bzobjs_del (BzDBusObj *bzobj) +_bzobjs_del(BzDBusObj *bzobj) { - nm_assert (bzobj); - nm_assert (bzobj == _bzobjs_get (bzobj->self, bzobj->object_path)); + nm_assert(bzobj); + nm_assert(bzobj == _bzobjs_get(bzobj->self, bzobj->object_path)); - if (!g_hash_table_remove (NM_BLUEZ_MANAGER_GET_PRIVATE (bzobj->self)->bzobjs, bzobj)) - nm_assert_not_reached (); + if (!g_hash_table_remove(NM_BLUEZ_MANAGER_GET_PRIVATE(bzobj->self)->bzobjs, bzobj)) + nm_assert_not_reached(); } static void -_bzobjs_del_if_dead (BzDBusObj *bzobj) +_bzobjs_del_if_dead(BzDBusObj *bzobj) { - if (_bzobjs_is_dead (bzobj)) - _bzobjs_del (bzobj); + if (_bzobjs_is_dead(bzobj)) + _bzobjs_del(bzobj); } static BzDBusObj * -_bzobjs_init (NMBluezManager *self, BzDBusObj **inout, const char *object_path) +_bzobjs_init(NMBluezManager *self, BzDBusObj **inout, const char *object_path) { - nm_assert (NM_IS_BLUEZ_MANAGER (self)); - nm_assert (object_path); - nm_assert (inout); + nm_assert(NM_IS_BLUEZ_MANAGER(self)); + nm_assert(object_path); + nm_assert(inout); - if (!*inout) { - *inout = _bzobjs_get (self, object_path); - if (!*inout) - *inout = _bzobjs_add (self, object_path); - } + if (!*inout) { + *inout = _bzobjs_get(self, object_path); + if (!*inout) + *inout = _bzobjs_add(self, object_path); + } - nm_assert (nm_streq ((*inout)->object_path, object_path)); - nm_assert (*inout == _bzobjs_get (self, object_path)); - return *inout; + nm_assert(nm_streq((*inout)->object_path, object_path)); + nm_assert(*inout == _bzobjs_get(self, object_path)); + return *inout; } static gboolean -_bzobjs_adapter_is_usable_for_device (const BzDBusObj *bzobj) +_bzobjs_adapter_is_usable_for_device(const BzDBusObj *bzobj) { - return bzobj->d_has_adapter_iface - && bzobj->d_adapter.address - && bzobj->d_adapter_powered; + return bzobj->d_has_adapter_iface && bzobj->d_adapter.address && bzobj->d_adapter_powered; } static gboolean -_bzobjs_device_is_usable (const BzDBusObj *bzobj, - BzDBusObj **out_adapter_bzobj, - gboolean *out_create_panu_connection) +_bzobjs_device_is_usable(const BzDBusObj *bzobj, + BzDBusObj ** out_adapter_bzobj, + gboolean * out_create_panu_connection) { - NMBluezManager *self; - NMBluezManagerPrivate *priv; - gboolean usable_dun = FALSE; - gboolean usable_nap = FALSE; - BzDBusObj *bzobj_adapter; - gboolean create_panu_connection = FALSE; + NMBluezManager * self; + NMBluezManagerPrivate *priv; + gboolean usable_dun = FALSE; + gboolean usable_nap = FALSE; + BzDBusObj * bzobj_adapter; + gboolean create_panu_connection = FALSE; - if ( !bzobj->d_has_device_iface - || !NM_FLAGS_ANY ((NMBluetoothCapabilities) bzobj->d_device_capabilities, _NM_BT_CAPABILITY_SUPPORTED) - || !bzobj->d_device.name - || !bzobj->d_device.address - || !bzobj->d_device_paired - || !bzobj->d_device.adapter) - goto out_unusable; + if (!bzobj->d_has_device_iface + || !NM_FLAGS_ANY((NMBluetoothCapabilities) bzobj->d_device_capabilities, + _NM_BT_CAPABILITY_SUPPORTED) + || !bzobj->d_device.name || !bzobj->d_device.address || !bzobj->d_device_paired + || !bzobj->d_device.adapter) + goto out_unusable; - self = bzobj->self; + self = bzobj->self; - priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - if (!priv->settings_registered) - goto out_unusable; + if (!priv->settings_registered) + goto out_unusable; - bzobj_adapter = _bzobjs_get (self, bzobj->d_device.adapter); - if ( !bzobj_adapter - || !_bzobjs_adapter_is_usable_for_device (bzobj_adapter)) - goto out_unusable; + bzobj_adapter = _bzobjs_get(self, bzobj->d_device.adapter); + if (!bzobj_adapter || !_bzobjs_adapter_is_usable_for_device(bzobj_adapter)) + goto out_unusable; #if WITH_BLUEZ5_DUN - if (NM_FLAGS_HAS (bzobj->d_device_capabilities, NM_BT_CAPABILITY_DUN)) { - if (_conn_track_find_head (self, NM_BT_CAPABILITY_DUN, bzobj->d_device.address)) - usable_dun = TRUE; - } + if (NM_FLAGS_HAS(bzobj->d_device_capabilities, NM_BT_CAPABILITY_DUN)) { + if (_conn_track_find_head(self, NM_BT_CAPABILITY_DUN, bzobj->d_device.address)) + usable_dun = TRUE; + } #endif - if (NM_FLAGS_HAS (bzobj->d_device_capabilities, NM_BT_CAPABILITY_NAP)) { - if (!bzobj->d_has_network_iface) - usable_nap = FALSE; - else if (_conn_track_find_head (self, NM_BT_CAPABILITY_NAP, bzobj->d_device.address)) - usable_nap = TRUE; - else if (bzobj->x_device_panu_connection_allow_create) { - /* We didn't yet try to create a connection. Presume we are going to create - * it when the time comes... */ - usable_nap = TRUE; - create_panu_connection = TRUE; - } - } - - if ( !usable_dun - && !usable_nap) { - if ( bzobj->x_device.device_bt - && nm_device_get_state (NM_DEVICE (bzobj->x_device.device_bt)) > NM_DEVICE_STATE_DISCONNECTED) { - /* The device is still activated... the absence of a profile does not - * render it unusable (yet). But since there is no more profile, the - * device is probably about to disconnect. */ - } else - goto out_unusable; - } - - NM_SET_OUT (out_create_panu_connection, create_panu_connection); - NM_SET_OUT (out_adapter_bzobj, bzobj_adapter); - return TRUE; + if (NM_FLAGS_HAS(bzobj->d_device_capabilities, NM_BT_CAPABILITY_NAP)) { + if (!bzobj->d_has_network_iface) + usable_nap = FALSE; + else if (_conn_track_find_head(self, NM_BT_CAPABILITY_NAP, bzobj->d_device.address)) + usable_nap = TRUE; + else if (bzobj->x_device_panu_connection_allow_create) { + /* We didn't yet try to create a connection. Presume we are going to create + * it when the time comes... */ + usable_nap = TRUE; + create_panu_connection = TRUE; + } + } + + if (!usable_dun && !usable_nap) { + if (bzobj->x_device.device_bt + && nm_device_get_state(NM_DEVICE(bzobj->x_device.device_bt)) + > NM_DEVICE_STATE_DISCONNECTED) { + /* The device is still activated... the absence of a profile does not + * render it unusable (yet). But since there is no more profile, the + * device is probably about to disconnect. */ + } else + goto out_unusable; + } + + NM_SET_OUT(out_create_panu_connection, create_panu_connection); + NM_SET_OUT(out_adapter_bzobj, bzobj_adapter); + return TRUE; out_unusable: - NM_SET_OUT (out_create_panu_connection, FALSE); - NM_SET_OUT (out_adapter_bzobj, NULL); - return FALSE; + NM_SET_OUT(out_create_panu_connection, FALSE); + NM_SET_OUT(out_adapter_bzobj, NULL); + return FALSE; } static gboolean -_bzobjs_device_is_connected (const BzDBusObj *bzobj) +_bzobjs_device_is_connected(const BzDBusObj *bzobj) { - nm_assert (_bzobjs_device_is_usable (bzobj, NULL, NULL)); + nm_assert(_bzobjs_device_is_usable(bzobj, NULL, NULL)); - if ( !bzobj->d_has_device_iface - || !bzobj->d_device_connected) - return FALSE; + if (!bzobj->d_has_device_iface || !bzobj->d_device_connected) + return FALSE; - if ( bzobj->d_has_network_iface - && bzobj->d_network_connected) - return TRUE; - if (bzobj->x_device.connect_dun_context) { - /* As long as we have a dun-context, we consider it connected. - * - * We require NMDeviceBt to try to connect to the modem, and if that fails, - * it will disconnect. */ - return TRUE; - } - return FALSE; + if (bzobj->d_has_network_iface && bzobj->d_network_connected) + return TRUE; + if (bzobj->x_device.connect_dun_context) { + /* As long as we have a dun-context, we consider it connected. + * + * We require NMDeviceBt to try to connect to the modem, and if that fails, + * it will disconnect. */ + return TRUE; + } + return FALSE; } static gboolean -_bzobjs_network_server_is_usable (const BzDBusObj *bzobj, - gboolean require_powered) +_bzobjs_network_server_is_usable(const BzDBusObj *bzobj, gboolean require_powered) { - return bzobj->d_has_network_server_iface - && bzobj->d_has_adapter_iface - && bzobj->d_adapter.address - && ( !require_powered - || bzobj->d_adapter_powered); + return bzobj->d_has_network_server_iface && bzobj->d_has_adapter_iface + && bzobj->d_adapter.address && (!require_powered || bzobj->d_adapter_powered); } /*****************************************************************************/ static ConnDataHead * -_conn_data_head_new (NMBluetoothCapabilities bt_type, - const char *bdaddr) +_conn_data_head_new(NMBluetoothCapabilities bt_type, const char *bdaddr) { - ConnDataHead *cdata_hd; - gsize l; + ConnDataHead *cdata_hd; + gsize l; - nm_assert (NM_IN_SET (bt_type, NM_BT_CAPABILITY_DUN, - NM_BT_CAPABILITY_NAP)); - nm_assert (bdaddr); + nm_assert(NM_IN_SET(bt_type, NM_BT_CAPABILITY_DUN, NM_BT_CAPABILITY_NAP)); + nm_assert(bdaddr); - l = strlen (bdaddr) + 1; - cdata_hd = g_malloc (sizeof (ConnDataHead) + l); - *cdata_hd = (ConnDataHead) { - .bdaddr = cdata_hd->bdaddr_data, - .lst_head = C_LIST_INIT (cdata_hd->lst_head), - .bt_type = bt_type, - }; - memcpy (cdata_hd->bdaddr_data, bdaddr, l); + l = strlen(bdaddr) + 1; + cdata_hd = g_malloc(sizeof(ConnDataHead) + l); + *cdata_hd = (ConnDataHead){ + .bdaddr = cdata_hd->bdaddr_data, + .lst_head = C_LIST_INIT(cdata_hd->lst_head), + .bt_type = bt_type, + }; + memcpy(cdata_hd->bdaddr_data, bdaddr, l); - nm_assert (cdata_hd->bt_type == bt_type); + nm_assert(cdata_hd->bt_type == bt_type); - return cdata_hd; + return cdata_hd; } static guint -_conn_data_head_hash (gconstpointer ptr) +_conn_data_head_hash(gconstpointer ptr) { - const ConnDataHead *cdata_hd = ptr; - NMHashState h; + const ConnDataHead *cdata_hd = ptr; + NMHashState h; - nm_hash_init (&h, 520317467u); - nm_hash_update_val (&h, (NMBluetoothCapabilities) cdata_hd->bt_type); - nm_hash_update_str (&h, cdata_hd->bdaddr); - return nm_hash_complete (&h); + nm_hash_init(&h, 520317467u); + nm_hash_update_val(&h, (NMBluetoothCapabilities) cdata_hd->bt_type); + nm_hash_update_str(&h, cdata_hd->bdaddr); + return nm_hash_complete(&h); } static gboolean -_conn_data_head_equal (gconstpointer a, gconstpointer b) +_conn_data_head_equal(gconstpointer a, gconstpointer b) { - const ConnDataHead *cdata_hd_a = a; - const ConnDataHead *cdata_hd_b = b; + const ConnDataHead *cdata_hd_a = a; + const ConnDataHead *cdata_hd_b = b; - return cdata_hd_a->bt_type == cdata_hd_b->bt_type - && nm_streq (cdata_hd_a->bdaddr, cdata_hd_b->bdaddr); + return cdata_hd_a->bt_type == cdata_hd_b->bt_type + && nm_streq(cdata_hd_a->bdaddr, cdata_hd_b->bdaddr); } static ConnDataHead * -_conn_track_find_head (NMBluezManager *self, - NMBluetoothCapabilities bt_type, - const char *bdaddr) +_conn_track_find_head(NMBluezManager *self, NMBluetoothCapabilities bt_type, const char *bdaddr) { - ConnDataHead cdata_hd = { - .bt_type = bt_type, - .bdaddr = bdaddr, - }; + ConnDataHead cdata_hd = { + .bt_type = bt_type, + .bdaddr = bdaddr, + }; - return g_hash_table_lookup (NM_BLUEZ_MANAGER_GET_PRIVATE (self)->conn_data_heads, &cdata_hd); + return g_hash_table_lookup(NM_BLUEZ_MANAGER_GET_PRIVATE(self)->conn_data_heads, &cdata_hd); } static ConnDataElem * -_conn_track_find_elem (NMBluezManager *self, - NMSettingsConnection *sett_conn) +_conn_track_find_elem(NMBluezManager *self, NMSettingsConnection *sett_conn) { - G_STATIC_ASSERT (G_STRUCT_OFFSET (ConnDataElem, sett_conn) == 0); + G_STATIC_ASSERT(G_STRUCT_OFFSET(ConnDataElem, sett_conn) == 0); - return g_hash_table_lookup (NM_BLUEZ_MANAGER_GET_PRIVATE (self)->conn_data_elems, &sett_conn); + return g_hash_table_lookup(NM_BLUEZ_MANAGER_GET_PRIVATE(self)->conn_data_elems, &sett_conn); } static gboolean -_conn_track_is_relevant_connection (NMConnection *connection, - NMBluetoothCapabilities *out_bt_type, - const char **out_bdaddr) +_conn_track_is_relevant_connection(NMConnection * connection, + NMBluetoothCapabilities *out_bt_type, + const char ** out_bdaddr) { - NMSettingBluetooth *s_bt; - NMBluetoothCapabilities bt_type; - const char *bdaddr; - const char *b_type; + NMSettingBluetooth * s_bt; + NMBluetoothCapabilities bt_type; + const char * bdaddr; + const char * b_type; - s_bt = nm_connection_get_setting_bluetooth (connection); - if (!s_bt) - return FALSE; + s_bt = nm_connection_get_setting_bluetooth(connection); + if (!s_bt) + return FALSE; - if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) - return FALSE; + if (!nm_connection_is_type(connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) + return FALSE; - bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr) - return FALSE; + bdaddr = nm_setting_bluetooth_get_bdaddr(s_bt); + if (!bdaddr) + return FALSE; - b_type = nm_setting_bluetooth_get_connection_type (s_bt); + b_type = nm_setting_bluetooth_get_connection_type(s_bt); - if (nm_streq (b_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) - bt_type = NM_BT_CAPABILITY_DUN; - else if (nm_streq (b_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) - bt_type = NM_BT_CAPABILITY_NAP; - else - return FALSE; + if (nm_streq(b_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) + bt_type = NM_BT_CAPABILITY_DUN; + else if (nm_streq(b_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) + bt_type = NM_BT_CAPABILITY_NAP; + else + return FALSE; - NM_SET_OUT (out_bt_type, bt_type); - NM_SET_OUT (out_bdaddr, bdaddr); - return TRUE; + NM_SET_OUT(out_bt_type, bt_type); + NM_SET_OUT(out_bdaddr, bdaddr); + return TRUE; } static gboolean -_conn_track_is_relevant_sett_conn (NMSettingsConnection *sett_conn, - NMBluetoothCapabilities *out_bt_type, - const char **out_bdaddr) +_conn_track_is_relevant_sett_conn(NMSettingsConnection * sett_conn, + NMBluetoothCapabilities *out_bt_type, + const char ** out_bdaddr) { - NMConnection *connection; + NMConnection *connection; - connection = nm_settings_connection_get_connection (sett_conn); - if (!connection) - return FALSE; + connection = nm_settings_connection_get_connection(sett_conn); + if (!connection) + return FALSE; - return _conn_track_is_relevant_connection (connection, out_bt_type, out_bdaddr); + return _conn_track_is_relevant_connection(connection, out_bt_type, out_bdaddr); } static gboolean -_conn_track_is_relevant_for_sett_conn (NMSettingsConnection *sett_conn, - NMBluetoothCapabilities bt_type, - const char *bdaddr) +_conn_track_is_relevant_for_sett_conn(NMSettingsConnection * sett_conn, + NMBluetoothCapabilities bt_type, + const char * bdaddr) { - NMBluetoothCapabilities x_bt_type; - const char *x_bdaddr; + NMBluetoothCapabilities x_bt_type; + const char * x_bdaddr; - return bdaddr - && _conn_track_is_relevant_sett_conn (sett_conn, &x_bt_type, &x_bdaddr) - && x_bt_type == bt_type - && nm_streq (x_bdaddr, bdaddr); + return bdaddr && _conn_track_is_relevant_sett_conn(sett_conn, &x_bt_type, &x_bdaddr) + && x_bt_type == bt_type && nm_streq(x_bdaddr, bdaddr); } static void -_conn_track_schedule_notify (NMBluezManager *self, - NMBluetoothCapabilities bt_type, - const char *bdaddr) +_conn_track_schedule_notify(NMBluezManager * self, + NMBluetoothCapabilities bt_type, + const char * bdaddr) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - GHashTableIter iter; - BzDBusObj *bzobj; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + GHashTableIter iter; + BzDBusObj * bzobj; - g_hash_table_iter_init (&iter, priv->bzobjs); - while (g_hash_table_iter_next (&iter, (gpointer *) &bzobj, NULL)) { - gboolean device_is_usable; + g_hash_table_iter_init(&iter, priv->bzobjs); + while (g_hash_table_iter_next(&iter, (gpointer *) &bzobj, NULL)) { + gboolean device_is_usable; - device_is_usable = _bzobjs_device_is_usable (bzobj, NULL, NULL); - if (bzobj->x_device_is_usable != device_is_usable) - _process_change_idle_schedule (self, bzobj); - } + device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, NULL); + if (bzobj->x_device_is_usable != device_is_usable) + _process_change_idle_schedule(self, bzobj); + } } static void -_conn_track_update (NMBluezManager *self, - NMSettingsConnection *sett_conn, - gboolean track, - gboolean *out_changed, - gboolean *out_changed_usable, - ConnDataElem **out_conn_data_elem) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - ConnDataHead *cdata_hd; - ConnDataElem *cdata_el; - ConnDataElem *cdata_el_remove = NULL; - NMBluetoothCapabilities bt_type; - const char *bdaddr; - gboolean changed = FALSE; - gboolean changed_usable = FALSE; - char sbuf_cap[100]; - - nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn)); - - cdata_el = _conn_track_find_elem (self, sett_conn); - - if (track) - track = _conn_track_is_relevant_sett_conn (sett_conn, &bt_type, &bdaddr); - - if (!track) { - cdata_el_remove = g_steal_pointer (&cdata_el); - goto out_remove; - } - - if (cdata_el) { - cdata_hd = cdata_el->cdata_hd; - if ( cdata_hd->bt_type != bt_type - || !nm_streq (cdata_hd->bdaddr, bdaddr)) - cdata_el_remove = g_steal_pointer (&cdata_el); - } - - if (!cdata_el) { - _LOGT ("connecton: track for %s, %s: %s (%s)", - nm_bluetooth_capability_to_string (bt_type, sbuf_cap, sizeof (sbuf_cap)), - bdaddr, - nm_settings_connection_get_uuid (sett_conn), - nm_settings_connection_get_id (sett_conn)); - changed = TRUE; - cdata_hd = _conn_track_find_head (self, bt_type, bdaddr); - if (!cdata_hd) { - changed_usable = TRUE; - cdata_hd = _conn_data_head_new (bt_type, bdaddr); - if (!g_hash_table_add (priv->conn_data_heads, cdata_hd)) - nm_assert_not_reached (); - _conn_track_schedule_notify (self, bt_type, bdaddr); - } - cdata_el = g_slice_new (ConnDataElem); - cdata_el->sett_conn = sett_conn; - cdata_el->cdata_hd = cdata_hd; - c_list_link_tail (&cdata_hd->lst_head, &cdata_el->lst); - if (!g_hash_table_add (priv->conn_data_elems, cdata_el)) - nm_assert_not_reached (); - } +_conn_track_update(NMBluezManager * self, + NMSettingsConnection *sett_conn, + gboolean track, + gboolean * out_changed, + gboolean * out_changed_usable, + ConnDataElem ** out_conn_data_elem) +{ + NMBluezManagerPrivate * priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + ConnDataHead * cdata_hd; + ConnDataElem * cdata_el; + ConnDataElem * cdata_el_remove = NULL; + NMBluetoothCapabilities bt_type; + const char * bdaddr; + gboolean changed = FALSE; + gboolean changed_usable = FALSE; + char sbuf_cap[100]; + + nm_assert(NM_IS_SETTINGS_CONNECTION(sett_conn)); + + cdata_el = _conn_track_find_elem(self, sett_conn); + + if (track) + track = _conn_track_is_relevant_sett_conn(sett_conn, &bt_type, &bdaddr); + + if (!track) { + cdata_el_remove = g_steal_pointer(&cdata_el); + goto out_remove; + } + + if (cdata_el) { + cdata_hd = cdata_el->cdata_hd; + if (cdata_hd->bt_type != bt_type || !nm_streq(cdata_hd->bdaddr, bdaddr)) + cdata_el_remove = g_steal_pointer(&cdata_el); + } + + if (!cdata_el) { + _LOGT("connection: track for %s, %s: %s (%s)", + nm_bluetooth_capability_to_string(bt_type, sbuf_cap, sizeof(sbuf_cap)), + bdaddr, + nm_settings_connection_get_uuid(sett_conn), + nm_settings_connection_get_id(sett_conn)); + changed = TRUE; + cdata_hd = _conn_track_find_head(self, bt_type, bdaddr); + if (!cdata_hd) { + changed_usable = TRUE; + cdata_hd = _conn_data_head_new(bt_type, bdaddr); + if (!g_hash_table_add(priv->conn_data_heads, cdata_hd)) + nm_assert_not_reached(); + _conn_track_schedule_notify(self, bt_type, bdaddr); + } + cdata_el = g_slice_new(ConnDataElem); + cdata_el->sett_conn = sett_conn; + cdata_el->cdata_hd = cdata_hd; + c_list_link_tail(&cdata_hd->lst_head, &cdata_el->lst); + if (!g_hash_table_add(priv->conn_data_elems, cdata_el)) + nm_assert_not_reached(); + } out_remove: - if (cdata_el_remove) { - GHashTableIter iter; - BzDBusObj *bzobj; - - _LOGT ("connecton: untrack for %s, %s: %s (%s)", - nm_bluetooth_capability_to_string (cdata_el_remove->cdata_hd->bt_type, sbuf_cap, sizeof (sbuf_cap)), - cdata_el_remove->cdata_hd->bdaddr, - nm_settings_connection_get_uuid (sett_conn), - nm_settings_connection_get_id (sett_conn)); - - g_hash_table_iter_init (&iter, priv->bzobjs); - while (g_hash_table_iter_next (&iter, (gpointer *) &bzobj, NULL)) { - if (bzobj->x_device.panu_connection == sett_conn) - bzobj->x_device.panu_connection = NULL; - } - - changed = TRUE; - cdata_hd = cdata_el_remove->cdata_hd; - c_list_unlink_stale (&cdata_el_remove->lst); - if (!g_hash_table_remove (priv->conn_data_elems, cdata_el_remove)) - nm_assert_not_reached (); - if (c_list_is_empty (&cdata_hd->lst_head)) { - changed_usable = TRUE; - _conn_track_schedule_notify (self, cdata_hd->bt_type, cdata_hd->bdaddr); - if (!g_hash_table_remove (priv->conn_data_heads, cdata_hd)) - nm_assert_not_reached (); - } - } - - NM_SET_OUT (out_changed, changed); - NM_SET_OUT (out_changed_usable, changed_usable); - NM_SET_OUT (out_conn_data_elem, cdata_el); + if (cdata_el_remove) { + GHashTableIter iter; + BzDBusObj * bzobj; + + _LOGT("connection: untrack for %s, %s: %s (%s)", + nm_bluetooth_capability_to_string(cdata_el_remove->cdata_hd->bt_type, + sbuf_cap, + sizeof(sbuf_cap)), + cdata_el_remove->cdata_hd->bdaddr, + nm_settings_connection_get_uuid(sett_conn), + nm_settings_connection_get_id(sett_conn)); + + g_hash_table_iter_init(&iter, priv->bzobjs); + while (g_hash_table_iter_next(&iter, (gpointer *) &bzobj, NULL)) { + if (bzobj->x_device.panu_connection == sett_conn) + bzobj->x_device.panu_connection = NULL; + } + + changed = TRUE; + cdata_hd = cdata_el_remove->cdata_hd; + c_list_unlink_stale(&cdata_el_remove->lst); + if (!g_hash_table_remove(priv->conn_data_elems, cdata_el_remove)) + nm_assert_not_reached(); + if (c_list_is_empty(&cdata_hd->lst_head)) { + changed_usable = TRUE; + _conn_track_schedule_notify(self, cdata_hd->bt_type, cdata_hd->bdaddr); + if (!g_hash_table_remove(priv->conn_data_heads, cdata_hd)) + nm_assert_not_reached(); + } + } + + NM_SET_OUT(out_changed, changed); + NM_SET_OUT(out_changed_usable, changed_usable); + NM_SET_OUT(out_conn_data_elem, cdata_el); } /*****************************************************************************/ static void -cp_connection_added (NMSettings *settings, - NMSettingsConnection *sett_conn, - NMBluezManager *self) +cp_connection_added(NMSettings *settings, NMSettingsConnection *sett_conn, NMBluezManager *self) { - _conn_track_update (self, sett_conn, TRUE, NULL, NULL, NULL); + _conn_track_update(self, sett_conn, TRUE, NULL, NULL, NULL); } static void -cp_connection_updated (NMSettings *settings, - NMSettingsConnection *sett_conn, - guint update_reason_u, - NMBluezManager *self) +cp_connection_updated(NMSettings * settings, + NMSettingsConnection *sett_conn, + guint update_reason_u, + NMBluezManager * self) { - _conn_track_update (self, sett_conn, TRUE, NULL, NULL, NULL); + _conn_track_update(self, sett_conn, TRUE, NULL, NULL, NULL); } static void -cp_connection_removed (NMSettings *settings, - NMSettingsConnection *sett_conn, - NMBluezManager *self) +cp_connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, NMBluezManager *self) { - _conn_track_update (self, sett_conn, FALSE, NULL, NULL, NULL); + _conn_track_update(self, sett_conn, FALSE, NULL, NULL, NULL); } /*****************************************************************************/ static NMBluezManager * -_network_server_get_bluez_manager (const NMBtVTableNetworkServer *vtable_network_server) +_network_server_get_bluez_manager(const NMBtVTableNetworkServer *vtable_network_server) { - NMBluezManager *self; + NMBluezManager *self; - self = (NMBluezManager *) (((char *) vtable_network_server) - G_STRUCT_OFFSET (NMBluezManager, _priv.vtable_network_server)); + self = (NMBluezManager *) (((char *) vtable_network_server) + - G_STRUCT_OFFSET(NMBluezManager, _priv.vtable_network_server)); - g_return_val_if_fail (NM_IS_BLUEZ_MANAGER (self), NULL); + g_return_val_if_fail(NM_IS_BLUEZ_MANAGER(self), NULL); - return self; + return self; } static BzDBusObj * -_network_server_find_has_device (NMBluezManagerPrivate *priv, - NMDevice *device) +_network_server_find_has_device(NMBluezManagerPrivate *priv, NMDevice *device) { - BzDBusObj *bzobj; + BzDBusObj *bzobj; - c_list_for_each_entry (bzobj, &priv->network_server_lst_head, x_network_server.lst) { - if (bzobj->x_network_server.device_br == device) - return bzobj; - } - return NULL; + c_list_for_each_entry (bzobj, &priv->network_server_lst_head, x_network_server.lst) { + if (bzobj->x_network_server.device_br == device) + return bzobj; + } + return NULL; } static BzDBusObj * -_network_server_find_available (NMBluezManagerPrivate *priv, - const char *addr, - NMDevice *device_accept_busy) -{ - BzDBusObj *bzobj; - - c_list_for_each_entry (bzobj, &priv->network_server_lst_head, x_network_server.lst) { - if (bzobj->x_network_server.device_br) { - if (bzobj->x_network_server.device_br != device_accept_busy) - continue; - } - if ( addr - && !nm_streq (addr, bzobj->d_adapter.address)) - continue; - nm_assert (!bzobj->x_network_server.r_req_data); - return bzobj; - } - return NULL; +_network_server_find_available(NMBluezManagerPrivate *priv, + const char * addr, + NMDevice * device_accept_busy) +{ + BzDBusObj *bzobj; + + c_list_for_each_entry (bzobj, &priv->network_server_lst_head, x_network_server.lst) { + if (bzobj->x_network_server.device_br) { + if (bzobj->x_network_server.device_br != device_accept_busy) + continue; + } + if (addr && !nm_streq(addr, bzobj->d_adapter.address)) + continue; + nm_assert(!bzobj->x_network_server.r_req_data); + return bzobj; + } + return NULL; } static gboolean -_network_server_vt_is_available (const NMBtVTableNetworkServer *vtable, - const char *addr, - NMDevice *device_accept_busy) +_network_server_vt_is_available(const NMBtVTableNetworkServer *vtable, + const char * addr, + NMDevice * device_accept_busy) { - NMBluezManager *self = _network_server_get_bluez_manager (vtable); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + NMBluezManager * self = _network_server_get_bluez_manager(vtable); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - return !!_network_server_find_available (priv, addr, device_accept_busy); + return !!_network_server_find_available(priv, addr, device_accept_busy); } static void -_network_server_register_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_network_server_register_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - gs_unref_variant GVariant *ret = NULL; - gs_free_error GError *error = NULL; - BzDBusObj *bzobj; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + BzDBusObj * bzobj; - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); - if ( !ret - && nm_utils_error_is_cancelled (error)) - return; + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source_object), res, &error); + if (!ret && nm_utils_error_is_cancelled(error)) + return; - bzobj = user_data; + bzobj = user_data; - if (!ret) { - _LOGT ("NAP: [%s]: registering failed: %s", bzobj->object_path, error->message); - } else - _LOGT ("NAP: [%s]: registration successful", bzobj->object_path); + if (!ret) { + _LOGT("NAP: [%s]: registering failed: %s", bzobj->object_path, error->message); + } else + _LOGT("NAP: [%s]: registration successful", bzobj->object_path); - g_clear_object (&bzobj->x_network_server.r_req_data->int_cancellable); - _network_server_register_req_data_complete (g_steal_pointer (&bzobj->x_network_server.r_req_data), error); + g_clear_object(&bzobj->x_network_server.r_req_data->int_cancellable); + _network_server_register_req_data_complete(g_steal_pointer(&bzobj->x_network_server.r_req_data), + error); } static void -_network_server_register_cancelled_cb (GCancellable *cancellable, - BzDBusObj *bzobj) +_network_server_register_cancelled_cb(GCancellable *cancellable, BzDBusObj *bzobj) { - _network_server_unregister_bridge (bzobj->self, bzobj, "registration cancelled"); + _network_server_unregister_bridge(bzobj->self, bzobj, "registration cancelled"); } static gboolean -_network_server_vt_register_bridge (const NMBtVTableNetworkServer *vtable, - const char *addr, - NMDevice *device, - GCancellable *cancellable, - NMBtVTableRegisterCallback callback, - gpointer callback_user_data, - GError **error) -{ - NMBluezManager *self = _network_server_get_bluez_manager (vtable); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - NetworkServerRegisterReqData *r_req_data; - BzDBusObj *bzobj; - const char *ifname; - - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE); - - nm_assert (!g_cancellable_is_cancelled (cancellable)); - nm_assert (!_network_server_find_has_device (priv, device)); - - ifname = nm_device_get_iface (device); - g_return_val_if_fail (ifname, FALSE); - - g_return_val_if_fail (ifname, FALSE); - - bzobj = _network_server_find_available (priv, addr, NULL); - if (!bzobj) { - /* The device checked that a network server is available, before - * starting the activation, but for some reason it no longer is. - * Indicate that the activation should not proceed. */ - if (addr) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "adapter %s is not available for %s", - addr, ifname); - } else { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "no adapter available for %s", - ifname); - } - return FALSE; - } - - _LOGD ("NAP: [%s]: registering \"%s\" on adapter %s", - bzobj->object_path, - ifname, - bzobj->d_adapter.address); - - r_req_data = g_slice_new (NetworkServerRegisterReqData); - *r_req_data = (NetworkServerRegisterReqData) { - .int_cancellable = g_cancellable_new (), - .ext_cancellable = g_object_ref (cancellable), - .callback = callback, - .callback_user_data = callback_user_data, - .ext_cancelled_id = g_signal_connect (cancellable, - "cancelled", - G_CALLBACK (_network_server_register_cancelled_cb), - bzobj), - }; - - bzobj->x_network_server.device_br = g_object_ref (device); - bzobj->x_network_server.r_req_data = r_req_data; - - g_dbus_connection_call (priv->dbus_connection, - priv->name_owner, - bzobj->object_path, - NM_BLUEZ5_NETWORK_SERVER_INTERFACE, - "Register", - g_variant_new ("(ss)", - BLUETOOTH_CONNECT_NAP, - ifname), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - bzobj->x_network_server.r_req_data->int_cancellable, - _network_server_register_cb, - bzobj); - return TRUE; +_network_server_vt_register_bridge(const NMBtVTableNetworkServer *vtable, + const char * addr, + NMDevice * device, + GCancellable * cancellable, + NMBtVTableRegisterCallback callback, + gpointer callback_user_data, + GError ** error) +{ + NMBluezManager * self = _network_server_get_bluez_manager(vtable); + NMBluezManagerPrivate * priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + NetworkServerRegisterReqData *r_req_data; + BzDBusObj * bzobj; + const char * ifname; + + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(G_IS_CANCELLABLE(cancellable), FALSE); + + nm_assert(!g_cancellable_is_cancelled(cancellable)); + nm_assert(!_network_server_find_has_device(priv, device)); + + ifname = nm_device_get_iface(device); + g_return_val_if_fail(ifname, FALSE); + + g_return_val_if_fail(ifname, FALSE); + + bzobj = _network_server_find_available(priv, addr, NULL); + if (!bzobj) { + /* The device checked that a network server is available, before + * starting the activation, but for some reason it no longer is. + * Indicate that the activation should not proceed. */ + if (addr) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "adapter %s is not available for %s", + addr, + ifname); + } else { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "no adapter available for %s", + ifname); + } + return FALSE; + } + + _LOGD("NAP: [%s]: registering \"%s\" on adapter %s", + bzobj->object_path, + ifname, + bzobj->d_adapter.address); + + r_req_data = g_slice_new(NetworkServerRegisterReqData); + *r_req_data = (NetworkServerRegisterReqData){ + .int_cancellable = g_cancellable_new(), + .ext_cancellable = g_object_ref(cancellable), + .callback = callback, + .callback_user_data = callback_user_data, + .ext_cancelled_id = g_signal_connect(cancellable, + "cancelled", + G_CALLBACK(_network_server_register_cancelled_cb), + bzobj), + }; + + bzobj->x_network_server.device_br = g_object_ref(device); + bzobj->x_network_server.r_req_data = r_req_data; + + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + bzobj->object_path, + NM_BLUEZ5_NETWORK_SERVER_INTERFACE, + "Register", + g_variant_new("(ss)", BLUETOOTH_CONNECT_NAP, ifname), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + bzobj->x_network_server.r_req_data->int_cancellable, + _network_server_register_cb, + bzobj); + return TRUE; } static void -_network_server_unregister_bridge_complete_on_idle_cb (gpointer user_data, - GCancellable *cancellable) +_network_server_unregister_bridge_complete_on_idle_cb(gpointer user_data, GCancellable *cancellable) { - gs_free_error GError *error = NULL; - gs_free char *reason = NULL; - NetworkServerRegisterReqData *r_req_data; + gs_free_error GError * error = NULL; + gs_free char * reason = NULL; + NetworkServerRegisterReqData *r_req_data; - nm_utils_user_data_unpack (user_data, &r_req_data, &reason); + nm_utils_user_data_unpack(user_data, &r_req_data, &reason); - nm_utils_error_set (&error, NM_UTILS_ERROR_UNKNOWN, - "registration was aborted due to %s", - reason); - _network_server_register_req_data_complete (r_req_data, error); + nm_utils_error_set(&error, + NM_UTILS_ERROR_UNKNOWN, + "registration was aborted due to %s", + reason); + _network_server_register_req_data_complete(r_req_data, error); } static void -_network_server_unregister_bridge (NMBluezManager *self, - BzDBusObj *bzobj, - const char *reason) +_network_server_unregister_bridge(NMBluezManager *self, BzDBusObj *bzobj, const char *reason) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - _nm_unused gs_unref_object NMDevice *device = NULL; - NetworkServerRegisterReqData *r_req_data; + NMBluezManagerPrivate * priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + _nm_unused gs_unref_object NMDevice *device = NULL; + NetworkServerRegisterReqData * r_req_data; - nm_assert (NM_IS_DEVICE (bzobj->x_network_server.device_br)); + nm_assert(NM_IS_DEVICE(bzobj->x_network_server.device_br)); - _LOGD ("NAP: [%s]: unregistering \"%s\" (%s)", - bzobj->object_path, - nm_device_get_iface (bzobj->x_network_server.device_br), - reason); + _LOGD("NAP: [%s]: unregistering \"%s\" (%s)", + bzobj->object_path, + nm_device_get_iface(bzobj->x_network_server.device_br), + reason); - device = g_steal_pointer (&bzobj->x_network_server.device_br); + device = g_steal_pointer(&bzobj->x_network_server.device_br); - r_req_data = g_steal_pointer (&bzobj->x_network_server.r_req_data); + r_req_data = g_steal_pointer(&bzobj->x_network_server.r_req_data); - if (priv->name_owner) { - gs_unref_object GCancellable *cancellable = NULL; + if (priv->name_owner) { + gs_unref_object GCancellable *cancellable = NULL; - cancellable = g_cancellable_new (); + cancellable = g_cancellable_new(); - nm_shutdown_wait_obj_register_cancellable_full (cancellable, - g_strdup_printf ("bt-unregister-nap[%s]", bzobj->object_path), - TRUE); + nm_shutdown_wait_obj_register_cancellable_full( + cancellable, + g_strdup_printf("bt-unregister-nap[%s]", bzobj->object_path), + TRUE); - g_dbus_connection_call (priv->dbus_connection, - priv->name_owner, - bzobj->object_path, - NM_BLUEZ5_NETWORK_SERVER_INTERFACE, - "Unregister", - g_variant_new ("(s)", BLUETOOTH_CONNECT_NAP), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - cancellable, - _dbus_call_complete_cb_nop, - NULL); - } + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + bzobj->object_path, + NM_BLUEZ5_NETWORK_SERVER_INTERFACE, + "Unregister", + g_variant_new("(s)", BLUETOOTH_CONNECT_NAP), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + cancellable, + _dbus_call_complete_cb_nop, + NULL); + } - if (r_req_data) { - nm_clear_g_cancellable (&r_req_data->int_cancellable); - nm_utils_invoke_on_idle (r_req_data->ext_cancellable, - _network_server_unregister_bridge_complete_on_idle_cb, - nm_utils_user_data_pack (r_req_data, g_strdup (reason))); - } + if (r_req_data) { + nm_clear_g_cancellable(&r_req_data->int_cancellable); + nm_utils_invoke_on_idle(r_req_data->ext_cancellable, + _network_server_unregister_bridge_complete_on_idle_cb, + nm_utils_user_data_pack(r_req_data, g_strdup(reason))); + } - _nm_device_bridge_notify_unregister_bt_nap (device, reason); + _nm_device_bridge_notify_unregister_bt_nap(device, reason); } static gboolean -_network_server_vt_unregister_bridge (const NMBtVTableNetworkServer *vtable, - NMDevice *device) +_network_server_vt_unregister_bridge(const NMBtVTableNetworkServer *vtable, NMDevice *device) { - NMBluezManager *self = _network_server_get_bluez_manager (vtable); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - BzDBusObj *bzobj; + NMBluezManager * self = _network_server_get_bluez_manager(vtable); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + BzDBusObj * bzobj; - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); - bzobj = _network_server_find_has_device (priv, device); - if (bzobj) - _network_server_unregister_bridge (self, bzobj, "disconnecting"); + bzobj = _network_server_find_has_device(priv, device); + if (bzobj) + _network_server_unregister_bridge(self, bzobj, "disconnecting"); - return TRUE; + return TRUE; } static void -_network_server_process_change (BzDBusObj *bzobj, - gboolean *out_emit_device_availability_changed) +_network_server_process_change(BzDBusObj *bzobj, gboolean *out_emit_device_availability_changed) { - NMBluezManager *self = bzobj->self; - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - gboolean network_server_is_usable; - gboolean emit_device_availability_changed = FALSE; - - network_server_is_usable = _bzobjs_network_server_is_usable (bzobj, TRUE); - - if (!network_server_is_usable) { + NMBluezManager * self = bzobj->self; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + gboolean network_server_is_usable; + gboolean emit_device_availability_changed = FALSE; - if (!c_list_is_empty (&bzobj->x_network_server.lst)) { - emit_device_availability_changed = TRUE; - c_list_unlink (&bzobj->x_network_server.lst); - } + network_server_is_usable = _bzobjs_network_server_is_usable(bzobj, TRUE); - nm_clear_g_free (&bzobj->x_network_server.adapter_address); + if (!network_server_is_usable) { + if (!c_list_is_empty(&bzobj->x_network_server.lst)) { + emit_device_availability_changed = TRUE; + c_list_unlink(&bzobj->x_network_server.lst); + } - if (bzobj->x_network_server.device_br) { - _network_server_unregister_bridge (self, - bzobj, - _bzobjs_network_server_is_usable (bzobj, FALSE) - ? "adapter disabled" - : "adapter disappeared"); - } + nm_clear_g_free(&bzobj->x_network_server.adapter_address); - } else { + if (bzobj->x_network_server.device_br) { + _network_server_unregister_bridge(self, + bzobj, + _bzobjs_network_server_is_usable(bzobj, FALSE) + ? "adapter disabled" + : "adapter disappeared"); + } - if (!nm_streq0 (bzobj->x_network_server.adapter_address, bzobj->d_adapter.address)) { - emit_device_availability_changed = TRUE; - g_free (bzobj->x_network_server.adapter_address); - bzobj->x_network_server.adapter_address = g_strdup (bzobj->d_adapter.address); - } + } else { + if (!nm_streq0(bzobj->x_network_server.adapter_address, bzobj->d_adapter.address)) { + emit_device_availability_changed = TRUE; + g_free(bzobj->x_network_server.adapter_address); + bzobj->x_network_server.adapter_address = g_strdup(bzobj->d_adapter.address); + } - if (c_list_is_empty (&bzobj->x_network_server.lst)) { - emit_device_availability_changed = TRUE; - c_list_link_tail (&priv->network_server_lst_head, &bzobj->x_network_server.lst); - } + if (c_list_is_empty(&bzobj->x_network_server.lst)) { + emit_device_availability_changed = TRUE; + c_list_link_tail(&priv->network_server_lst_head, &bzobj->x_network_server.lst); + } + } - } - - if (emit_device_availability_changed) - NM_SET_OUT (out_emit_device_availability_changed, TRUE); + if (emit_device_availability_changed) + NM_SET_OUT(out_emit_device_availability_changed, TRUE); } /*****************************************************************************/ static void -_conn_create_panu_connection (NMBluezManager *self, - BzDBusObj *bzobj) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *added; - NMSetting *setting; - gs_free char *id = NULL; - char uuid[37]; - gs_free_error GError *error = NULL; - - nm_utils_uuid_generate_buf (uuid); - id = g_strdup_printf (_("%s Network"), bzobj->d_device.name); - - connection = nm_simple_connection_new (); - - setting = nm_setting_connection_new (); - g_object_set (setting, - NM_SETTING_CONNECTION_ID, id, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME, - NULL); - nm_connection_add_setting (connection, setting); - - setting = nm_setting_bluetooth_new (); - g_object_set (setting, - NM_SETTING_BLUETOOTH_BDADDR, bzobj->d_device.address, - NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, - NULL); - nm_connection_add_setting (connection, setting); - - if (!nm_connection_normalize (connection, NULL, NULL, &error)) { - _LOGE ("connection: couldn't generate a connection for NAP device: %s", - error->message); - g_return_if_reached (); - } - - nm_assert (_conn_track_is_relevant_connection (connection, NULL, NULL)); - - _LOGT ("connection: create in-memory PANU connection %s (%s) for device \"%s\" (%s)", - uuid, - id, - bzobj->d_device.name, - bzobj->d_device.address); - - nm_settings_add_connection (priv->settings, - connection, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, - NM_SETTINGS_CONNECTION_ADD_REASON_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, - &added, - &error); - if (!added) { - _LOGW ("connection: couldn't add new Bluetooth connection for NAP device: '%s' (%s): %s", - id, uuid, error->message); - return; - } - - if ( !_conn_track_is_relevant_for_sett_conn (added, NM_BT_CAPABILITY_NAP, bzobj->d_device.address) - || !_conn_track_find_elem (self, added) - || bzobj->x_device.panu_connection) { - _LOGE ("connection: something went wrong creating PANU connection %s (%s) for device '%s'", - uuid, id, bzobj->d_device.address); - g_return_if_reached (); - } - - bzobj->x_device.panu_connection = added; +_conn_create_panu_connection(NMBluezManager *self, BzDBusObj *bzobj) +{ + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + gs_unref_object NMConnection *connection = NULL; + NMSettingsConnection * added; + NMSetting * setting; + gs_free char * id = NULL; + char uuid[37]; + gs_free_error GError *error = NULL; + + nm_utils_uuid_generate_buf(uuid); + id = g_strdup_printf(_("%s Network"), bzobj->d_device.name); + + connection = nm_simple_connection_new(); + + setting = nm_setting_connection_new(); + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + id, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_BLUETOOTH_SETTING_NAME, + NULL); + nm_connection_add_setting(connection, setting); + + setting = nm_setting_bluetooth_new(); + g_object_set(setting, + NM_SETTING_BLUETOOTH_BDADDR, + bzobj->d_device.address, + NM_SETTING_BLUETOOTH_TYPE, + NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + nm_connection_add_setting(connection, setting); + + if (!nm_connection_normalize(connection, NULL, NULL, &error)) { + _LOGE("connection: couldn't generate a connection for NAP device: %s", error->message); + g_return_if_reached(); + } + + nm_assert(_conn_track_is_relevant_connection(connection, NULL, NULL)); + + _LOGT("connection: create in-memory PANU connection %s (%s) for device \"%s\" (%s)", + uuid, + id, + bzobj->d_device.name, + bzobj->d_device.address); + + nm_settings_add_connection(priv->settings, + connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, + NM_SETTINGS_CONNECTION_ADD_REASON_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, + &added, + &error); + if (!added) { + _LOGW("connection: couldn't add new Bluetooth connection for NAP device: '%s' (%s): %s", + id, + uuid, + error->message); + return; + } + + if (!_conn_track_is_relevant_for_sett_conn(added, NM_BT_CAPABILITY_NAP, bzobj->d_device.address) + || !_conn_track_find_elem(self, added) || bzobj->x_device.panu_connection) { + _LOGE("connection: something went wrong creating PANU connection %s (%s) for device '%s'", + uuid, + id, + bzobj->d_device.address); + g_return_if_reached(); + } + + bzobj->x_device.panu_connection = added; } /*****************************************************************************/ static void -_device_state_changed_cb (NMDevice *device, - guint new_state_u, - guint old_state_u, - guint reason_u, - gpointer user_data) +_device_state_changed_cb(NMDevice *device, + guint new_state_u, + guint old_state_u, + guint reason_u, + gpointer user_data) { - BzDBusObj *bzobj = user_data; + BzDBusObj *bzobj = user_data; - if (!_bzobjs_device_is_usable (bzobj, NULL, NULL)) { - /* the device got unusable? Need to revisit it... */ - _process_change_idle_schedule (bzobj->self, bzobj); - } + if (!_bzobjs_device_is_usable(bzobj, NULL, NULL)) { + /* the device got unusable? Need to revisit it... */ + _process_change_idle_schedule(bzobj->self, bzobj); + } } static void -_device_process_change (BzDBusObj *bzobj) -{ - NMBluezManager *self = bzobj->self; - gs_unref_object NMDeviceBt *device_added = NULL; - gs_unref_object NMDeviceBt *device_deleted = NULL; - gboolean device_is_usable; - gboolean create_panu_connection = FALSE; - - device_is_usable = _bzobjs_device_is_usable (bzobj, NULL, &create_panu_connection); - - if (create_panu_connection) { - bzobj->x_device_panu_connection_allow_create = FALSE; - _conn_create_panu_connection (self, bzobj); - device_is_usable = _bzobjs_device_is_usable (bzobj, NULL, NULL); - } else { - if ( device_is_usable - && bzobj->x_device_panu_connection_allow_create - && NM_FLAGS_HAS (bzobj->d_device_capabilities, NM_BT_CAPABILITY_NAP) - && _conn_track_find_head (self, NM_BT_CAPABILITY_NAP, bzobj->d_device.address) ) { - /* We have a useable device and also a panu-connection. We block future attemps - * to generate a connection. */ - bzobj->x_device_panu_connection_allow_create = FALSE; - } - if (bzobj->x_device.panu_connection) { - if (!NM_FLAGS_HAS (nm_settings_connection_get_flags (bzobj->x_device.panu_connection), - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) { - /* the connection that we generated earlier still exists, but it's not longer the same - * as it was when we created it. Forget about it, so that we don't delete the profile later... */ - bzobj->x_device.panu_connection = NULL; - } else { - if ( !device_is_usable - || !_conn_track_is_relevant_for_sett_conn (bzobj->x_device.panu_connection, - NM_BT_CAPABILITY_NAP, - bzobj->d_device.address)) { - _LOGT ("connection: delete in-memory PANU connection %s (%s) as device %s", - nm_settings_connection_get_uuid (bzobj->x_device.panu_connection), - nm_settings_connection_get_id (bzobj->x_device.panu_connection), - !device_is_usable ? "is now unusable" : "no longer matches"); - bzobj->x_device_panu_connection_allow_create = TRUE; - nm_settings_connection_delete (g_steal_pointer (&bzobj->x_device.panu_connection), FALSE); - } - } - } - } - - bzobj->x_device_is_connected = device_is_usable - && _bzobjs_device_is_connected (bzobj); - - bzobj->x_device_is_usable = device_is_usable; - - if (bzobj->x_device.device_bt) { - const char *device_to_delete_msg; - - if (!device_is_usable) - device_to_delete_msg = "device became unusable"; - else if (!_nm_device_bt_for_same_device (bzobj->x_device.device_bt, - bzobj->object_path, - bzobj->d_device.address, - NULL, - bzobj->d_device_capabilities)) - device_to_delete_msg = "device is no longer compatible"; - else - device_to_delete_msg = NULL; - - if (device_to_delete_msg) { - nm_clear_g_signal_handler (bzobj->x_device.device_bt, &bzobj->x_device.device_bt_signal_id); - - device_deleted = g_steal_pointer (&bzobj->x_device.device_bt); - - _LOGD ("[%s]: drop device because %s", - bzobj->object_path, - device_to_delete_msg); - - _connect_disconnect (self, bzobj, device_to_delete_msg); - } - } - - if (device_is_usable) { - if (!bzobj->x_device.device_bt) { - bzobj->x_device.device_bt = nm_device_bt_new (self, - bzobj->object_path, - bzobj->d_device.address, - bzobj->d_device.name, - bzobj->d_device_capabilities); - device_added = g_object_ref (bzobj->x_device.device_bt); - bzobj->x_device.device_bt_signal_id = g_signal_connect (device_added, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (_device_state_changed_cb), - bzobj); - } else - _nm_device_bt_notify_set_name (bzobj->x_device.device_bt, bzobj->d_device.name); - - _nm_device_bt_notify_set_connected (bzobj->x_device.device_bt, bzobj->x_device_is_connected); - } - - if ( bzobj->x_device.c_req_data - && !bzobj->x_device.c_req_data->int_cancellable - && bzobj->x_device_is_connected) { - gs_free char *device_name = g_steal_pointer (&bzobj->x_device.c_req_data->device_name); - - _device_connect_req_data_complete (g_steal_pointer (&bzobj->x_device.c_req_data), - self, - device_name, - NULL); - } - - if (device_added) - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device_added); - - if (device_deleted) - _nm_device_bt_notify_removed (device_deleted); +_device_process_change(BzDBusObj *bzobj) +{ + NMBluezManager *self = bzobj->self; + gs_unref_object NMDeviceBt *device_added = NULL; + gs_unref_object NMDeviceBt *device_deleted = NULL; + gboolean device_is_usable; + gboolean create_panu_connection = FALSE; + + device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, &create_panu_connection); + + if (create_panu_connection) { + bzobj->x_device_panu_connection_allow_create = FALSE; + _conn_create_panu_connection(self, bzobj); + device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, NULL); + } else { + if (device_is_usable && bzobj->x_device_panu_connection_allow_create + && NM_FLAGS_HAS(bzobj->d_device_capabilities, NM_BT_CAPABILITY_NAP) + && _conn_track_find_head(self, NM_BT_CAPABILITY_NAP, bzobj->d_device.address)) { + /* We have a useable device and also a panu-connection. We block future attemps + * to generate a connection. */ + bzobj->x_device_panu_connection_allow_create = FALSE; + } + if (bzobj->x_device.panu_connection) { + if (!NM_FLAGS_HAS(nm_settings_connection_get_flags(bzobj->x_device.panu_connection), + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) { + /* the connection that we generated earlier still exists, but it's not longer the same + * as it was when we created it. Forget about it, so that we don't delete the profile later... */ + bzobj->x_device.panu_connection = NULL; + } else { + if (!device_is_usable + || !_conn_track_is_relevant_for_sett_conn(bzobj->x_device.panu_connection, + NM_BT_CAPABILITY_NAP, + bzobj->d_device.address)) { + _LOGT("connection: delete in-memory PANU connection %s (%s) as device %s", + nm_settings_connection_get_uuid(bzobj->x_device.panu_connection), + nm_settings_connection_get_id(bzobj->x_device.panu_connection), + !device_is_usable ? "is now unusable" : "no longer matches"); + bzobj->x_device_panu_connection_allow_create = TRUE; + nm_settings_connection_delete(g_steal_pointer(&bzobj->x_device.panu_connection), + FALSE); + } + } + } + } + + bzobj->x_device_is_connected = device_is_usable && _bzobjs_device_is_connected(bzobj); + + bzobj->x_device_is_usable = device_is_usable; + + if (bzobj->x_device.device_bt) { + const char *device_to_delete_msg; + + if (!device_is_usable) + device_to_delete_msg = "device became unusable"; + else if (!_nm_device_bt_for_same_device(bzobj->x_device.device_bt, + bzobj->object_path, + bzobj->d_device.address, + NULL, + bzobj->d_device_capabilities)) + device_to_delete_msg = "device is no longer compatible"; + else + device_to_delete_msg = NULL; + + if (device_to_delete_msg) { + nm_clear_g_signal_handler(bzobj->x_device.device_bt, + &bzobj->x_device.device_bt_signal_id); + + device_deleted = g_steal_pointer(&bzobj->x_device.device_bt); + + _LOGD("[%s]: drop device because %s", bzobj->object_path, device_to_delete_msg); + + _connect_disconnect(self, bzobj, device_to_delete_msg); + } + } + + if (device_is_usable) { + if (!bzobj->x_device.device_bt) { + bzobj->x_device.device_bt = nm_device_bt_new(self, + bzobj->object_path, + bzobj->d_device.address, + bzobj->d_device.name, + bzobj->d_device_capabilities); + device_added = g_object_ref(bzobj->x_device.device_bt); + bzobj->x_device.device_bt_signal_id = + g_signal_connect(device_added, + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(_device_state_changed_cb), + bzobj); + } else + _nm_device_bt_notify_set_name(bzobj->x_device.device_bt, bzobj->d_device.name); + + _nm_device_bt_notify_set_connected(bzobj->x_device.device_bt, bzobj->x_device_is_connected); + } + + if (bzobj->x_device.c_req_data && !bzobj->x_device.c_req_data->int_cancellable + && bzobj->x_device_is_connected) { + gs_free char *device_name = g_steal_pointer(&bzobj->x_device.c_req_data->device_name); + + _device_connect_req_data_complete(g_steal_pointer(&bzobj->x_device.c_req_data), + self, + device_name, + NULL); + } + + if (device_added) + g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, device_added); + + if (device_deleted) + _nm_device_bt_notify_removed(device_deleted); } /*****************************************************************************/ static void -_process_change_idle_all (NMBluezManager *self, - gboolean *out_emit_device_availability_changed) +_process_change_idle_all(NMBluezManager *self, gboolean *out_emit_device_availability_changed) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - BzDBusObj *bzobj; - - while ((bzobj = c_list_first_entry (&priv->process_change_lst_head, BzDBusObj, process_change_lst))) { + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + BzDBusObj * bzobj; - c_list_unlink (&bzobj->process_change_lst); + while ( + (bzobj = + c_list_first_entry(&priv->process_change_lst_head, BzDBusObj, process_change_lst))) { + c_list_unlink(&bzobj->process_change_lst); - _LOG_bzobj (bzobj, "before-processing"); + _LOG_bzobj(bzobj, "before-processing"); - _device_process_change (bzobj); + _device_process_change(bzobj); - _network_server_process_change (bzobj, out_emit_device_availability_changed); + _network_server_process_change(bzobj, out_emit_device_availability_changed); - _LOG_bzobj (bzobj, "after-processing"); + _LOG_bzobj(bzobj, "after-processing"); - _bzobjs_del_if_dead (bzobj); - } + _bzobjs_del_if_dead(bzobj); + } - nm_clear_g_source (&priv->process_change_idle_id); + nm_clear_g_source(&priv->process_change_idle_id); } static gboolean -_process_change_idle_cb (gpointer user_data) +_process_change_idle_cb(gpointer user_data) { - NMBluezManager *self = user_data; - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - gboolean emit_device_availability_changed = FALSE; + NMBluezManager * self = user_data; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + gboolean emit_device_availability_changed = FALSE; - _process_change_idle_all (self, &emit_device_availability_changed); + _process_change_idle_all(self, &emit_device_availability_changed); - if (emit_device_availability_changed) - nm_manager_notify_device_availibility_maybe_changed (priv->manager); + if (emit_device_availability_changed) + nm_manager_notify_device_availability_maybe_changed(priv->manager); - return G_SOURCE_CONTINUE; + return G_SOURCE_CONTINUE; } static void -_process_change_idle_schedule (NMBluezManager *self, - BzDBusObj *bzobj) +_process_change_idle_schedule(NMBluezManager *self, BzDBusObj *bzobj) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - nm_c_list_move_tail (&priv->process_change_lst_head, &bzobj->process_change_lst); - if (priv->process_change_idle_id == 0) - priv->process_change_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, _process_change_idle_cb, self, NULL); + nm_c_list_move_tail(&priv->process_change_lst_head, &bzobj->process_change_lst); + if (priv->process_change_idle_id == 0) + priv->process_change_idle_id = + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE + 1, _process_change_idle_cb, self, NULL); } static void -_dbus_process_changes (NMBluezManager *self, - BzDBusObj *bzobj, - const char *log_reason) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - gboolean network_server_is_usable; - gboolean adapter_is_usable_for_device; - gboolean device_is_usable; - gboolean changes = FALSE; - gboolean recheck_devices_for_adapter = FALSE; - - nm_assert (bzobj); - - _LOG_bzobj (bzobj, log_reason); - - device_is_usable = _bzobjs_device_is_usable (bzobj, NULL, NULL); - - if (bzobj->x_device_is_usable != device_is_usable) - changes = TRUE; - else if (bzobj->x_device.device_bt) { - if (!device_is_usable) - changes = TRUE; - else { - if ( bzobj->x_device_is_connected != _bzobjs_device_is_connected (bzobj) - || !_nm_device_bt_for_same_device (bzobj->x_device.device_bt, - bzobj->object_path, - bzobj->d_device.address, - bzobj->d_device.name, - bzobj->d_device_capabilities)) - changes = TRUE; - } - } - - adapter_is_usable_for_device = _bzobjs_adapter_is_usable_for_device (bzobj); - if (adapter_is_usable_for_device != bzobj->was_usable_adapter_for_device_before) { - /* this function does not modify bzobj in any other cases except here. - * Usually changes are processed delayed, in the idle handler. - * - * But the bzobj->was_usable_adapter_for_device_before only exists to know whether - * we need to re-check device availability. It is correct to set the flag - * here, right before we checked. */ - bzobj->was_usable_adapter_for_device_before = adapter_is_usable_for_device; - recheck_devices_for_adapter = TRUE; - changes = TRUE; - } - - if (!changes) { - network_server_is_usable = _bzobjs_network_server_is_usable (bzobj, TRUE); - - if (network_server_is_usable != (!c_list_is_empty (&bzobj->x_network_server.lst))) - changes = TRUE; - else if ( bzobj->x_network_server.device_br - && !network_server_is_usable) - changes = TRUE; - else if (!nm_streq0 (bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, - bzobj->x_network_server.adapter_address)) - changes = TRUE; - } - - if (changes) - _process_change_idle_schedule (self, bzobj); - - if (recheck_devices_for_adapter) { - GHashTableIter iter; - BzDBusObj *bzobj2; - - /* we got a change to the availability of an adapter. We might need to recheck - * all devices that use this adapter... */ - g_hash_table_iter_init (&iter, priv->bzobjs); - while (g_hash_table_iter_next (&iter, (gpointer *) &bzobj2, NULL)) { - if (bzobj2 == bzobj) - continue; - if (!nm_streq0 (bzobj2->d_device.adapter, bzobj->object_path)) - continue; - if (c_list_is_empty (&bzobj2->process_change_lst)) - _dbus_process_changes (self, bzobj2, "adapter-changed"); - else - nm_c_list_move_tail (&priv->process_change_lst_head, &bzobj2->process_change_lst); - } - } - - _bzobjs_del_if_dead (bzobj); +_dbus_process_changes(NMBluezManager *self, BzDBusObj *bzobj, const char *log_reason) +{ + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + gboolean network_server_is_usable; + gboolean adapter_is_usable_for_device; + gboolean device_is_usable; + gboolean changes = FALSE; + gboolean recheck_devices_for_adapter = FALSE; + + nm_assert(bzobj); + + _LOG_bzobj(bzobj, log_reason); + + device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, NULL); + + if (bzobj->x_device_is_usable != device_is_usable) + changes = TRUE; + else if (bzobj->x_device.device_bt) { + if (!device_is_usable) + changes = TRUE; + else { + if (bzobj->x_device_is_connected != _bzobjs_device_is_connected(bzobj) + || !_nm_device_bt_for_same_device(bzobj->x_device.device_bt, + bzobj->object_path, + bzobj->d_device.address, + bzobj->d_device.name, + bzobj->d_device_capabilities)) + changes = TRUE; + } + } + + adapter_is_usable_for_device = _bzobjs_adapter_is_usable_for_device(bzobj); + if (adapter_is_usable_for_device != bzobj->was_usable_adapter_for_device_before) { + /* this function does not modify bzobj in any other cases except here. + * Usually changes are processed delayed, in the idle handler. + * + * But the bzobj->was_usable_adapter_for_device_before only exists to know whether + * we need to re-check device availability. It is correct to set the flag + * here, right before we checked. */ + bzobj->was_usable_adapter_for_device_before = adapter_is_usable_for_device; + recheck_devices_for_adapter = TRUE; + changes = TRUE; + } + + if (!changes) { + network_server_is_usable = _bzobjs_network_server_is_usable(bzobj, TRUE); + + if (network_server_is_usable != (!c_list_is_empty(&bzobj->x_network_server.lst))) + changes = TRUE; + else if (bzobj->x_network_server.device_br && !network_server_is_usable) + changes = TRUE; + else if (!nm_streq0(bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, + bzobj->x_network_server.adapter_address)) + changes = TRUE; + } + + if (changes) + _process_change_idle_schedule(self, bzobj); + + if (recheck_devices_for_adapter) { + GHashTableIter iter; + BzDBusObj * bzobj2; + + /* we got a change to the availability of an adapter. We might need to recheck + * all devices that use this adapter... */ + g_hash_table_iter_init(&iter, priv->bzobjs); + while (g_hash_table_iter_next(&iter, (gpointer *) &bzobj2, NULL)) { + if (bzobj2 == bzobj) + continue; + if (!nm_streq0(bzobj2->d_device.adapter, bzobj->object_path)) + continue; + if (c_list_is_empty(&bzobj2->process_change_lst)) + _dbus_process_changes(self, bzobj2, "adapter-changed"); + else + nm_c_list_move_tail(&priv->process_change_lst_head, &bzobj2->process_change_lst); + } + } + + _bzobjs_del_if_dead(bzobj); } /*****************************************************************************/ -#define ALL_RELEVANT_INTERFACE_NAMES NM_MAKE_STRV (NM_BLUEZ5_ADAPTER_INTERFACE, \ - NM_BLUEZ5_DEVICE_INTERFACE, \ - NM_BLUEZ5_NETWORK_INTERFACE, \ - NM_BLUEZ5_NETWORK_SERVER_INTERFACE) +#define ALL_RELEVANT_INTERFACE_NAMES \ + NM_MAKE_STRV(NM_BLUEZ5_ADAPTER_INTERFACE, \ + NM_BLUEZ5_DEVICE_INTERFACE, \ + NM_BLUEZ5_NETWORK_INTERFACE, \ + NM_BLUEZ5_NETWORK_SERVER_INTERFACE) static gboolean -_dbus_handle_properties_changed (NMBluezManager *self, - const char *object_path, - const char *interface_name, - GVariant *changed_properties, - const char *const*invalidated_properties, - BzDBusObj **inout_bzobj) -{ - BzDBusObj *bzobj = NULL; - gboolean changed = FALSE; - const char *property_name; - GVariant *property_value; - GVariantIter iter_prop; - gsize i; - - if (!invalidated_properties) - invalidated_properties = NM_PTRARRAY_EMPTY (const char *); - - nm_assert (g_variant_is_of_type (changed_properties, G_VARIANT_TYPE ("a{sv}"))); - - if (inout_bzobj) { - bzobj = *inout_bzobj; - nm_assert (!bzobj || nm_streq (object_path, bzobj->object_path)); - } - - if (changed_properties) - g_variant_iter_init (&iter_prop, changed_properties); - - if (nm_streq (interface_name, NM_BLUEZ5_ADAPTER_INTERFACE)) { - _bzobjs_init (self, &bzobj, object_path); - if (!bzobj->d_has_adapter_iface) { - changed = TRUE; - bzobj->d_has_adapter_iface = TRUE; - } - - while ( changed_properties - && g_variant_iter_next (&iter_prop, "{&sv}", &property_name, &property_value)) { - _nm_unused gs_unref_variant GVariant *property_value_free = property_value; - - if (nm_streq (property_name, "Address")) { - gs_free char *s = g_variant_is_of_type (property_value, G_VARIANT_TYPE_STRING) - ? nm_utils_hwaddr_canonical (g_variant_get_string (property_value, NULL), ETH_ALEN) - : NULL; - - if (!nm_streq0 (bzobj->d_adapter.address, s)) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_adapter.address); - bzobj->d_adapter.address = g_steal_pointer (&s); - } - continue; - } - if (nm_streq (property_name, "Powered")) { - bool v = g_variant_is_of_type (property_value, G_VARIANT_TYPE_BOOLEAN) - && g_variant_get_boolean (property_value); - - if (bzobj->d_adapter_powered != v) { - changed = TRUE; - bzobj->d_adapter_powered = v; - } - continue; - } - } - - for (i = 0; (property_name = invalidated_properties[i]); i++) { - if (nm_streq (property_name, "Address")) { - if (bzobj->d_adapter.address) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_adapter.address); - } - continue; - } - if (nm_streq (property_name, "Powered")) { - if (bzobj->d_adapter_powered) { - changed = TRUE; - bzobj->d_adapter_powered = FALSE; - } - continue; - } - } - - } else if (nm_streq (interface_name, NM_BLUEZ5_DEVICE_INTERFACE)) { - _bzobjs_init (self, &bzobj, object_path); - if (!bzobj->d_has_device_iface) { - changed = TRUE; - bzobj->d_has_device_iface = TRUE; - } - - while ( changed_properties - && g_variant_iter_next (&iter_prop, "{&sv}", &property_name, &property_value)) { - _nm_unused gs_unref_variant GVariant *property_value_free = property_value; - - if (nm_streq (property_name, "Address")) { - gs_free char *s = g_variant_is_of_type (property_value, G_VARIANT_TYPE_STRING) - ? nm_utils_hwaddr_canonical (g_variant_get_string (property_value, NULL), ETH_ALEN) - : NULL; - - if (!nm_streq0 (bzobj->d_device.address, s)) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.address); - bzobj->d_device.address = g_steal_pointer (&s); - } - continue; - } - if (nm_streq (property_name, "Name")) { - const char *s = g_variant_is_of_type (property_value, G_VARIANT_TYPE_STRING) - ? g_variant_get_string (property_value, NULL) - : NULL; - - if (!nm_streq0 (bzobj->d_device.name, s)) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.name); - bzobj->d_device.name = g_strdup (s); - } - continue; - } - if (nm_streq (property_name, "Adapter")) { - const char *s = g_variant_is_of_type (property_value, G_VARIANT_TYPE_OBJECT_PATH) - ? g_variant_get_string (property_value, NULL) - : NULL; - - if (!nm_streq0 (bzobj->d_device.adapter, s)) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.adapter); - bzobj->d_device.adapter = g_strdup (s); - } - continue; - } - if (nm_streq (property_name, "UUIDs")) { - NMBluetoothCapabilities capabilities = NM_BT_CAPABILITY_NONE; - - if (g_variant_is_of_type (property_value, G_VARIANT_TYPE_STRING_ARRAY)) { - gs_free const char **s = g_variant_get_strv (property_value, NULL); - - capabilities = convert_uuids_to_capabilities (s); - } - if (bzobj->d_device_capabilities != capabilities) { - changed = TRUE; - bzobj->d_device_capabilities = capabilities; - nm_assert (bzobj->d_device_capabilities == capabilities); - } - continue; - } - if (nm_streq (property_name, "Connected")) { - bool v = g_variant_is_of_type (property_value, G_VARIANT_TYPE_BOOLEAN) - && g_variant_get_boolean (property_value); - - if (bzobj->d_device_connected != v) { - changed = TRUE; - bzobj->d_device_connected = v; - } - continue; - } - if (nm_streq (property_name, "Paired")) { - bool v = g_variant_is_of_type (property_value, G_VARIANT_TYPE_BOOLEAN) - && g_variant_get_boolean (property_value); - - if (bzobj->d_device_paired != v) { - changed = TRUE; - bzobj->d_device_paired = v; - } - continue; - } - } - - for (i = 0; (property_name = invalidated_properties[i]); i++) { - if (nm_streq (property_name, "Address")) { - if (bzobj->d_device.address) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.address); - } - continue; - } - if (nm_streq (property_name, "Name")) { - if (bzobj->d_device.name) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.name); - } - continue; - } - if (nm_streq (property_name, "Adapter")) { - if (bzobj->d_device.adapter) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.adapter); - } - continue; - } - if (nm_streq (property_name, "UUIDs")) { - if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { - changed = TRUE; - bzobj->d_device_capabilities = NM_BT_CAPABILITY_NONE; - } - continue; - } - if (nm_streq (property_name, "Connected")) { - if (bzobj->d_device_connected) { - changed = TRUE; - bzobj->d_device_connected = FALSE; - } - continue; - } - if (nm_streq (property_name, "Paired")) { - if (bzobj->d_device_paired) { - changed = TRUE; - bzobj->d_device_paired = FALSE; - } - continue; - } - } - - } else if (nm_streq (interface_name, NM_BLUEZ5_NETWORK_INTERFACE)) { - _bzobjs_init (self, &bzobj, object_path); - if (!bzobj->d_has_network_iface) { - changed = TRUE; - bzobj->d_has_network_iface = TRUE; - } - - while ( changed_properties - && g_variant_iter_next (&iter_prop, "{&sv}", &property_name, &property_value)) { - _nm_unused gs_unref_variant GVariant *property_value_free = property_value; - - if (nm_streq (property_name, "Interface")) { - const char *s = g_variant_is_of_type (property_value, G_VARIANT_TYPE_STRING) - ? g_variant_get_string (property_value, NULL) - : NULL; - - if (!nm_streq0 (bzobj->d_network.interface, s)) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_network.interface); - bzobj->d_network.interface = g_strdup (s); - } - continue; - } - if (nm_streq (property_name, "Connected")) { - bool v = g_variant_is_of_type (property_value, G_VARIANT_TYPE_BOOLEAN) - && g_variant_get_boolean (property_value); - - if (bzobj->d_network_connected != v) { - changed = TRUE; - bzobj->d_network_connected = v; - } - continue; - } - } - - for (i = 0; (property_name = invalidated_properties[i]); i++) { - if (nm_streq (property_name, "Interface")) { - if (bzobj->d_network.interface) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_network.interface); - } - continue; - } - if (nm_streq (property_name, "Connected")) { - if (bzobj->d_network_connected) { - changed = TRUE; - bzobj->d_network_connected = FALSE; - } - continue; - } - } - - } else if (nm_streq (interface_name, NM_BLUEZ5_NETWORK_SERVER_INTERFACE)) { - _bzobjs_init (self, &bzobj, object_path); - if (!bzobj->d_has_network_server_iface) { - changed = TRUE; - bzobj->d_has_network_server_iface = TRUE; - } - } - - nm_assert (!changed || bzobj); - - if (inout_bzobj) - *inout_bzobj = bzobj; - - return changed; +_dbus_handle_properties_changed(NMBluezManager * self, + const char * object_path, + const char * interface_name, + GVariant * changed_properties, + const char *const *invalidated_properties, + BzDBusObj ** inout_bzobj) +{ + BzDBusObj * bzobj = NULL; + gboolean changed = FALSE; + const char * property_name; + GVariant * property_value; + GVariantIter iter_prop; + gsize i; + + if (!invalidated_properties) + invalidated_properties = NM_PTRARRAY_EMPTY(const char *); + + nm_assert(g_variant_is_of_type(changed_properties, G_VARIANT_TYPE("a{sv}"))); + + if (inout_bzobj) { + bzobj = *inout_bzobj; + nm_assert(!bzobj || nm_streq(object_path, bzobj->object_path)); + } + + if (changed_properties) + g_variant_iter_init(&iter_prop, changed_properties); + + if (nm_streq(interface_name, NM_BLUEZ5_ADAPTER_INTERFACE)) { + _bzobjs_init(self, &bzobj, object_path); + if (!bzobj->d_has_adapter_iface) { + changed = TRUE; + bzobj->d_has_adapter_iface = TRUE; + } + + while (changed_properties + && g_variant_iter_next(&iter_prop, "{&sv}", &property_name, &property_value)) { + _nm_unused gs_unref_variant GVariant *property_value_free = property_value; + + if (nm_streq(property_name, "Address")) { + gs_free char *s = + g_variant_is_of_type(property_value, G_VARIANT_TYPE_STRING) + ? nm_utils_hwaddr_canonical(g_variant_get_string(property_value, NULL), + ETH_ALEN) + : NULL; + + if (!nm_streq0(bzobj->d_adapter.address, s)) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_adapter.address); + bzobj->d_adapter.address = g_steal_pointer(&s); + } + continue; + } + if (nm_streq(property_name, "Powered")) { + bool v = g_variant_is_of_type(property_value, G_VARIANT_TYPE_BOOLEAN) + && g_variant_get_boolean(property_value); + + if (bzobj->d_adapter_powered != v) { + changed = TRUE; + bzobj->d_adapter_powered = v; + } + continue; + } + } + + for (i = 0; (property_name = invalidated_properties[i]); i++) { + if (nm_streq(property_name, "Address")) { + if (bzobj->d_adapter.address) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_adapter.address); + } + continue; + } + if (nm_streq(property_name, "Powered")) { + if (bzobj->d_adapter_powered) { + changed = TRUE; + bzobj->d_adapter_powered = FALSE; + } + continue; + } + } + + } else if (nm_streq(interface_name, NM_BLUEZ5_DEVICE_INTERFACE)) { + _bzobjs_init(self, &bzobj, object_path); + if (!bzobj->d_has_device_iface) { + changed = TRUE; + bzobj->d_has_device_iface = TRUE; + } + + while (changed_properties + && g_variant_iter_next(&iter_prop, "{&sv}", &property_name, &property_value)) { + _nm_unused gs_unref_variant GVariant *property_value_free = property_value; + + if (nm_streq(property_name, "Address")) { + gs_free char *s = + g_variant_is_of_type(property_value, G_VARIANT_TYPE_STRING) + ? nm_utils_hwaddr_canonical(g_variant_get_string(property_value, NULL), + ETH_ALEN) + : NULL; + + if (!nm_streq0(bzobj->d_device.address, s)) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.address); + bzobj->d_device.address = g_steal_pointer(&s); + } + continue; + } + if (nm_streq(property_name, "Name")) { + const char *s = g_variant_is_of_type(property_value, G_VARIANT_TYPE_STRING) + ? g_variant_get_string(property_value, NULL) + : NULL; + + if (!nm_streq0(bzobj->d_device.name, s)) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.name); + bzobj->d_device.name = g_strdup(s); + } + continue; + } + if (nm_streq(property_name, "Adapter")) { + const char *s = g_variant_is_of_type(property_value, G_VARIANT_TYPE_OBJECT_PATH) + ? g_variant_get_string(property_value, NULL) + : NULL; + + if (!nm_streq0(bzobj->d_device.adapter, s)) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.adapter); + bzobj->d_device.adapter = g_strdup(s); + } + continue; + } + if (nm_streq(property_name, "UUIDs")) { + NMBluetoothCapabilities capabilities = NM_BT_CAPABILITY_NONE; + + if (g_variant_is_of_type(property_value, G_VARIANT_TYPE_STRING_ARRAY)) { + gs_free const char **s = g_variant_get_strv(property_value, NULL); + + capabilities = convert_uuids_to_capabilities(s); + } + if (bzobj->d_device_capabilities != capabilities) { + changed = TRUE; + bzobj->d_device_capabilities = capabilities; + nm_assert(bzobj->d_device_capabilities == capabilities); + } + continue; + } + if (nm_streq(property_name, "Connected")) { + bool v = g_variant_is_of_type(property_value, G_VARIANT_TYPE_BOOLEAN) + && g_variant_get_boolean(property_value); + + if (bzobj->d_device_connected != v) { + changed = TRUE; + bzobj->d_device_connected = v; + } + continue; + } + if (nm_streq(property_name, "Paired")) { + bool v = g_variant_is_of_type(property_value, G_VARIANT_TYPE_BOOLEAN) + && g_variant_get_boolean(property_value); + + if (bzobj->d_device_paired != v) { + changed = TRUE; + bzobj->d_device_paired = v; + } + continue; + } + } + + for (i = 0; (property_name = invalidated_properties[i]); i++) { + if (nm_streq(property_name, "Address")) { + if (bzobj->d_device.address) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.address); + } + continue; + } + if (nm_streq(property_name, "Name")) { + if (bzobj->d_device.name) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.name); + } + continue; + } + if (nm_streq(property_name, "Adapter")) { + if (bzobj->d_device.adapter) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.adapter); + } + continue; + } + if (nm_streq(property_name, "UUIDs")) { + if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { + changed = TRUE; + bzobj->d_device_capabilities = NM_BT_CAPABILITY_NONE; + } + continue; + } + if (nm_streq(property_name, "Connected")) { + if (bzobj->d_device_connected) { + changed = TRUE; + bzobj->d_device_connected = FALSE; + } + continue; + } + if (nm_streq(property_name, "Paired")) { + if (bzobj->d_device_paired) { + changed = TRUE; + bzobj->d_device_paired = FALSE; + } + continue; + } + } + + } else if (nm_streq(interface_name, NM_BLUEZ5_NETWORK_INTERFACE)) { + _bzobjs_init(self, &bzobj, object_path); + if (!bzobj->d_has_network_iface) { + changed = TRUE; + bzobj->d_has_network_iface = TRUE; + } + + while (changed_properties + && g_variant_iter_next(&iter_prop, "{&sv}", &property_name, &property_value)) { + _nm_unused gs_unref_variant GVariant *property_value_free = property_value; + + if (nm_streq(property_name, "Interface")) { + const char *s = g_variant_is_of_type(property_value, G_VARIANT_TYPE_STRING) + ? g_variant_get_string(property_value, NULL) + : NULL; + + if (!nm_streq0(bzobj->d_network.interface, s)) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_network.interface); + bzobj->d_network.interface = g_strdup(s); + } + continue; + } + if (nm_streq(property_name, "Connected")) { + bool v = g_variant_is_of_type(property_value, G_VARIANT_TYPE_BOOLEAN) + && g_variant_get_boolean(property_value); + + if (bzobj->d_network_connected != v) { + changed = TRUE; + bzobj->d_network_connected = v; + } + continue; + } + } + + for (i = 0; (property_name = invalidated_properties[i]); i++) { + if (nm_streq(property_name, "Interface")) { + if (bzobj->d_network.interface) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_network.interface); + } + continue; + } + if (nm_streq(property_name, "Connected")) { + if (bzobj->d_network_connected) { + changed = TRUE; + bzobj->d_network_connected = FALSE; + } + continue; + } + } + + } else if (nm_streq(interface_name, NM_BLUEZ5_NETWORK_SERVER_INTERFACE)) { + _bzobjs_init(self, &bzobj, object_path); + if (!bzobj->d_has_network_server_iface) { + changed = TRUE; + bzobj->d_has_network_server_iface = TRUE; + } + } + + nm_assert(!changed || bzobj); + + if (inout_bzobj) + *inout_bzobj = bzobj; + + return changed; } static void -_dbus_handle_interface_added (NMBluezManager *self, - const char *object_path, - GVariant *ifaces, - gboolean initial_get_managed_objects) -{ - BzDBusObj *bzobj = NULL; - gboolean changed = FALSE; - const char *interface_name; - GVariant *changed_properties; - GVariantIter iter_ifaces; - - nm_assert (g_variant_is_of_type (ifaces, G_VARIANT_TYPE ("a{sa{sv}}"))); - - g_variant_iter_init (&iter_ifaces, ifaces); - while (g_variant_iter_next (&iter_ifaces, "{&s@a{sv}}", &interface_name, &changed_properties)) { - _nm_unused gs_unref_variant GVariant *changed_properties_free = changed_properties; - - if (_dbus_handle_properties_changed (self, object_path, interface_name, changed_properties, NULL, &bzobj)) - changed = TRUE; - } - - if (changed) { - _dbus_process_changes (self, - bzobj, - initial_get_managed_objects - ? "dbus-init" - : "dbus-iface-added"); - } +_dbus_handle_interface_added(NMBluezManager *self, + const char * object_path, + GVariant * ifaces, + gboolean initial_get_managed_objects) +{ + BzDBusObj * bzobj = NULL; + gboolean changed = FALSE; + const char * interface_name; + GVariant * changed_properties; + GVariantIter iter_ifaces; + + nm_assert(g_variant_is_of_type(ifaces, G_VARIANT_TYPE("a{sa{sv}}"))); + + g_variant_iter_init(&iter_ifaces, ifaces); + while (g_variant_iter_next(&iter_ifaces, "{&s@a{sv}}", &interface_name, &changed_properties)) { + _nm_unused gs_unref_variant GVariant *changed_properties_free = changed_properties; + + if (_dbus_handle_properties_changed(self, + object_path, + interface_name, + changed_properties, + NULL, + &bzobj)) + changed = TRUE; + } + + if (changed) { + _dbus_process_changes(self, + bzobj, + initial_get_managed_objects ? "dbus-init" : "dbus-iface-added"); + } } static gboolean -_dbus_handle_interface_removed (NMBluezManager *self, - const char *object_path, - BzDBusObj **inout_bzobj, - const char *const*removed_interfaces) -{ - gboolean changed = FALSE; - BzDBusObj *bzobj; - gsize i; - - if ( inout_bzobj - && *inout_bzobj) { - bzobj = *inout_bzobj; - nm_assert (bzobj == _bzobjs_get (self, object_path)); - } else { - bzobj = _bzobjs_get (self, object_path); - if (!bzobj) - return FALSE; - NM_SET_OUT (inout_bzobj, bzobj); - } - - for (i = 0; removed_interfaces[i]; i++) { - const char *interface_name = removed_interfaces[i]; - - if (nm_streq (interface_name, NM_BLUEZ5_ADAPTER_INTERFACE)) { - if (bzobj->d_has_adapter_iface) { - changed = TRUE; - bzobj->d_has_adapter_iface = FALSE; - } - if (bzobj->d_adapter.address) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_adapter.address); - } - if (bzobj->d_adapter_powered) { - changed = TRUE; - bzobj->d_adapter_powered = FALSE; - } - } else if (nm_streq (interface_name, NM_BLUEZ5_DEVICE_INTERFACE)) { - if (bzobj->d_has_device_iface) { - changed = TRUE; - bzobj->d_has_device_iface = FALSE; - } - if (bzobj->d_device.address) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.address); - } - if (bzobj->d_device.name) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.name); - } - if (bzobj->d_device.adapter) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_device.adapter); - } - if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { - changed = TRUE; - bzobj->d_device_capabilities = NM_BT_CAPABILITY_NONE; - } - if (bzobj->d_device_connected) { - changed = TRUE; - bzobj->d_device_connected = FALSE; - } - if (bzobj->d_device_paired) { - changed = TRUE; - bzobj->d_device_paired = FALSE; - } - } else if (nm_streq (interface_name, NM_BLUEZ5_NETWORK_INTERFACE)) { - if (bzobj->d_has_network_iface) { - changed = TRUE; - bzobj->d_has_network_iface = FALSE; - } - if (bzobj->d_network.interface) { - changed = TRUE; - nm_clear_g_free (&bzobj->d_network.interface); - } - if (bzobj->d_network_connected) { - changed = TRUE; - bzobj->d_network_connected = FALSE; - } - } else if (nm_streq (interface_name, NM_BLUEZ5_NETWORK_SERVER_INTERFACE)) { - if (bzobj->d_has_network_server_iface) { - changed = TRUE; - bzobj->d_has_network_server_iface = FALSE; - } - } - } - - return changed; +_dbus_handle_interface_removed(NMBluezManager * self, + const char * object_path, + BzDBusObj ** inout_bzobj, + const char *const *removed_interfaces) +{ + gboolean changed = FALSE; + BzDBusObj *bzobj; + gsize i; + + if (inout_bzobj && *inout_bzobj) { + bzobj = *inout_bzobj; + nm_assert(bzobj == _bzobjs_get(self, object_path)); + } else { + bzobj = _bzobjs_get(self, object_path); + if (!bzobj) + return FALSE; + NM_SET_OUT(inout_bzobj, bzobj); + } + + for (i = 0; removed_interfaces[i]; i++) { + const char *interface_name = removed_interfaces[i]; + + if (nm_streq(interface_name, NM_BLUEZ5_ADAPTER_INTERFACE)) { + if (bzobj->d_has_adapter_iface) { + changed = TRUE; + bzobj->d_has_adapter_iface = FALSE; + } + if (bzobj->d_adapter.address) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_adapter.address); + } + if (bzobj->d_adapter_powered) { + changed = TRUE; + bzobj->d_adapter_powered = FALSE; + } + } else if (nm_streq(interface_name, NM_BLUEZ5_DEVICE_INTERFACE)) { + if (bzobj->d_has_device_iface) { + changed = TRUE; + bzobj->d_has_device_iface = FALSE; + } + if (bzobj->d_device.address) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.address); + } + if (bzobj->d_device.name) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.name); + } + if (bzobj->d_device.adapter) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_device.adapter); + } + if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { + changed = TRUE; + bzobj->d_device_capabilities = NM_BT_CAPABILITY_NONE; + } + if (bzobj->d_device_connected) { + changed = TRUE; + bzobj->d_device_connected = FALSE; + } + if (bzobj->d_device_paired) { + changed = TRUE; + bzobj->d_device_paired = FALSE; + } + } else if (nm_streq(interface_name, NM_BLUEZ5_NETWORK_INTERFACE)) { + if (bzobj->d_has_network_iface) { + changed = TRUE; + bzobj->d_has_network_iface = FALSE; + } + if (bzobj->d_network.interface) { + changed = TRUE; + nm_clear_g_free(&bzobj->d_network.interface); + } + if (bzobj->d_network_connected) { + changed = TRUE; + bzobj->d_network_connected = FALSE; + } + } else if (nm_streq(interface_name, NM_BLUEZ5_NETWORK_SERVER_INTERFACE)) { + if (bzobj->d_has_network_server_iface) { + changed = TRUE; + bzobj->d_has_network_server_iface = FALSE; + } + } + } + + return changed; } static void -_dbus_managed_objects_changed_cb (GDBusConnection *connection, - const char *sender_name, - const char *arg_object_path, - const char *interface_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) +_dbus_managed_objects_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * arg_object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) { - NMBluezManager *self = user_data; - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - BzDBusObj *bzobj = NULL; - gboolean changed; + NMBluezManager * self = user_data; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + BzDBusObj * bzobj = NULL; + gboolean changed; - nm_assert (nm_streq0 (interface_name, DBUS_INTERFACE_OBJECT_MANAGER)); + nm_assert(nm_streq0(interface_name, DBUS_INTERFACE_OBJECT_MANAGER)); - if (priv->get_managed_objects_cancellable) { - /* we still wait for the initial GetManagedObjects(). Ignore the event. */ - return; - } + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } - if (nm_streq (signal_name, "InterfacesAdded")) { - gs_unref_variant GVariant *interfaces_and_properties = NULL; - const char *object_path; + if (nm_streq(signal_name, "InterfacesAdded")) { + gs_unref_variant GVariant *interfaces_and_properties = NULL; + const char * object_path; - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oa{sa{sv}})"))) - return; + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oa{sa{sv}})"))) + return; - g_variant_get (parameters, - "(&o@a{sa{sv}})", - &object_path, - &interfaces_and_properties); + g_variant_get(parameters, "(&o@a{sa{sv}})", &object_path, &interfaces_and_properties); - _dbus_handle_interface_added (self, object_path, interfaces_and_properties, FALSE); - return; - } + _dbus_handle_interface_added(self, object_path, interfaces_and_properties, FALSE); + return; + } - if (nm_streq (signal_name, "InterfacesRemoved")) { - gs_free const char **interfaces = NULL; - const char *object_path; + if (nm_streq(signal_name, "InterfacesRemoved")) { + gs_free const char **interfaces = NULL; + const char * object_path; - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oas)"))) - return; + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oas)"))) + return; - g_variant_get (parameters, - "(&o^a&s)", - &object_path, - &interfaces); + g_variant_get(parameters, "(&o^a&s)", &object_path, &interfaces); - changed = _dbus_handle_interface_removed (self, object_path, &bzobj, interfaces); - if (changed) - _dbus_process_changes (self, bzobj, "dbus-iface-removed"); - return; - } + changed = _dbus_handle_interface_removed(self, object_path, &bzobj, interfaces); + if (changed) + _dbus_process_changes(self, bzobj, "dbus-iface-removed"); + return; + } } static void -_dbus_properties_changed_cb (GDBusConnection *connection, - const char *sender_name, - const char *object_path, - const char *signal_interface_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) -{ - NMBluezManager *self = user_data; - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - const char *interface_name; - gs_unref_variant GVariant *changed_properties = NULL; - gs_free const char **invalidated_properties = NULL; - BzDBusObj *bzobj = NULL; - - if (priv->get_managed_objects_cancellable) { - /* we still wait for the initial GetManagedObjects(). Ignore the event. */ - return; - } - - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)"))) - return; - - g_variant_get (parameters, - "(&s@a{sv}^a&s)", - &interface_name, - &changed_properties, - &invalidated_properties); - - if (_dbus_handle_properties_changed (self, object_path, interface_name, changed_properties, invalidated_properties, &bzobj)) - _dbus_process_changes (self, bzobj, "dbus-property-changed"); +_dbus_properties_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * signal_interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMBluezManager * self = user_data; + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + const char * interface_name; + gs_unref_variant GVariant *changed_properties = NULL; + gs_free const char ** invalidated_properties = NULL; + BzDBusObj * bzobj = NULL; + + if (priv->get_managed_objects_cancellable) { + /* we still wait for the initial GetManagedObjects(). Ignore the event. */ + return; + } + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv}as)"))) + return; + + g_variant_get(parameters, + "(&s@a{sv}^a&s)", + &interface_name, + &changed_properties, + &invalidated_properties); + + if (_dbus_handle_properties_changed(self, + object_path, + interface_name, + changed_properties, + invalidated_properties, + &bzobj)) + _dbus_process_changes(self, bzobj, "dbus-property-changed"); } static void -_dbus_get_managed_objects_cb (GVariant *result, - GError *error, - gpointer user_data) +_dbus_get_managed_objects_cb(GVariant *result, GError *error, gpointer user_data) { - NMBluezManager *self; - NMBluezManagerPrivate *priv; - GVariantIter iter; - const char *object_path; - GVariant *ifaces; + NMBluezManager * self; + NMBluezManagerPrivate *priv; + GVariantIter iter; + const char * object_path; + GVariant * ifaces; - if ( !result - && nm_utils_error_is_cancelled (error)) - return; + if (!result && nm_utils_error_is_cancelled(error)) + return; - self = user_data; - priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + self = user_data; + priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - g_clear_object (&priv->get_managed_objects_cancellable); + g_clear_object(&priv->get_managed_objects_cancellable); - if (!result) { - _LOGT ("initial GetManagedObjects() call failed: %s", error->message); - _cleanup_for_name_owner (self); - return; - } + if (!result) { + _LOGT("initial GetManagedObjects() call failed: %s", error->message); + _cleanup_for_name_owner(self); + return; + } - _LOGT ("initial GetManagedObjects call succeeded"); + _LOGT("initial GetManagedObjects call succeeded"); - g_variant_iter_init (&iter, result); - while (g_variant_iter_next (&iter, "{&o@a{sa{sv}}}", &object_path, &ifaces)) { - _nm_unused gs_unref_variant GVariant *ifaces_free = ifaces; + g_variant_iter_init(&iter, result); + while (g_variant_iter_next(&iter, "{&o@a{sa{sv}}}", &object_path, &ifaces)) { + _nm_unused gs_unref_variant GVariant *ifaces_free = ifaces; - _dbus_handle_interface_added (self, object_path, ifaces, TRUE); - } + _dbus_handle_interface_added(self, object_path, ifaces, TRUE); + } } /*****************************************************************************/ static void -_cleanup_for_name_owner (NMBluezManager *self) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - gboolean emit_device_availability_changed = FALSE; - GHashTableIter iter; - BzDBusObj *bzobj; - gboolean first = TRUE; - - nm_clear_g_cancellable (&priv->get_managed_objects_cancellable); - - nm_clear_g_dbus_connection_signal (priv->dbus_connection, - &priv->managed_objects_changed_id); - nm_clear_g_dbus_connection_signal (priv->dbus_connection, - &priv->properties_changed_id); - - nm_clear_g_free (&priv->name_owner); - - g_hash_table_iter_init (&iter, priv->bzobjs); - while (g_hash_table_iter_next (&iter, (gpointer *) &bzobj, NULL)) { - if (first) { - first = FALSE; - _LOGT ("drop all objects form D-Bus cache..."); - } - _dbus_handle_interface_removed (self, - bzobj->object_path, - &bzobj, - ALL_RELEVANT_INTERFACE_NAMES); - nm_c_list_move_tail (&priv->process_change_lst_head, &bzobj->process_change_lst); - } - _process_change_idle_all (self, &emit_device_availability_changed); - nm_assert (g_hash_table_size (priv->bzobjs) == 0); - - if (emit_device_availability_changed) - nm_manager_notify_device_availibility_maybe_changed (priv->manager); +_cleanup_for_name_owner(NMBluezManager *self) +{ + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + gboolean emit_device_availability_changed = FALSE; + GHashTableIter iter; + BzDBusObj * bzobj; + gboolean first = TRUE; + + nm_clear_g_cancellable(&priv->get_managed_objects_cancellable); + + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->managed_objects_changed_id); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->properties_changed_id); + + nm_clear_g_free(&priv->name_owner); + + g_hash_table_iter_init(&iter, priv->bzobjs); + while (g_hash_table_iter_next(&iter, (gpointer *) &bzobj, NULL)) { + if (first) { + first = FALSE; + _LOGT("drop all objects form D-Bus cache..."); + } + _dbus_handle_interface_removed(self, + bzobj->object_path, + &bzobj, + ALL_RELEVANT_INTERFACE_NAMES); + nm_c_list_move_tail(&priv->process_change_lst_head, &bzobj->process_change_lst); + } + _process_change_idle_all(self, &emit_device_availability_changed); + nm_assert(g_hash_table_size(priv->bzobjs) == 0); + + if (emit_device_availability_changed) + nm_manager_notify_device_availability_maybe_changed(priv->manager); } static void -name_owner_changed (NMBluezManager *self, - const char *owner) +name_owner_changed(NMBluezManager *self, const char *owner) { - _nm_unused gs_unref_object NMBluezManager *self_keep_alive = g_object_ref (self); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + _nm_unused gs_unref_object NMBluezManager *self_keep_alive = g_object_ref(self); + NMBluezManagerPrivate * priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - owner = nm_str_not_empty (owner); + owner = nm_str_not_empty(owner); - if (!owner) - _LOGT ("D-Bus name for bluez has no owner"); - else - _LOGT ("D-Bus name for bluez has owner %s", owner); + if (!owner) + _LOGT("D-Bus name for bluez has no owner"); + else + _LOGT("D-Bus name for bluez has owner %s", owner); - nm_clear_g_cancellable (&priv->name_owner_get_cancellable); + nm_clear_g_cancellable(&priv->name_owner_get_cancellable); - if (nm_streq0 (priv->name_owner, owner)) - return; + if (nm_streq0(priv->name_owner, owner)) + return; - _cleanup_for_name_owner (self); + _cleanup_for_name_owner(self); - if (!owner) - return; + if (!owner) + return; - priv->name_owner = g_strdup (owner); + priv->name_owner = g_strdup(owner); - priv->get_managed_objects_cancellable = g_cancellable_new (); + priv->get_managed_objects_cancellable = g_cancellable_new(); - priv->managed_objects_changed_id = nm_dbus_connection_signal_subscribe_object_manager (priv->dbus_connection, - priv->name_owner, - NM_BLUEZ_MANAGER_PATH, - NULL, - _dbus_managed_objects_changed_cb, - self, - NULL); + priv->managed_objects_changed_id = + nm_dbus_connection_signal_subscribe_object_manager(priv->dbus_connection, + priv->name_owner, + NM_BLUEZ_MANAGER_PATH, + NULL, + _dbus_managed_objects_changed_cb, + self, + NULL); - priv->properties_changed_id = nm_dbus_connection_signal_subscribe_properties_changed (priv->dbus_connection, - priv->name_owner, - NULL, - NULL, - _dbus_properties_changed_cb, - self, - NULL); + priv->properties_changed_id = + nm_dbus_connection_signal_subscribe_properties_changed(priv->dbus_connection, + priv->name_owner, + NULL, + NULL, + _dbus_properties_changed_cb, + self, + NULL); - nm_dbus_connection_call_get_managed_objects (priv->dbus_connection, - priv->name_owner, - NM_BLUEZ_MANAGER_PATH, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 20000, - priv->get_managed_objects_cancellable, - _dbus_get_managed_objects_cb, - self); + nm_dbus_connection_call_get_managed_objects(priv->dbus_connection, + priv->name_owner, + NM_BLUEZ_MANAGER_PATH, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 20000, + priv->get_managed_objects_cancellable, + _dbus_get_managed_objects_cb, + self); } static void -name_owner_changed_cb (GDBusConnection *connection, - const char *sender_name, - const char *object_path, - const char *interface_name, - const char *signal_name, - GVariant *parameters, - gpointer user_data) +name_owner_changed_cb(GDBusConnection *connection, + const char * sender_name, + const char * object_path, + const char * interface_name, + const char * signal_name, + GVariant * parameters, + gpointer user_data) { - NMBluezManager *self = user_data; - const char *new_owner; + NMBluezManager *self = user_data; + const char * new_owner; - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) - return; + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) + return; - g_variant_get (parameters, - "(&s&s&s)", - NULL, - NULL, - &new_owner); + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); - name_owner_changed (self, new_owner); + name_owner_changed(self, new_owner); } static void -name_owner_get_cb (const char *name_owner, - GError *error, - gpointer user_data) +name_owner_get_cb(const char *name_owner, GError *error, gpointer user_data) { - if ( name_owner - || !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - name_owner_changed (user_data, name_owner); + if (name_owner || !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + name_owner_changed(user_data, name_owner); } /*****************************************************************************/ static void -_cleanup_all (NMBluezManager *self) +_cleanup_all(NMBluezManager *self) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - priv->settings_registered = FALSE; + priv->settings_registered = FALSE; - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self); - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self); - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self); + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_added, self); + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_updated, self); + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_removed, self); - g_hash_table_remove_all (priv->conn_data_elems); - g_hash_table_remove_all (priv->conn_data_heads); + g_hash_table_remove_all(priv->conn_data_elems); + g_hash_table_remove_all(priv->conn_data_heads); - _cleanup_for_name_owner (self); + _cleanup_for_name_owner(self); - nm_clear_g_cancellable (&priv->name_owner_get_cancellable); + nm_clear_g_cancellable(&priv->name_owner_get_cancellable); - nm_clear_g_dbus_connection_signal (priv->dbus_connection, - &priv->name_owner_changed_id); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); } static void -start (NMDeviceFactory *factory) -{ - NMBluezManager *self; - NMBluezManagerPrivate *priv; - NMSettingsConnection *const*sett_conns; - guint n_sett_conns; - guint i; - - g_return_if_fail (NM_IS_BLUEZ_MANAGER (factory)); - - self = NM_BLUEZ_MANAGER (factory); - priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - - _cleanup_all (self); - - if (!priv->dbus_connection) { - _LOGI ("no D-Bus connection available"); - return; - } - - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, G_CALLBACK (cp_connection_added), self); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), self); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), self); - - priv->settings_registered = TRUE; - - sett_conns = nm_settings_get_connections (priv->settings, &n_sett_conns); - for (i = 0; i < n_sett_conns; i++) - _conn_track_update (self, sett_conns[i], TRUE, NULL, NULL, NULL); - - priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection, - NM_BLUEZ_SERVICE, - name_owner_changed_cb, - self, - NULL); - - priv->name_owner_get_cancellable = g_cancellable_new (); - - nm_dbus_connection_call_get_name_owner (priv->dbus_connection, - NM_BLUEZ_SERVICE, - 10000, - priv->name_owner_get_cancellable, - name_owner_get_cb, - self); +start(NMDeviceFactory *factory) +{ + NMBluezManager * self; + NMBluezManagerPrivate * priv; + NMSettingsConnection *const *sett_conns; + guint n_sett_conns; + guint i; + + g_return_if_fail(NM_IS_BLUEZ_MANAGER(factory)); + + self = NM_BLUEZ_MANAGER(factory); + priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + + _cleanup_all(self); + + if (!priv->dbus_connection) { + _LOGI("no D-Bus connection available"); + return; + } + + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK(cp_connection_added), + self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + G_CALLBACK(cp_connection_updated), + self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_CALLBACK(cp_connection_removed), + self); + + priv->settings_registered = TRUE; + + sett_conns = nm_settings_get_connections(priv->settings, &n_sett_conns); + for (i = 0; i < n_sett_conns; i++) + _conn_track_update(self, sett_conns[i], TRUE, NULL, NULL, NULL); + + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + NM_BLUEZ_SERVICE, + name_owner_changed_cb, + self, + NULL); + + priv->name_owner_get_cancellable = g_cancellable_new(); + + nm_dbus_connection_call_get_name_owner(priv->dbus_connection, + NM_BLUEZ_SERVICE, + 10000, + priv->name_owner_get_cancellable, + name_owner_get_cb, + self); } /*****************************************************************************/ static void -_connect_returned (NMBluezManager *self, - BzDBusObj *bzobj, - NMBluetoothCapabilities bt_type, - const char *device_name, - NMBluez5DunContext *dun_context, - GError *error) -{ - char sbuf_cap[100]; - - if (error) { - nm_assert (!device_name); - nm_assert (!dun_context); - - _LOGI ("%s [%s]: connect failed: %s", - nm_bluetooth_capability_to_string (bzobj->x_device_connect_bt_type, sbuf_cap, sizeof (sbuf_cap)), - bzobj->object_path, - error->message); - - _device_connect_req_data_complete (g_steal_pointer (&bzobj->x_device.c_req_data), - self, - NULL, - error); - _connect_disconnect (self, bzobj, "cleanup after connect failure"); - return; - } - - nm_assert (bzobj->x_device_connect_bt_type == bt_type); - nm_assert (device_name); - nm_assert ((bt_type == NM_BT_CAPABILITY_DUN) == (!!dun_context)); - nm_assert (bzobj->x_device.c_req_data); - - g_clear_object (&bzobj->x_device.c_req_data->int_cancellable); - - bzobj->x_device.connect_dun_context = dun_context; - - _LOGD ("%s [%s]: connect successful to device %s", - nm_bluetooth_capability_to_string (bzobj->x_device_connect_bt_type, sbuf_cap, sizeof (sbuf_cap)), - bzobj->object_path, - device_name); - - /* we already have another over-all timer running. But after we connected the device, - * we still need to wait for bluez to acknowledge the connected state (via D-Bus, for NAP). - * For DUN profiles we likely are already fully connected by now. - * - * Anyway, schedule another timeout that is possibly shorter than the overall, original - * timeout. Now this should go down fast. */ - bzobj->x_device.c_req_data->timeout_wait_connect_id = g_timeout_add (5000, - _connect_timeout_wait_connected_cb, - bzobj), - bzobj->x_device.c_req_data->device_name = g_strdup (device_name); - - if ( _bzobjs_device_is_usable (bzobj, NULL, NULL) - && _bzobjs_device_is_connected (bzobj)) { - /* We are now connected. Schedule the task that completes the state. */ - _process_change_idle_schedule (self, bzobj); - } +_connect_returned(NMBluezManager * self, + BzDBusObj * bzobj, + NMBluetoothCapabilities bt_type, + const char * device_name, + NMBluez5DunContext * dun_context, + GError * error) +{ + char sbuf_cap[100]; + + if (error) { + nm_assert(!device_name); + nm_assert(!dun_context); + + _LOGI("%s [%s]: connect failed: %s", + nm_bluetooth_capability_to_string(bzobj->x_device_connect_bt_type, + sbuf_cap, + sizeof(sbuf_cap)), + bzobj->object_path, + error->message); + + _device_connect_req_data_complete(g_steal_pointer(&bzobj->x_device.c_req_data), + self, + NULL, + error); + _connect_disconnect(self, bzobj, "cleanup after connect failure"); + return; + } + + nm_assert(bzobj->x_device_connect_bt_type == bt_type); + nm_assert(device_name); + nm_assert((bt_type == NM_BT_CAPABILITY_DUN) == (!!dun_context)); + nm_assert(bzobj->x_device.c_req_data); + + g_clear_object(&bzobj->x_device.c_req_data->int_cancellable); + + bzobj->x_device.connect_dun_context = dun_context; + + _LOGD("%s [%s]: connect successful to device %s", + nm_bluetooth_capability_to_string(bzobj->x_device_connect_bt_type, + sbuf_cap, + sizeof(sbuf_cap)), + bzobj->object_path, + device_name); + + /* we already have another over-all timer running. But after we connected the device, + * we still need to wait for bluez to acknowledge the connected state (via D-Bus, for NAP). + * For DUN profiles we likely are already fully connected by now. + * + * Anyway, schedule another timeout that is possibly shorter than the overall, original + * timeout. Now this should go down fast. */ + bzobj->x_device.c_req_data->timeout_wait_connect_id = + g_timeout_add(5000, _connect_timeout_wait_connected_cb, bzobj), + bzobj->x_device.c_req_data->device_name = g_strdup(device_name); + + if (_bzobjs_device_is_usable(bzobj, NULL, NULL) && _bzobjs_device_is_connected(bzobj)) { + /* We are now connected. Schedule the task that completes the state. */ + _process_change_idle_schedule(self, bzobj); + } } #if WITH_BLUEZ5_DUN static void -_connect_dun_notify_tty_hangup_cb (NMBluez5DunContext *context, - gpointer user_data) +_connect_dun_notify_tty_hangup_cb(NMBluez5DunContext *context, gpointer user_data) { - BzDBusObj *bzobj = user_data; + BzDBusObj *bzobj = user_data; - _connect_disconnect (bzobj->self, - bzobj, - "DUN connection hung up"); + _connect_disconnect(bzobj->self, bzobj, "DUN connection hung up"); } static void -_connect_dun_step2_cb (NMBluez5DunContext *context, - const char *rfcomm_dev, - GError *error, - gpointer user_data) +_connect_dun_step2_cb(NMBluez5DunContext *context, + const char * rfcomm_dev, + GError * error, + gpointer user_data) { - BzDBusObj *bzobj; + BzDBusObj *bzobj; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - bzobj = user_data; + bzobj = user_data; - if (rfcomm_dev) { - /* We want to early notifiy about the rfcomm path. That is because we might still delay - * to signal full activation longer (asynchronously). But the earliest time the callback - * is invoked with the rfcomm path, we just created the device synchronously. - * - * By already notifying the caller about the path early, it avoids a race where ModemManager - * would find the modem before the bluetooth code considers the profile fully activated. */ + if (rfcomm_dev) { + /* We want to early notify about the rfcomm path. That is because we might still delay + * to signal full activation longer (asynchronously). But the earliest time the callback + * is invoked with the rfcomm path, we just created the device synchronously. + * + * By already notifying the caller about the path early, it avoids a race where ModemManager + * would find the modem before the bluetooth code considers the profile fully activated. */ - nm_assert (!error); - nm_assert (bzobj->x_device.c_req_data); + nm_assert(!error); + nm_assert(bzobj->x_device.c_req_data); - if (!g_cancellable_is_cancelled (bzobj->x_device.c_req_data->ext_cancellable)) - bzobj->x_device.c_req_data->callback (bzobj->self, FALSE, rfcomm_dev, NULL, bzobj->x_device.c_req_data->callback_user_data); + if (!g_cancellable_is_cancelled(bzobj->x_device.c_req_data->ext_cancellable)) + bzobj->x_device.c_req_data->callback(bzobj->self, + FALSE, + rfcomm_dev, + NULL, + bzobj->x_device.c_req_data->callback_user_data); - if (!context) { - /* No context set. This means, we just got notified about the rfcomm path and need to wait - * longer, for the next callback. */ - return; - } - } + if (!context) { + /* No context set. This means, we just got notified about the rfcomm path and need to wait + * longer, for the next callback. */ + return; + } + } - _connect_returned (bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, rfcomm_dev, context, error); + _connect_returned(bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, rfcomm_dev, context, error); } static void -_connect_dun_step1_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - gs_unref_variant GVariant *ret = NULL; - gs_free_error GError *error = NULL; - BzDBusObj *bzobj_adapter; - BzDBusObj *bzobj; - - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); - - if ( !ret - && nm_utils_error_is_cancelled (error)) - return; - - bzobj = user_data; - - if (error) { - _LOGT ("DUN: [%s]: bluetooth device connect failed: %s", bzobj->object_path, error->message); - /* we actually ignore this error. Let's try, maybe we still can connect via DUN. */ - g_clear_error (&error); - } else - _LOGT ("DUN: [%s]: bluetooth device connected successfully", bzobj->object_path); - - if (!_bzobjs_device_is_usable (bzobj, &bzobj_adapter, NULL)) { - nm_utils_error_set (&error, NM_UTILS_ERROR_UNKNOWN, - "device %s is not usable for DUN after connect", - bzobj->object_path); - _connect_returned (bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, NULL, NULL, error); - return; - } - - if (!nm_bluez5_dun_connect (bzobj_adapter->d_adapter.address, - bzobj->d_device.address, - bzobj->x_device.c_req_data->int_cancellable, - _connect_dun_step2_cb, - bzobj, - _connect_dun_notify_tty_hangup_cb, - bzobj, - &error)) { - _connect_returned (bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, NULL, NULL, error); - return; - } +_connect_dun_step1_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + BzDBusObj * bzobj_adapter; + BzDBusObj * bzobj; + + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source_object), res, &error); + + if (!ret && nm_utils_error_is_cancelled(error)) + return; + + bzobj = user_data; + + if (error) { + _LOGT("DUN: [%s]: bluetooth device connect failed: %s", bzobj->object_path, error->message); + /* we actually ignore this error. Let's try, maybe we still can connect via DUN. */ + g_clear_error(&error); + } else + _LOGT("DUN: [%s]: bluetooth device connected successfully", bzobj->object_path); + + if (!_bzobjs_device_is_usable(bzobj, &bzobj_adapter, NULL)) { + nm_utils_error_set(&error, + NM_UTILS_ERROR_UNKNOWN, + "device %s is not usable for DUN after connect", + bzobj->object_path); + _connect_returned(bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, NULL, NULL, error); + return; + } + + if (!nm_bluez5_dun_connect(bzobj_adapter->d_adapter.address, + bzobj->d_device.address, + bzobj->x_device.c_req_data->int_cancellable, + _connect_dun_step2_cb, + bzobj, + _connect_dun_notify_tty_hangup_cb, + bzobj, + &error)) { + _connect_returned(bzobj->self, bzobj, NM_BT_CAPABILITY_DUN, NULL, NULL, error); + return; + } } #endif static void -_connect_nap_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_connect_nap_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - gs_unref_variant GVariant *ret = NULL; - const char *network_iface_name = NULL; - gs_free_error GError *error = NULL; - BzDBusObj *bzobj; + gs_unref_variant GVariant *ret = NULL; + const char * network_iface_name = NULL; + gs_free_error GError *error = NULL; + BzDBusObj * bzobj; - ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, &error); + ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source_object), res, &error); - if ( !ret - && nm_utils_error_is_cancelled (error)) - return; + if (!ret && nm_utils_error_is_cancelled(error)) + return; - if (ret) - g_variant_get (ret, "(&s)", &network_iface_name); + if (ret) + g_variant_get(ret, "(&s)", &network_iface_name); - bzobj = user_data; + bzobj = user_data; - _connect_returned (bzobj->self, bzobj, NM_BT_CAPABILITY_NAP, network_iface_name, NULL, error); + _connect_returned(bzobj->self, bzobj, NM_BT_CAPABILITY_NAP, network_iface_name, NULL, error); } static void -_connect_cancelled_cb (GCancellable *cancellable, - BzDBusObj *bzobj) +_connect_cancelled_cb(GCancellable *cancellable, BzDBusObj *bzobj) { - _connect_disconnect (bzobj->self, bzobj, "connect cancelled"); + _connect_disconnect(bzobj->self, bzobj, "connect cancelled"); } static gboolean -_connect_timeout_wait_connected_cb (gpointer user_data) +_connect_timeout_wait_connected_cb(gpointer user_data) { - BzDBusObj *bzobj = user_data; + BzDBusObj *bzobj = user_data; - bzobj->x_device.c_req_data->timeout_wait_connect_id = 0; - _connect_disconnect (bzobj->self, bzobj, "timeout waiting for connected"); - return G_SOURCE_REMOVE; + bzobj->x_device.c_req_data->timeout_wait_connect_id = 0; + _connect_disconnect(bzobj->self, bzobj, "timeout waiting for connected"); + return G_SOURCE_REMOVE; } static gboolean -_connect_timeout_cb (gpointer user_data) +_connect_timeout_cb(gpointer user_data) { - BzDBusObj *bzobj = user_data; + BzDBusObj *bzobj = user_data; - bzobj->x_device.c_req_data->timeout_id = 0; - _connect_disconnect (bzobj->self, bzobj, "timeout connecting"); - return G_SOURCE_REMOVE; + bzobj->x_device.c_req_data->timeout_id = 0; + _connect_disconnect(bzobj->self, bzobj, "timeout connecting"); + return G_SOURCE_REMOVE; } static void -_connect_disconnect (NMBluezManager *self, - BzDBusObj *bzobj, - const char *reason) -{ - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - DeviceConnectReqData *c_req_data; - char sbuf_cap[100]; - gboolean bt_type; - - if (bzobj->x_device_connect_bt_type == NM_BT_CAPABILITY_NONE) { - nm_assert (!bzobj->x_device.c_req_data); - return; - } - - bt_type = bzobj->x_device_connect_bt_type; - nm_assert (NM_IN_SET (bt_type, NM_BT_CAPABILITY_DUN, NM_BT_CAPABILITY_NAP)); - bzobj->x_device_connect_bt_type = NM_BT_CAPABILITY_NONE; - - c_req_data = g_steal_pointer (&bzobj->x_device.c_req_data); - - _LOGD ("%s [%s]: disconnect due to %s", - nm_bluetooth_capability_to_string (bt_type, sbuf_cap, sizeof (sbuf_cap)), - bzobj->object_path, - reason); - - if (c_req_data) - nm_clear_g_cancellable (&c_req_data->int_cancellable); - - if (bt_type == NM_BT_CAPABILITY_DUN) { - /* For DUN devices, we also called org.bluez.Device1.Connect() (because in order - * for nm_bluez5_dun_connect() to succeed, we need to be already connected *why??). - * - * But upon disconnect we don't call Disconnect() because we don't know whether somebody - * else also uses the bluetooth device for other purposes. During disconnect we only - * terminate the DUN connection, but don't disconnect entirely. I think that's the - * best we can do. */ +_connect_disconnect(NMBluezManager *self, BzDBusObj *bzobj, const char *reason) +{ + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + DeviceConnectReqData * c_req_data; + char sbuf_cap[100]; + gboolean bt_type; + + if (bzobj->x_device_connect_bt_type == NM_BT_CAPABILITY_NONE) { + nm_assert(!bzobj->x_device.c_req_data); + return; + } + + bt_type = bzobj->x_device_connect_bt_type; + nm_assert(NM_IN_SET(bt_type, NM_BT_CAPABILITY_DUN, NM_BT_CAPABILITY_NAP)); + bzobj->x_device_connect_bt_type = NM_BT_CAPABILITY_NONE; + + c_req_data = g_steal_pointer(&bzobj->x_device.c_req_data); + + _LOGD("%s [%s]: disconnect due to %s", + nm_bluetooth_capability_to_string(bt_type, sbuf_cap, sizeof(sbuf_cap)), + bzobj->object_path, + reason); + + if (c_req_data) + nm_clear_g_cancellable(&c_req_data->int_cancellable); + + if (bt_type == NM_BT_CAPABILITY_DUN) { + /* For DUN devices, we also called org.bluez.Device1.Connect() (because in order + * for nm_bluez5_dun_connect() to succeed, we need to be already connected *why??). + * + * But upon disconnect we don't call Disconnect() because we don't know whether somebody + * else also uses the bluetooth device for other purposes. During disconnect we only + * terminate the DUN connection, but don't disconnect entirely. I think that's the + * best we can do. */ #if WITH_BLUEZ5_DUN - nm_clear_pointer (&bzobj->x_device.connect_dun_context, nm_bluez5_dun_disconnect); + nm_clear_pointer(&bzobj->x_device.connect_dun_context, nm_bluez5_dun_disconnect); #else - nm_assert_not_reached (); + nm_assert_not_reached(); #endif - } else { - if (priv->name_owner) { - gs_unref_object GCancellable *cancellable = NULL; - - cancellable = g_cancellable_new (); - - nm_shutdown_wait_obj_register_cancellable_full (cancellable, - g_strdup_printf ("bt-disconnect-nap[%s]", bzobj->object_path), - TRUE); - - g_dbus_connection_call (priv->dbus_connection, - priv->name_owner, - bzobj->object_path, - NM_BLUEZ5_NETWORK_INTERFACE, - "Disconnect", - g_variant_new("()"), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - cancellable, - _dbus_call_complete_cb_nop, - NULL); - } - } - - if (c_req_data) { - gs_free_error GError *error = NULL; - - nm_utils_error_set (&error, - NM_UTILS_ERROR_UNKNOWN, - "connect aborted due to %s", - reason); - _device_connect_req_data_complete (c_req_data, self, NULL, error); - } + } else { + if (priv->name_owner) { + gs_unref_object GCancellable *cancellable = NULL; + + cancellable = g_cancellable_new(); + + nm_shutdown_wait_obj_register_cancellable_full( + cancellable, + g_strdup_printf("bt-disconnect-nap[%s]", bzobj->object_path), + TRUE); + + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + bzobj->object_path, + NM_BLUEZ5_NETWORK_INTERFACE, + "Disconnect", + g_variant_new("()"), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + cancellable, + _dbus_call_complete_cb_nop, + NULL); + } + } + + if (c_req_data) { + gs_free_error GError *error = NULL; + + nm_utils_error_set(&error, NM_UTILS_ERROR_UNKNOWN, "connect aborted due to %s", reason); + _device_connect_req_data_complete(c_req_data, self, NULL, error); + } } gboolean -nm_bluez_manager_connect (NMBluezManager *self, - const char *object_path, - NMBluetoothCapabilities connection_bt_type, - int timeout_msec, - GCancellable *cancellable, - NMBluezManagerConnectCb callback, - gpointer callback_user_data, - GError **error) -{ - gs_unref_object GCancellable *int_cancellable = NULL; - DeviceConnectReqData *c_req_data; - NMBluezManagerPrivate *priv; - BzDBusObj *bzobj; - char sbuf_cap[100]; - - g_return_val_if_fail (NM_IS_BLUEZ_MANAGER (self), FALSE); - g_return_val_if_fail (NM_IN_SET (connection_bt_type, NM_BT_CAPABILITY_DUN, - NM_BT_CAPABILITY_NAP), FALSE); - g_return_val_if_fail (callback, FALSE); - - nm_assert (timeout_msec > 0); - - priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); - - bzobj = _bzobjs_get (self, object_path); - - if (!bzobj) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "device %s does not exist", - object_path); - return FALSE; - } - - if (!_bzobjs_device_is_usable (bzobj, NULL, NULL)) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "device %s is not usable", - object_path); - return FALSE; - } - - if (!NM_FLAGS_ALL (bzobj->d_device_capabilities, connection_bt_type)) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "device %s has not the required capabilities", - object_path); - return FALSE; - } +nm_bluez_manager_connect(NMBluezManager * self, + const char * object_path, + NMBluetoothCapabilities connection_bt_type, + int timeout_msec, + GCancellable * cancellable, + NMBluezManagerConnectCb callback, + gpointer callback_user_data, + GError ** error) +{ + gs_unref_object GCancellable *int_cancellable = NULL; + DeviceConnectReqData * c_req_data; + NMBluezManagerPrivate * priv; + BzDBusObj * bzobj; + char sbuf_cap[100]; + + g_return_val_if_fail(NM_IS_BLUEZ_MANAGER(self), FALSE); + g_return_val_if_fail(NM_IN_SET(connection_bt_type, NM_BT_CAPABILITY_DUN, NM_BT_CAPABILITY_NAP), + FALSE); + g_return_val_if_fail(callback, FALSE); + + nm_assert(timeout_msec > 0); + + priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); + + bzobj = _bzobjs_get(self, object_path); + + if (!bzobj) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "device %s does not exist", object_path); + return FALSE; + } + + if (!_bzobjs_device_is_usable(bzobj, NULL, NULL)) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "device %s is not usable", object_path); + return FALSE; + } + + if (!NM_FLAGS_ALL(bzobj->d_device_capabilities, connection_bt_type)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "device %s has not the required capabilities", + object_path); + return FALSE; + } #if !WITH_BLUEZ5_DUN - if (connection_bt_type == NM_BT_CAPABILITY_DUN) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "DUN is not supported"); - return FALSE; - } + if (connection_bt_type == NM_BT_CAPABILITY_DUN) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "DUN is not supported"); + return FALSE; + } #endif - _connect_disconnect (self, bzobj, "new activation"); + _connect_disconnect(self, bzobj, "new activation"); - _LOGD ("%s [%s]: connecting...", - nm_bluetooth_capability_to_string (connection_bt_type, sbuf_cap, sizeof (sbuf_cap)), - bzobj->object_path); + _LOGD("%s [%s]: connecting...", + nm_bluetooth_capability_to_string(connection_bt_type, sbuf_cap, sizeof(sbuf_cap)), + bzobj->object_path); - int_cancellable = g_cancellable_new(); + int_cancellable = g_cancellable_new(); #if WITH_BLUEZ5_DUN - if (connection_bt_type == NM_BT_CAPABILITY_DUN) { - g_dbus_connection_call (priv->dbus_connection, - priv->name_owner, - bzobj->object_path, - NM_BLUEZ5_DEVICE_INTERFACE, - "Connect", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - timeout_msec, - int_cancellable, - _connect_dun_step1_cb, - bzobj); - } else + if (connection_bt_type == NM_BT_CAPABILITY_DUN) { + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + bzobj->object_path, + NM_BLUEZ5_DEVICE_INTERFACE, + "Connect", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + timeout_msec, + int_cancellable, + _connect_dun_step1_cb, + bzobj); + } else #endif - { - nm_assert (connection_bt_type == NM_BT_CAPABILITY_NAP); - g_dbus_connection_call (priv->dbus_connection, - priv->name_owner, - bzobj->object_path, - NM_BLUEZ5_NETWORK_INTERFACE, - "Connect", - g_variant_new ("(s)", BLUETOOTH_CONNECT_NAP), - G_VARIANT_TYPE ("(s)"), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - timeout_msec, - int_cancellable, - _connect_nap_cb, - bzobj); - } - - c_req_data = g_slice_new (DeviceConnectReqData); - *c_req_data = (DeviceConnectReqData) { - .int_cancellable = g_steal_pointer (&int_cancellable), - .ext_cancellable = g_object_ref (cancellable), - .callback = callback, - .callback_user_data = callback_user_data, - .ext_cancelled_id = g_signal_connect (cancellable, - "cancelled", - G_CALLBACK (_connect_cancelled_cb), - bzobj), - .timeout_id = g_timeout_add (timeout_msec, - _connect_timeout_cb, - bzobj), - }; - - bzobj->x_device_connect_bt_type = connection_bt_type; - bzobj->x_device.c_req_data = c_req_data; - - return TRUE; + { + nm_assert(connection_bt_type == NM_BT_CAPABILITY_NAP); + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + bzobj->object_path, + NM_BLUEZ5_NETWORK_INTERFACE, + "Connect", + g_variant_new("(s)", BLUETOOTH_CONNECT_NAP), + G_VARIANT_TYPE("(s)"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + timeout_msec, + int_cancellable, + _connect_nap_cb, + bzobj); + } + + c_req_data = g_slice_new(DeviceConnectReqData); + *c_req_data = (DeviceConnectReqData){ + .int_cancellable = g_steal_pointer(&int_cancellable), + .ext_cancellable = g_object_ref(cancellable), + .callback = callback, + .callback_user_data = callback_user_data, + .ext_cancelled_id = + g_signal_connect(cancellable, "cancelled", G_CALLBACK(_connect_cancelled_cb), bzobj), + .timeout_id = g_timeout_add(timeout_msec, _connect_timeout_cb, bzobj), + }; + + bzobj->x_device_connect_bt_type = connection_bt_type; + bzobj->x_device.c_req_data = c_req_data; + + return TRUE; } void -nm_bluez_manager_disconnect (NMBluezManager *self, - const char *object_path) +nm_bluez_manager_disconnect(NMBluezManager *self, const char *object_path) { - BzDBusObj *bzobj; + BzDBusObj *bzobj; - g_return_if_fail (NM_IS_BLUEZ_MANAGER (self)); - g_return_if_fail (object_path); + g_return_if_fail(NM_IS_BLUEZ_MANAGER(self)); + g_return_if_fail(object_path); - bzobj = _bzobjs_get (self, object_path); - if (!bzobj) - return; + bzobj = _bzobjs_get(self, object_path); + if (!bzobj) + return; - _connect_disconnect (self, bzobj, "disconnected by user"); + _connect_disconnect(self, bzobj, "disconnected by user"); } /*****************************************************************************/ static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - *out_ignore = TRUE; - g_return_val_if_fail (plink->type == NM_LINK_TYPE_BNEP, NULL); - return NULL; + *out_ignore = TRUE; + g_return_val_if_fail(plink->type == NM_LINK_TYPE_BNEP, NULL); + return NULL; } static gboolean -match_connection (NMDeviceFactory *factory, - NMConnection *connection) +match_connection(NMDeviceFactory *factory, NMConnection *connection) { - const char *type = nm_connection_get_connection_type (connection); + const char *type = nm_connection_get_connection_type(connection); - nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME)); + nm_assert(nm_streq(type, NM_SETTING_BLUETOOTH_SETTING_NAME)); - if (_nm_connection_get_setting_bluetooth_for_nap (connection)) - return FALSE; /* handled by the bridge factory */ + if (_nm_connection_get_setting_bluetooth_for_nap(connection)) + return FALSE; /* handled by the bridge factory */ - return TRUE; + return TRUE; } /*****************************************************************************/ static void -nm_bluez_manager_init (NMBluezManager *self) +nm_bluez_manager_init(NMBluezManager *self) { - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - priv->vtable_network_server = (NMBtVTableNetworkServer) { - .is_available = _network_server_vt_is_available, - .register_bridge = _network_server_vt_register_bridge, - .unregister_bridge = _network_server_vt_unregister_bridge, - }; + priv->vtable_network_server = (NMBtVTableNetworkServer){ + .is_available = _network_server_vt_is_available, + .register_bridge = _network_server_vt_register_bridge, + .unregister_bridge = _network_server_vt_unregister_bridge, + }; - c_list_init (&priv->network_server_lst_head); - c_list_init (&priv->process_change_lst_head); + c_list_init(&priv->network_server_lst_head); + c_list_init(&priv->process_change_lst_head); - priv->conn_data_heads = g_hash_table_new_full (_conn_data_head_hash, _conn_data_head_equal, g_free, NULL); - priv->conn_data_elems = g_hash_table_new_full (nm_pdirect_hash, nm_pdirect_equal, nm_g_slice_free_fcn (ConnDataElem), NULL); + priv->conn_data_heads = + g_hash_table_new_full(_conn_data_head_hash, _conn_data_head_equal, g_free, NULL); + priv->conn_data_elems = g_hash_table_new_full(nm_pdirect_hash, + nm_pdirect_equal, + nm_g_slice_free_fcn(ConnDataElem), + NULL); - priv->bzobjs = g_hash_table_new_full (nm_pstr_hash, nm_pstr_equal, (GDestroyNotify) _bz_dbus_obj_free, NULL); + priv->bzobjs = g_hash_table_new_full(nm_pstr_hash, + nm_pstr_equal, + (GDestroyNotify) _bz_dbus_obj_free, + NULL); - priv->manager = g_object_ref (NM_MANAGER_GET); - priv->settings = g_object_ref (NM_SETTINGS_GET); - priv->dbus_connection = nm_g_object_ref (NM_MAIN_DBUS_CONNECTION_GET); + priv->manager = g_object_ref(NM_MANAGER_GET); + priv->settings = g_object_ref(NM_SETTINGS_GET); + priv->dbus_connection = nm_g_object_ref(NM_MAIN_DBUS_CONNECTION_GET); - g_atomic_pointer_compare_and_exchange (&nm_bt_vtable_network_server, NULL, &priv->vtable_network_server); + g_atomic_pointer_compare_and_exchange(&nm_bt_vtable_network_server, + NULL, + &priv->vtable_network_server); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMBluezManager *self = NM_BLUEZ_MANAGER (object); - NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self); + NMBluezManager * self = NM_BLUEZ_MANAGER(object); + NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - /* FIXME(shutdown): we need a nm_device_factory_stop() hook to first unregister all - * BzDBusObj instances and do necessary cleanup actions (like disconnecting devices - * or deleting panu_connection). */ + /* FIXME(shutdown): we need a nm_device_factory_stop() hook to first unregister all + * BzDBusObj instances and do necessary cleanup actions (like disconnecting devices + * or deleting panu_connection). */ - nm_assert (c_list_is_empty (&priv->network_server_lst_head)); - nm_assert (c_list_is_empty (&priv->process_change_lst_head)); - nm_assert (priv->process_change_idle_id == 0); + nm_assert(c_list_is_empty(&priv->network_server_lst_head)); + nm_assert(c_list_is_empty(&priv->process_change_lst_head)); + nm_assert(priv->process_change_idle_id == 0); - g_atomic_pointer_compare_and_exchange (&nm_bt_vtable_network_server, &priv->vtable_network_server, NULL); + g_atomic_pointer_compare_and_exchange(&nm_bt_vtable_network_server, + &priv->vtable_network_server, + NULL); - _cleanup_all (self); + _cleanup_all(self); - G_OBJECT_CLASS (nm_bluez_manager_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_bluez_manager_parent_class)->dispose(object); - g_clear_object (&priv->settings); - g_clear_object (&priv->manager); - g_clear_object (&priv->dbus_connection); + g_clear_object(&priv->settings); + g_clear_object(&priv->manager); + g_clear_object(&priv->dbus_connection); - nm_clear_pointer (&priv->bzobjs, g_hash_table_destroy); + nm_clear_pointer(&priv->bzobjs, g_hash_table_destroy); } static void -nm_bluez_manager_class_init (NMBluezManagerClass *klass) +nm_bluez_manager_class_init(NMBluezManagerClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - factory_class->get_supported_types = get_supported_types; - factory_class->create_device = create_device; - factory_class->match_connection = match_connection; - factory_class->start = start; + factory_class->get_supported_types = get_supported_types; + factory_class->create_device = create_device; + factory_class->match_connection = match_connection; + factory_class->start = start; } diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h index 85dbaa83..40a2fcdd 100644 --- a/src/devices/bluetooth/nm-bluez-manager.h +++ b/src/devices/bluetooth/nm-bluez-manager.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2009 - 2019 Red Hat, Inc. */ @@ -6,34 +6,37 @@ #ifndef __NM_BLUEZ_MANAGER_H__ #define __NM_BLUEZ_MANAGER_H__ -#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ()) -#define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager)) -#define NM_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) -#define NM_IS_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_BLUEZ_MANAGER)) -#define NM_IS_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ_MANAGER)) -#define NM_BLUEZ_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) - -typedef struct _NMBluezManager NMBluezManager; +#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type()) +#define NM_BLUEZ_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager)) +#define NM_BLUEZ_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) +#define NM_IS_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_BLUEZ_MANAGER)) +#define NM_IS_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_BLUEZ_MANAGER)) +#define NM_BLUEZ_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass)) + +typedef struct _NMBluezManager NMBluezManager; typedef struct _NMBluezManagerClass NMBluezManagerClass; -GType nm_bluez_manager_get_type (void); - -typedef void (*NMBluezManagerConnectCb) (NMBluezManager *self, - gboolean is_completed /* or else is early notification with DUN path */, - const char *device_name, - GError *error, - gpointer user_data); - -gboolean nm_bluez_manager_connect (NMBluezManager *self, - const char *object_path, - NMBluetoothCapabilities connection_bt_type, - int timeout_msec, - GCancellable *cancellable, - NMBluezManagerConnectCb callback, - gpointer callback_user_data, - GError **error); - -void nm_bluez_manager_disconnect (NMBluezManager *self, - const char *object_path); +GType nm_bluez_manager_get_type(void); + +typedef void (*NMBluezManagerConnectCb)( + NMBluezManager *self, + gboolean is_completed /* or else is early notification with DUN path */, + const char * device_name, + GError * error, + gpointer user_data); + +gboolean nm_bluez_manager_connect(NMBluezManager * self, + const char * object_path, + NMBluetoothCapabilities connection_bt_type, + int timeout_msec, + GCancellable * cancellable, + NMBluezManagerConnectCb callback, + gpointer callback_user_data, + GError ** error); + +void nm_bluez_manager_disconnect(NMBluezManager *self, const char *object_path); #endif /* __NM_BLUEZ_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c index c253d4e2..422c8516 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.c +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -23,843 +23,835 @@ /*****************************************************************************/ typedef struct { - GCancellable *cancellable; - NMBluez5DunConnectCb callback; - gpointer callback_user_data; + GCancellable * cancellable; + NMBluez5DunConnectCb callback; + gpointer callback_user_data; - sdp_session_t *sdp_session; + sdp_session_t *sdp_session; - GError *rfcomm_sdp_search_error; + GError *rfcomm_sdp_search_error; - GSource *source; + GSource *source; - gint64 connect_open_tty_started_at; + gint64 connect_open_tty_started_at; - gulong cancelled_id; + gulong cancelled_id; - guint8 sdp_session_try_count; + guint8 sdp_session_try_count; } ConnectData; struct _NMBluez5DunContext { - const char *dst_str; + const char *dst_str; - ConnectData *cdat; + ConnectData *cdat; - NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb; - gpointer notify_tty_hangup_user_data; + NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb; + gpointer notify_tty_hangup_user_data; - char *rfcomm_tty_path; + char *rfcomm_tty_path; - GSource *rfcomm_tty_poll_source; + GSource *rfcomm_tty_poll_source; - int rfcomm_sock_fd; - int rfcomm_tty_fd; - int rfcomm_tty_no; - int rfcomm_channel; + int rfcomm_sock_fd; + int rfcomm_tty_fd; + int rfcomm_tty_no; + int rfcomm_channel; - bdaddr_t src; - bdaddr_t dst; + bdaddr_t src; + bdaddr_t dst; - char src_str[]; + char src_str[]; }; /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_BT #define _NMLOG_PREFIX_NAME "bluez" -#define _NMLOG(level, context, ...) \ - G_STMT_START { \ - if (nm_logging_enabled ((level), (_NMLOG_DOMAIN))) { \ - const NMBluez5DunContext *const _context = (context); \ - \ - _nm_log ((level), (_NMLOG_DOMAIN), 0, NULL, NULL, \ - "%s: DUN[%s] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - _context->src_str \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG(level, context, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + const NMBluez5DunContext *const _context = (context); \ + \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s: DUN[%s] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + _context->src_str _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -static void _context_invoke_callback_success (NMBluez5DunContext *context); -static void _context_invoke_callback_fail_and_free (NMBluez5DunContext *context, - GError *error); -static void _context_free (NMBluez5DunContext *context); -static int _connect_open_tty (NMBluez5DunContext *context); -static gboolean _connect_sdp_session_start (NMBluez5DunContext *context, - GError **error); +static void _context_invoke_callback_success(NMBluez5DunContext *context); +static void _context_invoke_callback_fail_and_free(NMBluez5DunContext *context, GError *error); +static void _context_free(NMBluez5DunContext *context); +static int _connect_open_tty(NMBluez5DunContext *context); +static gboolean _connect_sdp_session_start(NMBluez5DunContext *context, GError **error); /*****************************************************************************/ -NM_AUTO_DEFINE_FCN0 (NMBluez5DunContext *, _nm_auto_free_context, _context_free) +NM_AUTO_DEFINE_FCN0(NMBluez5DunContext *, _nm_auto_free_context, _context_free); #define nm_auto_free_context nm_auto(_nm_auto_free_context) /*****************************************************************************/ const char * -nm_bluez5_dun_context_get_adapter (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_adapter(const NMBluez5DunContext *context) { - return context->src_str; + return context->src_str; } const char * -nm_bluez5_dun_context_get_remote (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_remote(const NMBluez5DunContext *context) { - return context->dst_str; + return context->dst_str; } const char * -nm_bluez5_dun_context_get_rfcomm_dev (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_rfcomm_dev(const NMBluez5DunContext *context) { - return context->rfcomm_tty_path; + return context->rfcomm_tty_path; } /*****************************************************************************/ static gboolean -_rfcomm_tty_poll_cb (int fd, - GIOCondition condition, - gpointer user_data) +_rfcomm_tty_poll_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; + NMBluez5DunContext *context = user_data; - _LOGD (context, "receive %s%s%s signal on rfcomm file descriptor", - NM_FLAGS_HAS (condition, G_IO_ERR) ? "ERR" : "", - NM_FLAGS_ALL (condition, G_IO_HUP | G_IO_ERR) ? "," : "", - NM_FLAGS_HAS (condition, G_IO_HUP) ? "HUP" : ""); + _LOGD(context, + "receive %s%s%s signal on rfcomm file descriptor", + NM_FLAGS_HAS(condition, G_IO_ERR) ? "ERR" : "", + NM_FLAGS_ALL(condition, G_IO_HUP | G_IO_ERR) ? "," : "", + NM_FLAGS_HAS(condition, G_IO_HUP) ? "HUP" : ""); - nm_clear_g_source_inst (&context->rfcomm_tty_poll_source); - context->notify_tty_hangup_cb (context, - context->notify_tty_hangup_user_data); - return G_SOURCE_REMOVE; + nm_clear_g_source_inst(&context->rfcomm_tty_poll_source); + context->notify_tty_hangup_cb(context, context->notify_tty_hangup_user_data); + return G_SOURCE_REMOVE; } static gboolean -_connect_open_tty_retry_cb (gpointer user_data) +_connect_open_tty_retry_cb(gpointer user_data) { - NMBluez5DunContext *context = user_data; - int r; - - r = _connect_open_tty (context); - if (r >= 0) - return G_SOURCE_REMOVE; - - if (nm_utils_get_monotonic_timestamp_nsec () > context->cdat->connect_open_tty_started_at + (30 * 100 * NM_UTILS_NSEC_PER_MSEC)) { - gs_free_error GError *error = NULL; - - nm_clear_g_source_inst (&context->cdat->source); - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "give up waiting to open %s device: %s (%d)", - context->rfcomm_tty_path, - nm_strerror_native (r), - -r); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - return G_SOURCE_CONTINUE; + NMBluez5DunContext *context = user_data; + int r; + + r = _connect_open_tty(context); + if (r >= 0) + return G_SOURCE_REMOVE; + + if (nm_utils_get_monotonic_timestamp_nsec() + > context->cdat->connect_open_tty_started_at + (30 * 100 * NM_UTILS_NSEC_PER_MSEC)) { + gs_free_error GError *error = NULL; + + nm_clear_g_source_inst(&context->cdat->source); + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "give up waiting to open %s device: %s (%d)", + context->rfcomm_tty_path, + nm_strerror_native(r), + -r); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; } static int -_connect_open_tty (NMBluez5DunContext *context) +_connect_open_tty(NMBluez5DunContext *context) { - int fd; - int errsv; - - fd = open (context->rfcomm_tty_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); - if (fd < 0) { - errsv = NM_ERRNO_NATIVE (errno); - - if (!context->cdat->source) { - _LOGD (context, "failed opening tty "RFCOMM_FMT": %s (%d). Start polling...", - context->rfcomm_tty_no, - nm_strerror_native (errsv), - errsv); - context->cdat->connect_open_tty_started_at = nm_utils_get_monotonic_timestamp_nsec (); - context->cdat->source = nm_g_timeout_source_new (100, - G_PRIORITY_DEFAULT, - _connect_open_tty_retry_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - } - return -errsv; - } - - context->rfcomm_tty_fd = fd; - - context->rfcomm_tty_poll_source = nm_g_unix_fd_source_new (context->rfcomm_tty_fd, - G_IO_ERR | G_IO_HUP, - G_PRIORITY_DEFAULT, - _rfcomm_tty_poll_cb, - context, - NULL); - g_source_attach (context->rfcomm_tty_poll_source, NULL); - - _context_invoke_callback_success (context); - return 0; + int fd; + int errsv; + + fd = open(context->rfcomm_tty_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); + if (fd < 0) { + errsv = NM_ERRNO_NATIVE(errno); + + if (!context->cdat->source) { + _LOGD(context, + "failed opening tty " RFCOMM_FMT ": %s (%d). Start polling...", + context->rfcomm_tty_no, + nm_strerror_native(errsv), + errsv); + context->cdat->connect_open_tty_started_at = nm_utils_get_monotonic_timestamp_nsec(); + context->cdat->source = nm_g_timeout_source_new(100, + G_PRIORITY_DEFAULT, + _connect_open_tty_retry_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + } + return -errsv; + } + + context->rfcomm_tty_fd = fd; + + context->rfcomm_tty_poll_source = nm_g_unix_fd_source_new(context->rfcomm_tty_fd, + G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + _rfcomm_tty_poll_cb, + context, + NULL); + g_source_attach(context->rfcomm_tty_poll_source, NULL); + + _context_invoke_callback_success(context); + return 0; } static void -_connect_create_rfcomm (NMBluez5DunContext *context) +_connect_create_rfcomm(NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; - struct rfcomm_dev_req req; - int devid; - int errsv; - int r; - - _LOGD (context, "connected to %s on channel %d", - context->dst_str, context->rfcomm_channel); - - /* Create an RFCOMM kernel device for the DUN channel */ - memset (&req, 0, sizeof (req)); - req.dev_id = -1; - req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); - req.channel = context->rfcomm_channel; - memcpy (&req.src, &context->src, ETH_ALEN); - memcpy (&req.dst, &context->dst, ETH_ALEN); - devid = ioctl (context->rfcomm_sock_fd, RFCOMMCREATEDEV, &req); - if (devid < 0) { - errsv = NM_ERRNO_NATIVE (errno); - if (errsv == EBADFD) { - /* hm. We use a non-blocking socket to connect. Above getsockopt(SOL_SOCKET,SO_ERROR) indicated - * success, but still now we fail with EBADFD. I think that is a bug and we should get the - * failure during connect(). - * - * Anyway, craft a less confusing error message than - * "failed to create rfcomm device: File descriptor in bad state (77)". */ - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "unknown failure to connect to DUN device"); - } else { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to create rfcomm device: %s (%d)", - nm_strerror_native (errsv), errsv); - } - _context_invoke_callback_fail_and_free (context, error); - return; - } - - context->rfcomm_tty_no = devid; - context->rfcomm_tty_path = g_strdup_printf (RFCOMM_FMT, devid); - - r = _connect_open_tty (context); - if (r < 0) { - /* we created the rfcomm device, but cannot yet open it. That means, we are - * not yet fully connected. However, we notify the caller about "what we learned - * so far". Note that this happens synchronously. - * - * The purpose is that once we proceed synchrnously, modem-manager races with - * the detection of the modem. We want to notify the caller first about the - * device name. */ - context->cdat->callback (NULL, - context->rfcomm_tty_path, - NULL, - context->cdat->callback_user_data); - } + gs_free_error GError *error = NULL; + struct rfcomm_dev_req req; + int devid; + int errsv; + int r; + + _LOGD(context, "connected to %s on channel %d", context->dst_str, context->rfcomm_channel); + + /* Create an RFCOMM kernel device for the DUN channel */ + memset(&req, 0, sizeof(req)); + req.dev_id = -1; + req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); + req.channel = context->rfcomm_channel; + memcpy(&req.src, &context->src, ETH_ALEN); + memcpy(&req.dst, &context->dst, ETH_ALEN); + devid = ioctl(context->rfcomm_sock_fd, RFCOMMCREATEDEV, &req); + if (devid < 0) { + errsv = NM_ERRNO_NATIVE(errno); + if (errsv == EBADFD) { + /* hm. We use a non-blocking socket to connect. Above getsockopt(SOL_SOCKET,SO_ERROR) indicated + * success, but still now we fail with EBADFD. I think that is a bug and we should get the + * failure during connect(). + * + * Anyway, craft a less confusing error message than + * "failed to create rfcomm device: File descriptor in bad state (77)". */ + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "unknown failure to connect to DUN device"); + } else { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to create rfcomm device: %s (%d)", + nm_strerror_native(errsv), + errsv); + } + _context_invoke_callback_fail_and_free(context, error); + return; + } + + context->rfcomm_tty_no = devid; + context->rfcomm_tty_path = g_strdup_printf(RFCOMM_FMT, devid); + + r = _connect_open_tty(context); + if (r < 0) { + /* we created the rfcomm device, but cannot yet open it. That means, we are + * not yet fully connected. However, we notify the caller about "what we learned + * so far". Note that this happens synchronously. + * + * The purpose is that once we proceed synchronously, modem-manager races with + * the detection of the modem. We want to notify the caller first about the + * device name. */ + context->cdat->callback(NULL, + context->rfcomm_tty_path, + NULL, + context->cdat->callback_user_data); + } } static gboolean -_connect_socket_connect_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_socket_connect_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; - int errsv = 0; - socklen_t slen = sizeof(errsv); - int r; - - nm_clear_g_source_inst (&context->cdat->source); - - r = getsockopt (context->rfcomm_sock_fd, SOL_SOCKET, SO_ERROR, &errsv, &slen); - - if (r < 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to complete connecting RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (errsv != 0) { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - _connect_create_rfcomm (context); - return G_SOURCE_REMOVE; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; + int errsv = 0; + socklen_t slen = sizeof(errsv); + int r; + + nm_clear_g_source_inst(&context->cdat->source); + + r = getsockopt(context->rfcomm_sock_fd, SOL_SOCKET, SO_ERROR, &errsv, &slen); + + if (r < 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to complete connecting RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (errsv != 0) { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + _connect_create_rfcomm(context); + return G_SOURCE_REMOVE; } static void -_connect_socket_connect (NMBluez5DunContext *context) +_connect_socket_connect(NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; - struct sockaddr_rc sa; - int errsv; - - context->rfcomm_sock_fd = socket (AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_RFCOMM); - if (context->rfcomm_sock_fd < 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to create RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - /* Connect to the remote device */ - memset (&sa, 0, sizeof (sa)); - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = 0; - memcpy (&sa.rc_bdaddr, &context->src, ETH_ALEN); - if (bind (context->rfcomm_sock_fd, - (struct sockaddr *) &sa, - sizeof(sa)) != 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to bind socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - memset (&sa, 0, sizeof (sa)); - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = context->rfcomm_channel; - memcpy (&sa.rc_bdaddr, &context->dst, ETH_ALEN); - if (connect (context->rfcomm_sock_fd, - (struct sockaddr *) &sa, - sizeof (sa)) != 0) { - - errsv = errno; - if (errsv != EINPROGRESS) { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect to remote device: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - _LOGD (context, "connecting to %s on channel %d...", - context->dst_str, - context->rfcomm_channel); - - context->cdat->source = nm_g_unix_fd_source_new (context->rfcomm_sock_fd, - G_IO_OUT, - G_PRIORITY_DEFAULT, - _connect_socket_connect_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return; - } - - _connect_create_rfcomm (context); + gs_free_error GError *error = NULL; + struct sockaddr_rc sa; + int errsv; + + context->rfcomm_sock_fd = + socket(AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_RFCOMM); + if (context->rfcomm_sock_fd < 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to create RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + /* Connect to the remote device */ + memset(&sa, 0, sizeof(sa)); + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = 0; + memcpy(&sa.rc_bdaddr, &context->src, ETH_ALEN); + if (bind(context->rfcomm_sock_fd, (struct sockaddr *) &sa, sizeof(sa)) != 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to bind socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + memset(&sa, 0, sizeof(sa)); + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = context->rfcomm_channel; + memcpy(&sa.rc_bdaddr, &context->dst, ETH_ALEN); + if (connect(context->rfcomm_sock_fd, (struct sockaddr *) &sa, sizeof(sa)) != 0) { + errsv = errno; + if (errsv != EINPROGRESS) { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect to remote device: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + _LOGD(context, + "connecting to %s on channel %d...", + context->dst_str, + context->rfcomm_channel); + + context->cdat->source = nm_g_unix_fd_source_new(context->rfcomm_sock_fd, + G_IO_OUT, + G_PRIORITY_DEFAULT, + _connect_socket_connect_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return; + } + + _connect_create_rfcomm(context); } static void -_connect_sdp_search_cb (uint8_t type, - uint16_t status, - uint8_t *rsp, - size_t size, - void *user_data) +_connect_sdp_search_cb(uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data) { - NMBluez5DunContext *context = user_data; - int scanned; - int seqlen = 0; - int bytesleft = size; - uint8_t dataType; - int channel = -1; - - if ( context->cdat->rfcomm_sdp_search_error - || context->rfcomm_channel >= 0) - return; - - _LOGD (context, "SDP search finished with type=%d status=%d", - status, type); - - /* SDP response received */ - if ( status - || type != SDP_SVC_SEARCH_ATTR_RSP) { - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "did not get a Service Discovery response"); - return; - } - - scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); - - _LOGD (context, "SDP sequence type scanned=%d length=%d", - scanned, seqlen); - - scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); - if ( !scanned - || !seqlen) { - /* Short read or unknown sequence type */ - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "improper Service Discovery response"); - return; - } - - rsp += scanned; - bytesleft -= scanned; - do { - sdp_record_t *rec; - int recsize = 0; - sdp_list_t *protos; - - rec = sdp_extract_pdu (rsp, bytesleft, &recsize); - if (!rec) - break; - - if (!recsize) { - sdp_record_free (rec); - break; - } - - if (sdp_get_access_protos (rec, &protos) == 0) { - /* Extract the DUN channel number */ - channel = sdp_get_proto_port (protos, RFCOMM_UUID); - sdp_list_free (protos, NULL); - - _LOGD (context, "SDP channel=%d", - channel); - } - sdp_record_free (rec); - - scanned += recsize; - rsp += recsize; - bytesleft -= recsize; - } while ( scanned < (ssize_t) size - && bytesleft > 0 - && channel < 0); - - if (channel == -1) { - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "did not receive rfcomm-channel"); - return; - } - - context->rfcomm_channel = channel; + NMBluez5DunContext *context = user_data; + int scanned; + int seqlen = 0; + int bytesleft = size; + uint8_t dataType; + int channel = -1; + + if (context->cdat->rfcomm_sdp_search_error || context->rfcomm_channel >= 0) + return; + + _LOGD(context, "SDP search finished with type=%d status=%d", status, type); + + /* SDP response received */ + if (status || type != SDP_SVC_SEARCH_ATTR_RSP) { + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "did not get a Service Discovery response"); + return; + } + + scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen); + + _LOGD(context, "SDP sequence type scanned=%d length=%d", scanned, seqlen); + + scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen); + if (!scanned || !seqlen) { + /* Short read or unknown sequence type */ + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "improper Service Discovery response"); + return; + } + + rsp += scanned; + bytesleft -= scanned; + do { + sdp_record_t *rec; + int recsize = 0; + sdp_list_t * protos; + + rec = sdp_extract_pdu(rsp, bytesleft, &recsize); + if (!rec) + break; + + if (!recsize) { + sdp_record_free(rec); + break; + } + + if (sdp_get_access_protos(rec, &protos) == 0) { + /* Extract the DUN channel number */ + channel = sdp_get_proto_port(protos, RFCOMM_UUID); + sdp_list_free(protos, NULL); + + _LOGD(context, "SDP channel=%d", channel); + } + sdp_record_free(rec); + + scanned += recsize; + rsp += recsize; + bytesleft -= recsize; + } while (scanned < (ssize_t) size && bytesleft > 0 && channel < 0); + + if (channel == -1) { + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "did not receive rfcomm-channel"); + return; + } + + context->rfcomm_channel = channel; } static gboolean -_connect_sdp_search_io_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_sdp_search_io_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; - int errsv; - - if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { - _LOGD (context, "SDP search returned with invalid IO condition 0x%x", - (guint) condition); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "Service Discovery interrupted"); - nm_clear_g_source_inst (&context->cdat->source); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (sdp_process (context->cdat->sdp_session) == 0) { - _LOGD (context, "SDP search still not finished"); - return G_SOURCE_CONTINUE; - } - - nm_clear_g_source_inst (&context->cdat->source); - - if ( context->rfcomm_channel < 0 - && !context->cdat->rfcomm_sdp_search_error) { - errsv = sdp_get_error (context->cdat->sdp_session); - _LOGD (context, "SDP search failed: %s (%d)", - nm_strerror_native (errsv), errsv); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "Service Discovery failed with %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (context->cdat->rfcomm_sdp_search_error) { - _LOGD (context, "SDP search failed to complete: %s", context->cdat->rfcomm_sdp_search_error->message); - _context_invoke_callback_fail_and_free (context, context->cdat->rfcomm_sdp_search_error); - return G_SOURCE_REMOVE; - } - - nm_clear_pointer (&context->cdat->sdp_session, sdp_close); - - _connect_socket_connect (context); - - return G_SOURCE_REMOVE; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; + int errsv; + + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + _LOGD(context, "SDP search returned with invalid IO condition 0x%x", (guint) condition); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery interrupted"); + nm_clear_g_source_inst(&context->cdat->source); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (sdp_process(context->cdat->sdp_session) == 0) { + _LOGD(context, "SDP search still not finished"); + return G_SOURCE_CONTINUE; + } + + nm_clear_g_source_inst(&context->cdat->source); + + if (context->rfcomm_channel < 0 && !context->cdat->rfcomm_sdp_search_error) { + errsv = sdp_get_error(context->cdat->sdp_session); + _LOGD(context, "SDP search failed: %s (%d)", nm_strerror_native(errsv), errsv); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery failed with %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (context->cdat->rfcomm_sdp_search_error) { + _LOGD(context, + "SDP search failed to complete: %s", + context->cdat->rfcomm_sdp_search_error->message); + _context_invoke_callback_fail_and_free(context, context->cdat->rfcomm_sdp_search_error); + return G_SOURCE_REMOVE; + } + + nm_clear_pointer(&context->cdat->sdp_session, sdp_close); + + _connect_socket_connect(context); + + return G_SOURCE_REMOVE; } static gboolean -_connect_sdp_session_start_on_idle_cb (gpointer user_data) +_connect_sdp_session_start_on_idle_cb(gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; - nm_clear_g_source_inst (&context->cdat->source); + nm_clear_g_source_inst(&context->cdat->source); - _LOGD (context, "retry starting sdp-session..."); + _LOGD(context, "retry starting sdp-session..."); - if (!_connect_sdp_session_start (context, &error)) - _context_invoke_callback_fail_and_free (context, error); + if (!_connect_sdp_session_start(context, &error)) + _context_invoke_callback_fail_and_free(context, error); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean -_connect_sdp_io_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_sdp_io_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - sdp_list_t *search; - sdp_list_t *attrs; - uuid_t svclass; - uint16_t attr; - int errsv; - int fd_err = 0; - int r; - socklen_t len = sizeof (fd_err); - gs_free_error GError *error = NULL; - - nm_clear_g_source_inst (&context->cdat->source); - - _LOGD (context, "sdp-session ready to connect with fd=%d", fd); - - if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { - errsv = NM_ERRNO_NATIVE (errno); - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "error for getsockopt on Service Discovery socket: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - if (fd_err != 0) { - errsv = nm_errno_native (fd_err); - - if ( NM_IN_SET (errsv, ECONNREFUSED, EHOSTDOWN) - && --context->cdat->sdp_session_try_count > 0) { - /* *sigh* */ - _LOGD (context, "sdp-session failed with %s (%d). Retry in a bit", nm_strerror_native (errsv), errsv); - nm_clear_g_source_inst (&context->cdat->source); - context->cdat->source = nm_g_timeout_source_new (1000, - G_PRIORITY_DEFAULT, - _connect_sdp_session_start_on_idle_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return G_SOURCE_REMOVE; - } - - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "error on Service Discovery socket: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - if (sdp_set_notify (context->cdat->sdp_session, _connect_sdp_search_cb, context) < 0) { - /* Should not be reached, only can fail if we passed bad sdp_session. */ - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "could not set Service Discovery notification"); - goto done; - } - - sdp_uuid16_create (&svclass, DIALUP_NET_SVCLASS_ID); - search = sdp_list_append (NULL, &svclass); - attr = SDP_ATTR_PROTO_DESC_LIST; - attrs = sdp_list_append (NULL, &attr); - - r = sdp_service_search_attr_async (context->cdat->sdp_session, - search, - SDP_ATTR_REQ_INDIVIDUAL, - attrs); - - sdp_list_free (attrs, NULL); - sdp_list_free (search, NULL); - - if (r < 0) { - errsv = nm_errno_native (sdp_get_error (context->cdat->sdp_session)); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "error starting Service Discovery: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - /* Set callback responsible for update the internal SDP transaction */ - context->cdat->source = nm_g_unix_fd_source_new (fd, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, - _connect_sdp_search_io_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); + NMBluez5DunContext *context = user_data; + sdp_list_t * search; + sdp_list_t * attrs; + uuid_t svclass; + uint16_t attr; + int errsv; + int fd_err = 0; + int r; + socklen_t len = sizeof(fd_err); + gs_free_error GError *error = NULL; + + nm_clear_g_source_inst(&context->cdat->source); + + _LOGD(context, "sdp-session ready to connect with fd=%d", fd); + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { + errsv = NM_ERRNO_NATIVE(errno); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error for getsockopt on Service Discovery socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + if (fd_err != 0) { + errsv = nm_errno_native(fd_err); + + if (NM_IN_SET(errsv, ECONNREFUSED, EHOSTDOWN) + && --context->cdat->sdp_session_try_count > 0) { + /* *sigh* */ + _LOGD(context, + "sdp-session failed with %s (%d). Retry in a bit", + nm_strerror_native(errsv), + errsv); + nm_clear_g_source_inst(&context->cdat->source); + context->cdat->source = nm_g_timeout_source_new(1000, + G_PRIORITY_DEFAULT, + _connect_sdp_session_start_on_idle_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return G_SOURCE_REMOVE; + } + + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error on Service Discovery socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + if (sdp_set_notify(context->cdat->sdp_session, _connect_sdp_search_cb, context) < 0) { + /* Should not be reached, only can fail if we passed bad sdp_session. */ + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "could not set Service Discovery notification"); + goto done; + } + + sdp_uuid16_create(&svclass, DIALUP_NET_SVCLASS_ID); + search = sdp_list_append(NULL, &svclass); + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + r = sdp_service_search_attr_async(context->cdat->sdp_session, + search, + SDP_ATTR_REQ_INDIVIDUAL, + attrs); + + sdp_list_free(attrs, NULL); + sdp_list_free(search, NULL); + + if (r < 0) { + errsv = nm_errno_native(sdp_get_error(context->cdat->sdp_session)); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error starting Service Discovery: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + /* Set callback responsible for update the internal SDP transaction */ + context->cdat->source = nm_g_unix_fd_source_new(fd, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + G_PRIORITY_DEFAULT, + _connect_sdp_search_io_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); done: - if (error) - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; + if (error) + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; } /*****************************************************************************/ static void -_connect_cancelled_cb (GCancellable *cancellable, - NMBluez5DunContext *context) +_connect_cancelled_cb(GCancellable *cancellable, NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) - g_return_if_reached (); + if (!g_cancellable_set_error_if_cancelled(cancellable, &error)) + g_return_if_reached(); - _context_invoke_callback_fail_and_free (context, error); + _context_invoke_callback_fail_and_free(context, error); } static gboolean -_connect_sdp_session_start (NMBluez5DunContext *context, - GError **error) +_connect_sdp_session_start(NMBluez5DunContext *context, GError **error) { - nm_assert (context->cdat); - - nm_clear_g_source_inst (&context->cdat->source); - nm_clear_pointer (&context->cdat->sdp_session, sdp_close); - - context->cdat->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING); - if (!context->cdat->sdp_session) { - int errsv = nm_errno_native (errno); - - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect to the SDP server: %s (%d)", - nm_strerror_native (errsv), errsv); - return FALSE; - } - - context->cdat->source = nm_g_unix_fd_source_new (sdp_get_socket (context->cdat->sdp_session), - G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, - _connect_sdp_io_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return TRUE; + nm_assert(context->cdat); + + nm_clear_g_source_inst(&context->cdat->source); + nm_clear_pointer(&context->cdat->sdp_session, sdp_close); + + context->cdat->sdp_session = sdp_connect(&context->src, &context->dst, SDP_NON_BLOCKING); + if (!context->cdat->sdp_session) { + int errsv = nm_errno_native(errno); + + g_set_error(error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect to the SDP server: %s (%d)", + nm_strerror_native(errsv), + errsv); + return FALSE; + } + + context->cdat->source = nm_g_unix_fd_source_new(sdp_get_socket(context->cdat->sdp_session), + G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + G_PRIORITY_DEFAULT, + _connect_sdp_io_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return TRUE; } /*****************************************************************************/ gboolean -nm_bluez5_dun_connect (const char *adapter, - const char *remote, - GCancellable *cancellable, - NMBluez5DunConnectCb callback, - gpointer callback_user_data, - NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, - gpointer notify_tty_hangup_user_data, - GError **error) +nm_bluez5_dun_connect(const char * adapter, + const char * remote, + GCancellable * cancellable, + NMBluez5DunConnectCb callback, + gpointer callback_user_data, + NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, + gpointer notify_tty_hangup_user_data, + GError ** error) { - nm_auto_free_context NMBluez5DunContext *context = NULL; - ConnectData *cdat; - gsize src_l; - gsize dst_l; - - g_return_val_if_fail (adapter, FALSE); - g_return_val_if_fail (remote, FALSE); - g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (callback, FALSE); - g_return_val_if_fail (notify_tty_hangup_cb, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - nm_assert (!g_cancellable_is_cancelled (cancellable)); - - src_l = strlen (adapter) + 1; - dst_l = strlen (remote) + 1; - - cdat = g_slice_new (ConnectData); - *cdat = (ConnectData) { - .callback = callback, - .callback_user_data = callback_user_data, - .cancellable = g_object_ref (cancellable), - .sdp_session_try_count = 5, - }; - - context = g_malloc (sizeof (NMBluez5DunContext) + src_l + dst_l); - *context = (NMBluez5DunContext) { - .cdat = cdat, - .notify_tty_hangup_cb = notify_tty_hangup_cb, - .notify_tty_hangup_user_data = notify_tty_hangup_user_data, - .rfcomm_tty_no = -1, - .rfcomm_sock_fd = -1, - .rfcomm_tty_fd = -1, - .rfcomm_channel = -1, - }; - memcpy (&context->src_str[0], adapter, src_l); - context->dst_str = &context->src_str[src_l]; - memcpy ((char *) context->dst_str, remote, dst_l); - - if (str2ba (adapter, &context->src) < 0) { - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "invalid source"); - return FALSE; - } - - if (str2ba (remote, &context->dst) < 0) { - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "invalid remote"); - return FALSE; - } - - context->cdat->cancelled_id = g_signal_connect (context->cdat->cancellable, - "cancelled", - G_CALLBACK (_connect_cancelled_cb), - context); - - if (!_connect_sdp_session_start (context, error)) - return FALSE; - - _LOGD (context, "starting channel number discovery for device %s", - context->dst_str); - - g_steal_pointer (&context); - return TRUE; + nm_auto_free_context NMBluez5DunContext *context = NULL; + ConnectData * cdat; + gsize src_l; + gsize dst_l; + + g_return_val_if_fail(adapter, FALSE); + g_return_val_if_fail(remote, FALSE); + g_return_val_if_fail(G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(callback, FALSE); + g_return_val_if_fail(notify_tty_hangup_cb, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + nm_assert(!g_cancellable_is_cancelled(cancellable)); + + src_l = strlen(adapter) + 1; + dst_l = strlen(remote) + 1; + + cdat = g_slice_new(ConnectData); + *cdat = (ConnectData){ + .callback = callback, + .callback_user_data = callback_user_data, + .cancellable = g_object_ref(cancellable), + .sdp_session_try_count = 5, + }; + + context = g_malloc(sizeof(NMBluez5DunContext) + src_l + dst_l); + *context = (NMBluez5DunContext){ + .cdat = cdat, + .notify_tty_hangup_cb = notify_tty_hangup_cb, + .notify_tty_hangup_user_data = notify_tty_hangup_user_data, + .rfcomm_tty_no = -1, + .rfcomm_sock_fd = -1, + .rfcomm_tty_fd = -1, + .rfcomm_channel = -1, + }; + memcpy(&context->src_str[0], adapter, src_l); + context->dst_str = &context->src_str[src_l]; + memcpy((char *) context->dst_str, remote, dst_l); + + if (str2ba(adapter, &context->src) < 0) { + g_set_error(error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, "invalid source"); + return FALSE; + } + + if (str2ba(remote, &context->dst) < 0) { + g_set_error(error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, "invalid remote"); + return FALSE; + } + + context->cdat->cancelled_id = g_signal_connect(context->cdat->cancellable, + "cancelled", + G_CALLBACK(_connect_cancelled_cb), + context); + + if (!_connect_sdp_session_start(context, error)) + return FALSE; + + _LOGD(context, "starting channel number discovery for device %s", context->dst_str); + + g_steal_pointer(&context); + return TRUE; } /*****************************************************************************/ void -nm_bluez5_dun_disconnect (NMBluez5DunContext *context) +nm_bluez5_dun_disconnect(NMBluez5DunContext *context) { - nm_assert (context); - nm_assert (!context->cdat); + nm_assert(context); + nm_assert(!context->cdat); - _LOGD (context, "disconnecting DUN connection"); + _LOGD(context, "disconnecting DUN connection"); - _context_free (context); + _context_free(context); } /*****************************************************************************/ static void -_context_cleanup_connect_data (NMBluez5DunContext *context) +_context_cleanup_connect_data(NMBluez5DunContext *context) { - ConnectData *cdat; + ConnectData *cdat; - cdat = g_steal_pointer (&context->cdat); - if (!cdat) - return; + cdat = g_steal_pointer(&context->cdat); + if (!cdat) + return; - nm_clear_g_signal_handler (cdat->cancellable, &cdat->cancelled_id); + nm_clear_g_signal_handler(cdat->cancellable, &cdat->cancelled_id); - nm_clear_g_source_inst (&cdat->source); + nm_clear_g_source_inst(&cdat->source); - nm_clear_pointer (&cdat->sdp_session, sdp_close); + nm_clear_pointer(&cdat->sdp_session, sdp_close); - g_clear_object (&cdat->cancellable); + g_clear_object(&cdat->cancellable); - g_clear_error (&cdat->rfcomm_sdp_search_error); + g_clear_error(&cdat->rfcomm_sdp_search_error); - nm_g_slice_free (cdat); + nm_g_slice_free(cdat); } static void -_context_invoke_callback (NMBluez5DunContext *context, - GError *error) +_context_invoke_callback(NMBluez5DunContext *context, GError *error) { - NMBluez5DunConnectCb callback; - gpointer callback_user_data; - - nm_assert (context); - nm_assert (context->cdat); - nm_assert (context->cdat->callback); - nm_assert (error || context->rfcomm_tty_path); - - if (!error) - _LOGD (context, "connected via \"%s\"", context->rfcomm_tty_path); - else if (nm_utils_error_is_cancelled (error)) - _LOGD (context, "cancelled"); - else - _LOGD (context, "failed to connect: %s", error->message); - - callback = context->cdat->callback; - callback_user_data = context->cdat->callback_user_data; - - _context_cleanup_connect_data (context); - - callback (error ? NULL : context, - error ? NULL : context->rfcomm_tty_path, - error, - callback_user_data); + NMBluez5DunConnectCb callback; + gpointer callback_user_data; + + nm_assert(context); + nm_assert(context->cdat); + nm_assert(context->cdat->callback); + nm_assert(error || context->rfcomm_tty_path); + + if (!error) + _LOGD(context, "connected via \"%s\"", context->rfcomm_tty_path); + else if (nm_utils_error_is_cancelled(error)) + _LOGD(context, "cancelled"); + else + _LOGD(context, "failed to connect: %s", error->message); + + callback = context->cdat->callback; + callback_user_data = context->cdat->callback_user_data; + + _context_cleanup_connect_data(context); + + callback(error ? NULL : context, + error ? NULL : context->rfcomm_tty_path, + error, + callback_user_data); } static void -_context_invoke_callback_success (NMBluez5DunContext *context) +_context_invoke_callback_success(NMBluez5DunContext *context) { - nm_assert (context->rfcomm_tty_path); - _context_invoke_callback (context, NULL); + nm_assert(context->rfcomm_tty_path); + _context_invoke_callback(context, NULL); } static void -_context_invoke_callback_fail_and_free (NMBluez5DunContext *context, - GError *error) +_context_invoke_callback_fail_and_free(NMBluez5DunContext *context, GError *error) { - nm_assert (error); - _context_invoke_callback (context, error); - _context_free (context); + nm_assert(error); + _context_invoke_callback(context, error); + _context_free(context); } static void -_context_free (NMBluez5DunContext *context) +_context_free(NMBluez5DunContext *context) { - nm_assert (context); + nm_assert(context); - _context_cleanup_connect_data (context); + _context_cleanup_connect_data(context); - nm_clear_g_source_inst (&context->rfcomm_tty_poll_source); + nm_clear_g_source_inst(&context->rfcomm_tty_poll_source); - if (context->rfcomm_sock_fd >= 0) { - if (context->rfcomm_tty_no >= 0) { - struct rfcomm_dev_req req; + if (context->rfcomm_sock_fd >= 0) { + if (context->rfcomm_tty_no >= 0) { + struct rfcomm_dev_req req; - memset (&req, 0, sizeof (struct rfcomm_dev_req)); - req.dev_id = context->rfcomm_tty_no; - context->rfcomm_tty_no = -1; - (void) ioctl (context->rfcomm_sock_fd, RFCOMMRELEASEDEV, &req); - } - nm_close (nm_steal_fd (&context->rfcomm_sock_fd)); - } + memset(&req, 0, sizeof(struct rfcomm_dev_req)); + req.dev_id = context->rfcomm_tty_no; + context->rfcomm_tty_no = -1; + (void) ioctl(context->rfcomm_sock_fd, RFCOMMRELEASEDEV, &req); + } + nm_close(nm_steal_fd(&context->rfcomm_sock_fd)); + } - if (context->rfcomm_tty_fd >= 0) - nm_close (nm_steal_fd (&context->rfcomm_tty_fd)); - nm_clear_g_free (&context->rfcomm_tty_path); - g_free (context); + if (context->rfcomm_tty_fd >= 0) + nm_close(nm_steal_fd(&context->rfcomm_tty_fd)); + nm_clear_g_free(&context->rfcomm_tty_path); + g_free(context); } diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h index b3f22965..94fa5550 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.h +++ b/src/devices/bluetooth/nm-bluez5-dun.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -10,29 +10,28 @@ typedef struct _NMBluez5DunContext NMBluez5DunContext; #if WITH_BLUEZ5_DUN -typedef void (*NMBluez5DunConnectCb) (NMBluez5DunContext *context, - const char *rfcomm_dev, - GError *error, - gpointer user_data); +typedef void (*NMBluez5DunConnectCb)(NMBluez5DunContext *context, + const char * rfcomm_dev, + GError * error, + gpointer user_data); -typedef void (*NMBluez5DunNotifyTtyHangupCb) (NMBluez5DunContext *context, - gpointer user_data); +typedef void (*NMBluez5DunNotifyTtyHangupCb)(NMBluez5DunContext *context, gpointer user_data); -gboolean nm_bluez5_dun_connect (const char *adapter, - const char *remote, - GCancellable *cancellable, - NMBluez5DunConnectCb callback, - gpointer callback_user_data, - NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, - gpointer notify_tty_hangup_user_data, - GError **error); +gboolean nm_bluez5_dun_connect(const char * adapter, + const char * remote, + GCancellable * cancellable, + NMBluez5DunConnectCb callback, + gpointer callback_user_data, + NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, + gpointer notify_tty_hangup_user_data, + GError ** error); -void nm_bluez5_dun_disconnect (NMBluez5DunContext *context); +void nm_bluez5_dun_disconnect(NMBluez5DunContext *context); -const char *nm_bluez5_dun_context_get_adapter (const NMBluez5DunContext *context); -const char *nm_bluez5_dun_context_get_remote (const NMBluez5DunContext *context); -const char *nm_bluez5_dun_context_get_rfcomm_dev (const NMBluez5DunContext *context); +const char *nm_bluez5_dun_context_get_adapter(const NMBluez5DunContext *context); +const char *nm_bluez5_dun_context_get_remote(const NMBluez5DunContext *context); +const char *nm_bluez5_dun_context_get_rfcomm_dev(const NMBluez5DunContext *context); #endif /* WITH_BLUEZ5_DUN */ -#endif /* __NM_BLUEZ5_DUN_H__ */ +#endif /* __NM_BLUEZ5_DUN_H__ */ diff --git a/src/devices/bluetooth/nm-bt-error.c b/src/devices/bluetooth/nm-bt-error.c index 8aa4283d..8f5265f8 100644 --- a/src/devices/bluetooth/nm-bt-error.c +++ b/src/devices/bluetooth/nm-bt-error.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -7,5 +7,4 @@ #include "nm-bt-error.h" -NM_CACHED_QUARK_FCN ("nm-bt-error", nm_bt_error_quark) - +NM_CACHED_QUARK_FCN("nm-bt-error", nm_bt_error_quark); diff --git a/src/devices/bluetooth/nm-bt-error.h b/src/devices/bluetooth/nm-bt-error.h index 258fca8d..766d2d39 100644 --- a/src/devices/bluetooth/nm-bt-error.h +++ b/src/devices/bluetooth/nm-bt-error.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -7,14 +7,13 @@ #define _NM_BLUEZ5_ERROR_H_ typedef enum { - NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ - NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_BT_ERROR_DUN_CONNECT_FAILED, /*< nick=DunConnectFailed >*/ + NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ + NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_BT_ERROR_DUN_CONNECT_FAILED, /*< nick=DunConnectFailed >*/ } NMBtError; -#define NM_BT_ERROR (nm_bt_error_quark ()) -GQuark nm_bt_error_quark (void); - -#endif /* _NM_BT_ERROR_H_ */ +#define NM_BT_ERROR (nm_bt_error_quark()) +GQuark nm_bt_error_quark(void); +#endif /* _NM_BT_ERROR_H_ */ diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index a02ce34f..c31961df 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2011 Red Hat, Inc. */ @@ -35,1361 +35,1377 @@ _LOG_DECLARE_SELF(NMDeviceBt); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceBt, - PROP_BT_BDADDR, - PROP_BT_BZ_MGR, - PROP_BT_CAPABILITIES, - PROP_BT_DBUS_PATH, - PROP_BT_NAME, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceBt, + PROP_BT_BDADDR, + PROP_BT_BZ_MGR, + PROP_BT_CAPABILITIES, + PROP_BT_DBUS_PATH, + PROP_BT_NAME, ); enum { - PPP_STATS, - LAST_SIGNAL, + PPP_STATS, + LAST_SIGNAL, }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - NMModemManager *modem_manager; + NMModemManager *modem_manager; - NMBluezManager *bz_mgr; + NMBluezManager *bz_mgr; - char *dbus_path; + char *dbus_path; - char *bdaddr; - char *name; + char *bdaddr; + char *name; - char *connect_rfcomm_iface; + char *connect_rfcomm_iface; - GSList *connect_modem_candidates; + GSList *connect_modem_candidates; - NMModem *modem; + NMModem *modem; - GCancellable *connect_bz_cancellable; + GCancellable *connect_bz_cancellable; - gulong connect_watch_link_id; + gulong connect_watch_link_id; - guint connect_watch_link_idle_id; + guint connect_watch_link_idle_id; - guint connect_wait_modem_id; + guint connect_wait_modem_id; - NMBluetoothCapabilities capabilities:6; + NMBluetoothCapabilities capabilities : 6; - NMBluetoothCapabilities connect_bt_type:6; /* BT type of the current connection */ + NMBluetoothCapabilities connect_bt_type : 6; /* BT type of the current connection */ - NMDeviceStageState stage1_bt_state:3; - NMDeviceStageState stage1_modem_prepare_state:3; + NMDeviceStageState stage1_bt_state : 3; + NMDeviceStageState stage1_modem_prepare_state : 3; - bool is_connected:1; + bool is_connected : 1; - bool mm_running:1; + bool mm_running : 1; } NMDeviceBtPrivate; struct _NMDeviceBt { - NMDevice parent; - NMDeviceBtPrivate _priv; + NMDevice parent; + NMDeviceBtPrivate _priv; }; struct _NMDeviceBtClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) -#define NM_DEVICE_BT_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceBt, NM_IS_DEVICE_BT, NMDevice) +#define NM_DEVICE_BT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceBt, NM_IS_DEVICE_BT, NMDevice) /*****************************************************************************/ -NMBluetoothCapabilities nm_device_bt_get_capabilities (NMDeviceBt *self) +NMBluetoothCapabilities +nm_device_bt_get_capabilities(NMDeviceBt *self) { - g_return_val_if_fail (NM_IS_DEVICE_BT (self), NM_BT_CAPABILITY_NONE); + g_return_val_if_fail(NM_IS_DEVICE_BT(self), NM_BT_CAPABILITY_NONE); - return NM_DEVICE_BT_GET_PRIVATE (self)->capabilities; + return NM_DEVICE_BT_GET_PRIVATE(self)->capabilities; } static NMBluetoothCapabilities -get_connection_bt_type (NMConnection *connection) +get_connection_bt_type(NMConnection *connection) { - NMSettingBluetooth *s_bt; - const char *bt_type; - - s_bt = nm_connection_get_setting_bluetooth (connection); - - if (s_bt) { - bt_type = nm_setting_bluetooth_get_connection_type (s_bt); - if (bt_type) { - if (nm_streq (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) - return NM_BT_CAPABILITY_DUN; - else if (nm_streq (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) - return NM_BT_CAPABILITY_NAP; - } - } - - return NM_BT_CAPABILITY_NONE; + NMSettingBluetooth *s_bt; + const char * bt_type; + + s_bt = nm_connection_get_setting_bluetooth(connection); + + if (s_bt) { + bt_type = nm_setting_bluetooth_get_connection_type(s_bt); + if (bt_type) { + if (nm_streq(bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) + return NM_BT_CAPABILITY_DUN; + else if (nm_streq(bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) + return NM_BT_CAPABILITY_NAP; + } + } + + return NM_BT_CAPABILITY_NONE; } static gboolean -get_connection_bt_type_check (NMDeviceBt *self, - NMConnection *connection, - NMBluetoothCapabilities *out_bt_type, - GError **error) +get_connection_bt_type_check(NMDeviceBt * self, + NMConnection * connection, + NMBluetoothCapabilities *out_bt_type, + GError ** error) { - NMBluetoothCapabilities bt_type; + NMBluetoothCapabilities bt_type; - bt_type = get_connection_bt_type (connection); + bt_type = get_connection_bt_type(connection); - NM_SET_OUT (out_bt_type, bt_type); + NM_SET_OUT(out_bt_type, bt_type); - if (bt_type == NM_BT_CAPABILITY_NONE) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "profile is not a PANU/DUN bluetooth type"); - return FALSE; - } + if (bt_type == NM_BT_CAPABILITY_NONE) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "profile is not a PANU/DUN bluetooth type"); + return FALSE; + } - if (!NM_FLAGS_ALL (NM_DEVICE_BT_GET_PRIVATE (self)->capabilities, bt_type)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not support bluetooth type"); - return FALSE; - } + if (!NM_FLAGS_ALL(NM_DEVICE_BT_GET_PRIVATE(self)->capabilities, bt_type)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not support bluetooth type"); + return FALSE; + } - return TRUE; + return TRUE; } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_NON_KERNEL; + return NM_DEVICE_CAP_IS_NON_KERNEL; } static gboolean -can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, - char **specific_object) +can_auto_connect(NMDevice *device, NMSettingsConnection *sett_conn, char **specific_object) { - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - NMBluetoothCapabilities bt_type; + NMDeviceBt * self = NM_DEVICE_BT(device); + NMDeviceBtPrivate * priv = NM_DEVICE_BT_GET_PRIVATE(self); + NMBluetoothCapabilities bt_type; - nm_assert (!specific_object || !*specific_object); + nm_assert(!specific_object || !*specific_object); - if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->can_auto_connect (device, sett_conn, NULL)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_bt_parent_class)->can_auto_connect(device, sett_conn, NULL)) + return FALSE; - if (!get_connection_bt_type_check (self, - nm_settings_connection_get_connection (sett_conn), - &bt_type, - NULL)) - return FALSE; + if (!get_connection_bt_type_check(self, + nm_settings_connection_get_connection(sett_conn), + &bt_type, + NULL)) + return FALSE; - /* Can't auto-activate a DUN connection without ModemManager */ - if ( bt_type == NM_BT_CAPABILITY_DUN - && priv->mm_running == FALSE) - return FALSE; + /* Can't auto-activate a DUN connection without ModemManager */ + if (bt_type == NM_BT_CAPABILITY_DUN && priv->mm_running == FALSE) + return FALSE; - return TRUE; + return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - NMSettingBluetooth *s_bt; - const char *bdaddr; - - if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (!get_connection_bt_type_check (self, connection, NULL, error)) - return FALSE; - - s_bt = nm_connection_get_setting_bluetooth (connection); - - bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "profile lacks bdaddr setting"); - return FALSE; - } - if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "devices bdaddr setting mismatches"); - return FALSE; - } - - return TRUE; + NMDeviceBt * self = NM_DEVICE_BT(device); + NMDeviceBtPrivate * priv = NM_DEVICE_BT_GET_PRIVATE(self); + NMSettingBluetooth *s_bt; + const char * bdaddr; + + if (!NM_DEVICE_CLASS(nm_device_bt_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (!get_connection_bt_type_check(self, connection, NULL, error)) + return FALSE; + + s_bt = nm_connection_get_setting_bluetooth(connection); + + bdaddr = nm_setting_bluetooth_get_bdaddr(s_bt); + if (!bdaddr) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "profile lacks bdaddr setting"); + return FALSE; + } + if (!nm_utils_hwaddr_matches(priv->bdaddr, -1, bdaddr, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "devices bdaddr setting mismatches"); + return FALSE; + } + + return TRUE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) { - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - NMBluetoothCapabilities bt_type; + NMDeviceBt * self = NM_DEVICE_BT(device); + NMDeviceBtPrivate * priv = NM_DEVICE_BT_GET_PRIVATE(self); + NMBluetoothCapabilities bt_type; - if (!get_connection_bt_type_check (self, connection, &bt_type, error)) - return FALSE; + if (!get_connection_bt_type_check(self, connection, &bt_type, error)) + return FALSE; - if ( bt_type == NM_BT_CAPABILITY_DUN - && !priv->mm_running) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "ModemManager missing for DUN profile"); - return FALSE; - } + if (bt_type == NM_BT_CAPABILITY_DUN && !priv->mm_running) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "ModemManager missing for DUN profile"); + return FALSE; + } - return TRUE; + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); - NMSettingBluetooth *s_bt; - const char *setting_bdaddr; - const char *ctype; - gboolean is_dun = FALSE; - gboolean is_pan = FALSE; - NMSettingGsm *s_gsm; - NMSettingCdma *s_cdma; - NMSettingSerial *s_serial; - NMSettingPpp *s_ppp; - const char *fallback_prefix = NULL, *preferred = NULL; - - s_gsm = nm_connection_get_setting_gsm (connection); - s_cdma = nm_connection_get_setting_cdma (connection); - s_serial = nm_connection_get_setting_serial (connection); - s_ppp = nm_connection_get_setting_ppp (connection); - - s_bt = nm_connection_get_setting_bluetooth (connection); - if (!s_bt) { - s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bt)); - } - - ctype = nm_setting_bluetooth_get_connection_type (s_bt); - if (ctype) { - if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_DUN)) - is_dun = TRUE; - else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_PANU)) - is_pan = TRUE; - } else { - if (s_gsm || s_cdma) - is_dun = TRUE; - else if (priv->capabilities & NM_BT_CAPABILITY_NAP) - is_pan = TRUE; - } - - if (is_pan) { - /* Make sure the device supports PAN */ - if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("PAN requested, but Bluetooth device does not support NAP")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); - return FALSE; - } - - /* PAN can't use any DUN-related settings */ - if ( s_gsm - || s_cdma - || s_serial - || s_ppp) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("PAN connections cannot specify GSM, CDMA, or serial settings")); - g_prefix_error (error, "%s: ", - s_gsm ? NM_SETTING_GSM_SETTING_NAME : - s_cdma ? NM_SETTING_CDMA_SETTING_NAME : - s_serial ? NM_SETTING_SERIAL_SETTING_NAME : - NM_SETTING_PPP_SETTING_NAME); - return FALSE; - } - - g_object_set (G_OBJECT (s_bt), - NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, - NULL); - - fallback_prefix = _("PAN connection"); - } else if (is_dun) { - /* Make sure the device supports PAN */ - if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("DUN requested, but Bluetooth device does not support DUN")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); - return FALSE; - } - - /* Need at least a GSM or a CDMA setting */ - if ( !s_gsm - && !s_cdma) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("DUN connection must include a GSM or CDMA setting")); - g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); - return FALSE; - } - - g_object_set (G_OBJECT (s_bt), - NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN, - NULL); - - if (s_gsm) { - fallback_prefix = _("GSM connection"); - } else { - fallback_prefix = _("CDMA connection"); - if (!nm_setting_cdma_get_number (s_cdma)) - g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); - } - } else { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Unknown/unhandled Bluetooth connection type")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); - return FALSE; - } - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_BLUETOOTH_SETTING_NAME, - existing_connections, - preferred, - fallback_prefix, - NULL, - NULL, - is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */ - - setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (setting_bdaddr) { - /* Make sure the setting BT Address (if any) matches the device's */ - if (!nm_utils_hwaddr_matches (setting_bdaddr, -1, priv->bdaddr, -1)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("connection does not match device")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); - return FALSE; - } - } else { - /* Lock the connection to this device by default */ - if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, NULL, ETH_ALEN)) - g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, priv->bdaddr, NULL); - } - - return TRUE; + NMDeviceBtPrivate * priv = NM_DEVICE_BT_GET_PRIVATE(device); + NMSettingBluetooth *s_bt; + const char * setting_bdaddr; + const char * ctype; + gboolean is_dun = FALSE; + gboolean is_pan = FALSE; + NMSettingGsm * s_gsm; + NMSettingCdma * s_cdma; + NMSettingSerial * s_serial; + NMSettingPpp * s_ppp; + const char * fallback_prefix = NULL, *preferred = NULL; + + s_gsm = nm_connection_get_setting_gsm(connection); + s_cdma = nm_connection_get_setting_cdma(connection); + s_serial = nm_connection_get_setting_serial(connection); + s_ppp = nm_connection_get_setting_ppp(connection); + + s_bt = nm_connection_get_setting_bluetooth(connection); + if (!s_bt) { + s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bt)); + } + + ctype = nm_setting_bluetooth_get_connection_type(s_bt); + if (ctype) { + if (!strcmp(ctype, NM_SETTING_BLUETOOTH_TYPE_DUN)) + is_dun = TRUE; + else if (!strcmp(ctype, NM_SETTING_BLUETOOTH_TYPE_PANU)) + is_pan = TRUE; + } else { + if (s_gsm || s_cdma) + is_dun = TRUE; + else if (priv->capabilities & NM_BT_CAPABILITY_NAP) + is_pan = TRUE; + } + + if (is_pan) { + /* Make sure the device supports PAN */ + if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("PAN requested, but Bluetooth device does not support NAP")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + + /* PAN can't use any DUN-related settings */ + if (s_gsm || s_cdma || s_serial || s_ppp) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("PAN connections cannot specify GSM, CDMA, or serial settings")); + g_prefix_error(error, + "%s: ", + s_gsm ? NM_SETTING_GSM_SETTING_NAME + : s_cdma ? NM_SETTING_CDMA_SETTING_NAME + : s_serial ? NM_SETTING_SERIAL_SETTING_NAME + : NM_SETTING_PPP_SETTING_NAME); + return FALSE; + } + + g_object_set(G_OBJECT(s_bt), + NM_SETTING_BLUETOOTH_TYPE, + NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + + fallback_prefix = _("PAN connection"); + } else if (is_dun) { + /* Make sure the device supports PAN */ + if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("DUN requested, but Bluetooth device does not support DUN")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + + /* Need at least a GSM or a CDMA setting */ + if (!s_gsm && !s_cdma) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("DUN connection must include a GSM or CDMA setting")); + g_prefix_error(error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); + return FALSE; + } + + g_object_set(G_OBJECT(s_bt), + NM_SETTING_BLUETOOTH_TYPE, + NM_SETTING_BLUETOOTH_TYPE_DUN, + NULL); + + if (s_gsm) { + fallback_prefix = _("GSM connection"); + } else { + fallback_prefix = _("CDMA connection"); + if (!nm_setting_cdma_get_number(s_cdma)) + g_object_set(G_OBJECT(s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); + } + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown/unhandled Bluetooth connection type")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_BLUETOOTH_SETTING_NAME, + existing_connections, + preferred, + fallback_prefix, + NULL, + NULL, + is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */ + + setting_bdaddr = nm_setting_bluetooth_get_bdaddr(s_bt); + if (setting_bdaddr) { + /* Make sure the setting BT Address (if any) matches the device's */ + if (!nm_utils_hwaddr_matches(setting_bdaddr, -1, priv->bdaddr, -1)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_BLUETOOTH_SETTING_NAME, + NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + } else { + /* Lock the connection to this device by default */ + if (!nm_utils_hwaddr_matches(priv->bdaddr, -1, NULL, ETH_ALEN)) + g_object_set(G_OBJECT(s_bt), NM_SETTING_BLUETOOTH_BDADDR, priv->bdaddr, NULL); + } + + return TRUE; } /*****************************************************************************/ /* IP method PPP */ static void -ppp_stats (NMModem *modem, - guint i_in_bytes, - guint i_out_bytes, - gpointer user_data) +ppp_stats(NMModem *modem, guint i_in_bytes, guint i_out_bytes, gpointer user_data) { - guint32 in_bytes = i_in_bytes; - guint32 out_bytes = i_out_bytes; - - g_signal_emit (NM_DEVICE_BT (user_data), signals[PPP_STATS], 0, (guint) in_bytes, (guint) out_bytes); + guint32 in_bytes = i_in_bytes; + guint32 out_bytes = i_out_bytes; + + g_signal_emit(NM_DEVICE_BT(user_data), + signals[PPP_STATS], + 0, + (guint) in_bytes, + (guint) out_bytes); } static void -ppp_failed (NMModem *modem, - guint i_reason, - gpointer user_data) +ppp_failed(NMModem *modem, guint i_reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMDeviceStateReason reason = i_reason; - - switch (nm_device_get_state (device)) { - case NM_DEVICE_STATE_PREPARE: - case NM_DEVICE_STATE_CONFIG: - case NM_DEVICE_STATE_NEED_AUTH: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - break; - case NM_DEVICE_STATE_IP_CONFIG: - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_ACTIVATED: - if (nm_device_activate_ip4_state_in_conf (device)) - nm_device_activate_schedule_ip_config_timeout (device, AF_INET); - else if (nm_device_activate_ip6_state_in_conf (device)) - nm_device_activate_schedule_ip_config_timeout (device, AF_INET6); - else if (nm_device_activate_ip4_state_done (device)) { - nm_device_ip_method_failed (device, - AF_INET, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else if (nm_device_activate_ip6_state_done (device)) { - nm_device_ip_method_failed (device, - AF_INET6, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else { - _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device)); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } - break; - default: - break; - } + NMDevice * device = NM_DEVICE(user_data); + NMDeviceBt * self = NM_DEVICE_BT(user_data); + NMDeviceStateReason reason = i_reason; + + switch (nm_device_get_state(device)) { + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, reason); + break; + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + if (nm_device_activate_ip4_state_in_conf(device)) + nm_device_activate_schedule_ip_config_timeout(device, AF_INET); + else if (nm_device_activate_ip6_state_in_conf(device)) + nm_device_activate_schedule_ip_config_timeout(device, AF_INET6); + else if (nm_device_activate_ip4_state_done(device)) { + nm_device_ip_method_failed(device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else if (nm_device_activate_ip6_state_done(device)) { + nm_device_ip_method_failed(device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW(LOGD_MB, + "PPP failure in unexpected state %u", + (guint) nm_device_get_state(device)); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + break; + default: + break; + } } static void -modem_auth_requested (NMModem *modem, gpointer user_data) +modem_auth_requested(NMModem *modem, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled - * during activation. - */ - if (!nm_device_is_activating (device)) - return; + /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled + * during activation. + */ + if (!nm_device_is_activating(device)) + return; - nm_device_state_changed (device, - NM_DEVICE_STATE_NEED_AUTH, - NM_DEVICE_STATE_REASON_NONE); + nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); } static void -modem_auth_result (NMModem *modem, GError *error, gpointer user_data) +modem_auth_result(NMModem *modem, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_NEED_AUTH); - if (error) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } + if (error) { + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } - priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_INIT; - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_INIT; + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -modem_prepare_result (NMModem *modem, - gboolean success, - guint i_reason, - gpointer user_data) +modem_prepare_result(NMModem *modem, gboolean success, guint i_reason, gpointer user_data) { - NMDeviceBt *self = user_data; - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - NMDeviceStateReason reason = i_reason; - NMDeviceState state; + NMDeviceBt * self = user_data; + NMDeviceBtPrivate * priv = NM_DEVICE_BT_GET_PRIVATE(self); + NMDeviceStateReason reason = i_reason; + NMDeviceState state; - state = nm_device_get_state (NM_DEVICE (self)); + state = nm_device_get_state(NM_DEVICE(self)); - g_return_if_fail (NM_IN_SET (state, NM_DEVICE_STATE_PREPARE, - NM_DEVICE_STATE_NEED_AUTH)); + g_return_if_fail(NM_IN_SET(state, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_NEED_AUTH)); - nm_assert (priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_PENDING); + nm_assert(priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_PENDING); - if (!success) { - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT) { - /* If the connect failed because the SIM PIN was wrong don't allow - * the device to be auto-activated anymore, which would risk locking - * the SIM if the incorrect PIN continues to be used. - */ - nm_device_autoconnect_blocked_set (NM_DEVICE (self), NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN); - } + if (!success) { + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT) { + /* If the connect failed because the SIM PIN was wrong don't allow + * the device to be auto-activated anymore, which would risk locking + * the SIM if the incorrect PIN continues to be used. + */ + nm_device_autoconnect_blocked_set(NM_DEVICE(self), + NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN); + } - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason); - return; - } + nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason); + return; + } - priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_COMPLETED; - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); + priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); - - if (priv->modem) - nm_modem_device_state_changed (priv->modem, new_state, old_state); - - /* Need to recheck available connections whenever MM appears or disappears, - * since the device could be both DUN and NAP capable and thus may not - * change state (which rechecks available connections) when MM comes and goes. - */ - if ( priv->mm_running - && NM_FLAGS_HAS (priv->capabilities, NM_BT_CAPABILITY_DUN)) - nm_device_recheck_available_connections (device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + + if (priv->modem) + nm_modem_device_state_changed(priv->modem, new_state, old_state); + + /* Need to recheck available connections whenever MM appears or disappears, + * since the device could be both DUN and NAP capable and thus may not + * change state (which rechecks available connections) when MM comes and goes. + */ + if (priv->mm_running && NM_FLAGS_HAS(priv->capabilities, NM_BT_CAPABILITY_DUN)) + nm_device_recheck_available_connections(device); } static void -modem_ip4_config_result (NMModem *modem, - NMIP4Config *config, - GError *error, - gpointer user_data) +modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMDevice *device = NM_DEVICE (self); - - g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); - - if (error) { - _LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT, - "retrieving IP4 configuration failed: %s", - error->message); - nm_device_ip_method_failed (device, - AF_INET, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return; - } - - nm_device_activate_schedule_ip_config_result (device, AF_INET, NM_IP_CONFIG_CAST (config)); + NMDeviceBt *self = NM_DEVICE_BT(user_data); + NMDevice * device = NM_DEVICE(self); + + g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE); + + if (error) { + _LOGW(LOGD_MB | LOGD_IP4 | LOGD_BT, + "retrieving IP4 configuration failed: %s", + error->message); + nm_device_ip_method_failed(device, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config)); } static void -ip_ifindex_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) +ip_ifindex_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - if (!nm_device_is_activating (device)) - return; + if (!nm_device_is_activating(device)) + return; - if (!nm_device_set_ip_ifindex (device, - nm_modem_get_ip_ifindex (modem))) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } + if (!nm_device_set_ip_ifindex(device, nm_modem_get_ip_ifindex(modem))) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } } /*****************************************************************************/ static void -modem_cleanup (NMDeviceBt *self) +modem_cleanup(NMDeviceBt *self) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - - if (priv->modem) { - g_signal_handlers_disconnect_matched (priv->modem, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); - nm_clear_pointer (&priv->modem, nm_modem_unclaim); - } + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); + + if (priv->modem) { + g_signal_handlers_disconnect_matched(priv->modem, + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + self); + nm_clear_pointer(&priv->modem, nm_modem_unclaim); + } } static void -modem_state_cb (NMModem *modem, - int new_state_i, - int old_state_i, - gpointer user_data) +modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_data) { - NMModemState new_state = new_state_i; - NMModemState old_state = old_state_i; - NMDevice *device = NM_DEVICE (user_data); - NMDeviceState dev_state = nm_device_get_state (device); - - if ( new_state <= NM_MODEM_STATE_DISABLING - && old_state > NM_MODEM_STATE_DISABLING) { - /* Will be called whenever something external to NM disables the - * modem directly through ModemManager. - */ - if ( nm_device_is_activating (device) - || dev_state == NM_DEVICE_STATE_ACTIVATED) { - nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - return; - } - } - - if ( new_state < NM_MODEM_STATE_CONNECTING - && old_state >= NM_MODEM_STATE_CONNECTING - && dev_state >= NM_DEVICE_STATE_NEED_AUTH - && dev_state <= NM_DEVICE_STATE_ACTIVATED) { - /* Fail the device if the modem disconnects unexpectedly while the - * device is activating/activated. */ - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return; - } + NMModemState new_state = new_state_i; + NMModemState old_state = old_state_i; + NMDevice * device = NM_DEVICE(user_data); + NMDeviceState dev_state = nm_device_get_state(device); + + if (new_state <= NM_MODEM_STATE_DISABLING && old_state > NM_MODEM_STATE_DISABLING) { + /* Will be called whenever something external to NM disables the + * modem directly through ModemManager. + */ + if (nm_device_is_activating(device) || dev_state == NM_DEVICE_STATE_ACTIVATED) { + nm_device_state_changed(device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + return; + } + } + + if (new_state < NM_MODEM_STATE_CONNECTING && old_state >= NM_MODEM_STATE_CONNECTING + && dev_state >= NM_DEVICE_STATE_NEED_AUTH && dev_state <= NM_DEVICE_STATE_ACTIVATED) { + /* Fail the device if the modem disconnects unexpectedly while the + * device is activating/activated. */ + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return; + } } static void -modem_removed_cb (NMModem *modem, gpointer user_data) +modem_removed_cb(NMModem *modem, gpointer user_data) { - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMDeviceState state; - - state = nm_device_get_state (NM_DEVICE (self)); - if ( nm_device_is_activating (NM_DEVICE (self)) - || state == NM_DEVICE_STATE_ACTIVATED) { - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - return; - } - - modem_cleanup (self); + NMDeviceBt * self = NM_DEVICE_BT(user_data); + NMDeviceState state; + + state = nm_device_get_state(NM_DEVICE(self)); + if (nm_device_is_activating(NM_DEVICE(self)) || state == NM_DEVICE_STATE_ACTIVATED) { + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + return; + } + + modem_cleanup(self); } static gboolean -modem_try_claim (NMDeviceBt *self, - NMModem *modem) +modem_try_claim(NMDeviceBt *self, NMModem *modem) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - gs_free char *rfcomm_base_name = NULL; - NMDeviceState state; - - if (priv->modem) { - if (priv->modem == modem) - return TRUE; - return FALSE; - } - - if (nm_modem_is_claimed (modem)) - return FALSE; - - if (!priv->connect_rfcomm_iface) - return FALSE; - - rfcomm_base_name = g_path_get_basename (priv->connect_rfcomm_iface); - if (!nm_streq0 (rfcomm_base_name, nm_modem_get_control_port (modem))) - return FALSE; - - /* Can only accept the modem in stage1, but since the interface matched - * what we were expecting, don't let anything else claim the modem either. - */ - state = nm_device_get_state (NM_DEVICE (self)); - if (state != NM_DEVICE_STATE_PREPARE) { - _LOGD (LOGD_BT | LOGD_MB, - "modem found but device not in correct state (%d)", - nm_device_get_state (NM_DEVICE (self))); - return FALSE; - } - - priv->modem = nm_modem_claim (modem); - priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_INIT; - - g_signal_connect (modem, NM_MODEM_PPP_STATS, G_CALLBACK (ppp_stats), self); - g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); - g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); - g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); - g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); - g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); - g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); - g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_IP_IFINDEX, G_CALLBACK (ip_ifindex_changed_cb), self); - - _LOGD (LOGD_BT | LOGD_MB, - "modem found"); - - return TRUE; + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); + gs_free char * rfcomm_base_name = NULL; + NMDeviceState state; + + if (priv->modem) { + if (priv->modem == modem) + return TRUE; + return FALSE; + } + + if (nm_modem_is_claimed(modem)) + return FALSE; + + if (!priv->connect_rfcomm_iface) + return FALSE; + + rfcomm_base_name = g_path_get_basename(priv->connect_rfcomm_iface); + if (!nm_streq0(rfcomm_base_name, nm_modem_get_control_port(modem))) + return FALSE; + + /* Can only accept the modem in stage1, but since the interface matched + * what we were expecting, don't let anything else claim the modem either. + */ + state = nm_device_get_state(NM_DEVICE(self)); + if (state != NM_DEVICE_STATE_PREPARE) { + _LOGD(LOGD_BT | LOGD_MB, + "modem found but device not in correct state (%d)", + nm_device_get_state(NM_DEVICE(self))); + return FALSE; + } + + priv->modem = nm_modem_claim(modem); + priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_INIT; + + g_signal_connect(modem, NM_MODEM_PPP_STATS, G_CALLBACK(ppp_stats), self); + g_signal_connect(modem, NM_MODEM_PPP_FAILED, G_CALLBACK(ppp_failed), self); + g_signal_connect(modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK(modem_prepare_result), self); + g_signal_connect(modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK(modem_ip4_config_result), self); + g_signal_connect(modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK(modem_auth_requested), self); + g_signal_connect(modem, NM_MODEM_AUTH_RESULT, G_CALLBACK(modem_auth_result), self); + g_signal_connect(modem, NM_MODEM_STATE_CHANGED, G_CALLBACK(modem_state_cb), self); + g_signal_connect(modem, NM_MODEM_REMOVED, G_CALLBACK(modem_removed_cb), self); + g_signal_connect(modem, + "notify::" NM_MODEM_IP_IFINDEX, + G_CALLBACK(ip_ifindex_changed_cb), + self); + + _LOGD(LOGD_BT | LOGD_MB, "modem found"); + + return TRUE; } static void -mm_modem_added_cb (NMModemManager *manager, - NMModem *modem, - gpointer user_data) +mm_modem_added_cb(NMModemManager *manager, NMModem *modem, gpointer user_data) { - NMDeviceBt *self = user_data; - NMDeviceBtPrivate *priv; + NMDeviceBt * self = user_data; + NMDeviceBtPrivate *priv; - if (!modem_try_claim (user_data, modem)) - return; + if (!modem_try_claim(user_data, modem)) + return; - priv = NM_DEVICE_BT_GET_PRIVATE (self); + priv = NM_DEVICE_BT_GET_PRIVATE(self); - if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_COMPLETED) - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); + if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_COMPLETED) + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); } /*****************************************************************************/ void -_nm_device_bt_notify_set_connected (NMDeviceBt *self, - gboolean connected) +_nm_device_bt_notify_set_connected(NMDeviceBt *self, gboolean connected) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - connected = !!connected; - if (priv->is_connected == connected) - return; + connected = !!connected; + if (priv->is_connected == connected) + return; - priv->is_connected = connected; + priv->is_connected = connected; - if ( connected - || priv->stage1_bt_state != NM_DEVICE_STAGE_STATE_COMPLETED - || nm_device_get_state (NM_DEVICE (self)) > NM_DEVICE_STATE_ACTIVATED) { - _LOGT (LOGD_BT, "set-connected: %d", connected); - return; - } + if (connected || priv->stage1_bt_state != NM_DEVICE_STAGE_STATE_COMPLETED + || nm_device_get_state(NM_DEVICE(self)) > NM_DEVICE_STATE_ACTIVATED) { + _LOGT(LOGD_BT, "set-connected: %d", connected); + return; + } - _LOGT (LOGD_BT, "set-connected: %d (disconnecting device...)", connected); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_CARRIER); + _LOGT(LOGD_BT, "set-connected: %d (disconnecting device...)", connected); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CARRIER); } static gboolean -connect_watch_link_idle_cb (gpointer user_data) +connect_watch_link_idle_cb(gpointer user_data) { - NMDeviceBt *self = user_data; - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - int ifindex; - - priv->connect_watch_link_idle_id = 0; - - if (nm_device_get_state (NM_DEVICE (self)) <= NM_DEVICE_STATE_ACTIVATED) { - ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self)); - if ( ifindex > 0 - && !nm_platform_link_get (nm_device_get_platform (NM_DEVICE (self)), ifindex)) { - _LOGT (LOGD_BT, "device disappeared"); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - } - } - - return G_SOURCE_REMOVE; + NMDeviceBt * self = user_data; + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); + int ifindex; + + priv->connect_watch_link_idle_id = 0; + + if (nm_device_get_state(NM_DEVICE(self)) <= NM_DEVICE_STATE_ACTIVATED) { + ifindex = nm_device_get_ip_ifindex(NM_DEVICE(self)); + if (ifindex > 0 + && !nm_platform_link_get(nm_device_get_platform(NM_DEVICE(self)), ifindex)) { + _LOGT(LOGD_BT, "device disappeared"); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + } + } + + return G_SOURCE_REMOVE; } static void -connect_watch_link_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *info, - int change_type_i, - NMDevice *self) +connect_watch_link_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *info, + int change_type_i, + NMDevice * self) { - const NMPlatformSignalChangeType change_type = change_type_i; - NMDeviceBtPrivate *priv; - - /* bluez doesn't notify us when the connection disconnects. - * Neither does NMManager (or NMDevice) tell us when the ip-ifindex goes away. - * This is horrible, and should be improved. For now, watch the link ourself... */ - - if (NM_IN_SET (change_type, NM_PLATFORM_SIGNAL_CHANGED, - NM_PLATFORM_SIGNAL_REMOVED)) { - priv = NM_DEVICE_BT_GET_PRIVATE (self); - if (priv->connect_watch_link_idle_id == 0) - priv->connect_watch_link_idle_id = g_idle_add (connect_watch_link_idle_cb, self); - } + const NMPlatformSignalChangeType change_type = change_type_i; + NMDeviceBtPrivate * priv; + + /* bluez doesn't notify us when the connection disconnects. + * Neither does NMManager (or NMDevice) tell us when the ip-ifindex goes away. + * This is horrible, and should be improved. For now, watch the link ourself... */ + + if (NM_IN_SET(change_type, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_SIGNAL_REMOVED)) { + priv = NM_DEVICE_BT_GET_PRIVATE(self); + if (priv->connect_watch_link_idle_id == 0) + priv->connect_watch_link_idle_id = g_idle_add(connect_watch_link_idle_cb, self); + } } static gboolean -connect_wait_modem_timeout (gpointer user_data) +connect_wait_modem_timeout(gpointer user_data) { - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBt * self = NM_DEVICE_BT(user_data); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - /* since this timeout is longer than the connect timeout, we must have already - * hit the connect-timeout first or being connected. */ - nm_assert (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_COMPLETED); + /* since this timeout is longer than the connect timeout, we must have already + * hit the connect-timeout first or being connected. */ + nm_assert(priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_COMPLETED); - priv->connect_wait_modem_id = 0; - nm_clear_g_cancellable (&priv->connect_bz_cancellable); + priv->connect_wait_modem_id = 0; + nm_clear_g_cancellable(&priv->connect_bz_cancellable); - if (priv->modem) - _LOGD (LOGD_BT, "timeout connecting modem for DUN connection"); - else - _LOGD (LOGD_BT, "timeout finding modem for DUN connection"); + if (priv->modem) + _LOGD(LOGD_BT, "timeout connecting modem for DUN connection"); + else + _LOGD(LOGD_BT, "timeout finding modem for DUN connection"); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND); - return G_SOURCE_REMOVE; + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND); + return G_SOURCE_REMOVE; } static void -connect_bz_cb (NMBluezManager *bz_mgr, - gboolean is_complete, - const char *device_name, - GError *error, - gpointer user_data) +connect_bz_cb(NMBluezManager *bz_mgr, + gboolean is_complete, + const char * device_name, + GError * error, + gpointer user_data) { - NMDeviceBt *self; - NMDeviceBtPrivate *priv; - char sbuf[100]; - - if (nm_utils_error_is_cancelled (error)) - return; - - self = user_data; - priv = NM_DEVICE_BT_GET_PRIVATE (self); - - nm_assert (nm_device_is_activating (NM_DEVICE (self))); - nm_assert (NM_IN_SET ((NMBluetoothCapabilities) priv->connect_bt_type, NM_BT_CAPABILITY_DUN, - NM_BT_CAPABILITY_NAP)); - - if (!is_complete) { - nm_assert (priv->connect_bt_type == NM_BT_CAPABILITY_DUN); - nm_assert (device_name); - nm_assert (!error); - - if (!nm_streq0 (priv->connect_rfcomm_iface, device_name)) { - nm_assert (!priv->connect_rfcomm_iface); - _LOGD (LOGD_BT, "DUN is still connecting but got serial port \"%s\" to claim modem", device_name); - g_free (priv->connect_rfcomm_iface); - priv->connect_rfcomm_iface = g_strdup (device_name); - } - return; - } - - g_clear_object (&priv->connect_bz_cancellable); - - if (!device_name) { - _LOGW (LOGD_BT, "%s connect request failed: %s", - nm_bluetooth_capability_to_string (priv->connect_bt_type, sbuf, sizeof (sbuf)), - error->message); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - return; - } - - _LOGD (LOGD_BT, "%s connect request successful (%s)", - nm_bluetooth_capability_to_string (priv->connect_bt_type, sbuf, sizeof (sbuf)), - device_name); - - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (!nm_streq0 (priv->connect_rfcomm_iface, device_name)) { - nm_assert_not_reached (); - g_free (priv->connect_rfcomm_iface); - priv->connect_rfcomm_iface = g_strdup (device_name); - } - } else { - nm_assert (priv->connect_bt_type == NM_BT_CAPABILITY_NAP); - if (!nm_device_set_ip_iface (NM_DEVICE (self), device_name)) { - _LOGW (LOGD_BT, "Error connecting with bluez: cannot find device %s", device_name); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - return; - } - priv->connect_watch_link_id = g_signal_connect (nm_device_get_platform (NM_DEVICE (self)), - NM_PLATFORM_SIGNAL_LINK_CHANGED, - G_CALLBACK (connect_watch_link_cb), - self); - } - - if (!priv->is_connected) { - /* we got the callback from NMBluezManager with succes. We actually should be - * connected and this line shouldn't be reached. */ - nm_assert_not_reached (); - _LOGE (LOGD_BT, "bluetooth is unexpectedly not in connected state"); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - return; - } - - priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_COMPLETED; - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); + NMDeviceBt * self; + NMDeviceBtPrivate *priv; + char sbuf[100]; + + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_DEVICE_BT_GET_PRIVATE(self); + + nm_assert(nm_device_is_activating(NM_DEVICE(self))); + nm_assert(NM_IN_SET((NMBluetoothCapabilities) priv->connect_bt_type, + NM_BT_CAPABILITY_DUN, + NM_BT_CAPABILITY_NAP)); + + if (!is_complete) { + nm_assert(priv->connect_bt_type == NM_BT_CAPABILITY_DUN); + nm_assert(device_name); + nm_assert(!error); + + if (!nm_streq0(priv->connect_rfcomm_iface, device_name)) { + nm_assert(!priv->connect_rfcomm_iface); + _LOGD(LOGD_BT, + "DUN is still connecting but got serial port \"%s\" to claim modem", + device_name); + g_free(priv->connect_rfcomm_iface); + priv->connect_rfcomm_iface = g_strdup(device_name); + } + return; + } + + g_clear_object(&priv->connect_bz_cancellable); + + if (!device_name) { + _LOGW(LOGD_BT, + "%s connect request failed: %s", + nm_bluetooth_capability_to_string(priv->connect_bt_type, sbuf, sizeof(sbuf)), + error->message); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + return; + } + + _LOGD(LOGD_BT, + "%s connect request successful (%s)", + nm_bluetooth_capability_to_string(priv->connect_bt_type, sbuf, sizeof(sbuf)), + device_name); + + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { + if (!nm_streq0(priv->connect_rfcomm_iface, device_name)) { + nm_assert_not_reached(); + g_free(priv->connect_rfcomm_iface); + priv->connect_rfcomm_iface = g_strdup(device_name); + } + } else { + nm_assert(priv->connect_bt_type == NM_BT_CAPABILITY_NAP); + if (!nm_device_set_ip_iface(NM_DEVICE(self), device_name)) { + _LOGW(LOGD_BT, "Error connecting with bluez: cannot find device %s", device_name); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + return; + } + priv->connect_watch_link_id = g_signal_connect(nm_device_get_platform(NM_DEVICE(self)), + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(connect_watch_link_cb), + self); + } + + if (!priv->is_connected) { + /* we got the callback from NMBluezManager with success. We actually should be + * connected and this line shouldn't be reached. */ + nm_assert_not_reached(); + _LOGE(LOGD_BT, "bluetooth is unexpectedly not in connected state"); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + return; + } + + priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); } static NMActStageReturn -act_stage1_prepare (NMDevice *device, - NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - gs_free_error GError *error = NULL; - NMConnection *connection; - - connection = nm_device_get_applied_connection (device); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - priv->connect_bt_type = get_connection_bt_type (connection); - if (priv->connect_bt_type == NM_BT_CAPABILITY_NONE) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_BT_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if ( priv->connect_bt_type == NM_BT_CAPABILITY_DUN - && !priv->mm_running) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_PENDING) - return NM_ACT_STAGE_RETURN_POSTPONE; - else if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_INIT) { - gs_unref_object GCancellable *cancellable = NULL; - char sbuf[100]; - - _LOGD (LOGD_BT, "connecting to %s bluetooth device", - nm_bluetooth_capability_to_string (priv->connect_bt_type, sbuf, sizeof (sbuf))); - - cancellable = g_cancellable_new (); - - if (!nm_bluez_manager_connect (priv->bz_mgr, - priv->dbus_path, - priv->connect_bt_type, - 30000, - cancellable, - connect_bz_cb, - self, - &error)) { - _LOGD (LOGD_BT, "cannot connect to bluetooth device: %s", error->message); - *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - priv->connect_bz_cancellable = g_steal_pointer (&cancellable); - priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_PENDING; - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (!priv->modem) { - gs_free NMModem **modems = NULL; - guint i, n; - - if (priv->connect_wait_modem_id == 0) - priv->connect_wait_modem_id = g_timeout_add_seconds (30, connect_wait_modem_timeout, self); - - modems = nm_modem_manager_get_modems (priv->modem_manager, &n); - for (i = 0; i < n; i++) { - if (modem_try_claim (self, modems[i])) - break; - } - if (!priv->modem) - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_PENDING) - return NM_ACT_STAGE_RETURN_POSTPONE; - if (priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_INIT) { - priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_PENDING; - return nm_modem_act_stage1_prepare (priv->modem, - nm_device_get_act_request (NM_DEVICE (self)), - out_failure_reason); - } - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceBt * self = NM_DEVICE_BT(device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + NMConnection * connection; + + connection = nm_device_get_applied_connection(device); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + priv->connect_bt_type = get_connection_bt_type(connection); + if (priv->connect_bt_type == NM_BT_CAPABILITY_NONE) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_BT_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN && !priv->mm_running) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; + else if (priv->stage1_bt_state == NM_DEVICE_STAGE_STATE_INIT) { + gs_unref_object GCancellable *cancellable = NULL; + char sbuf[100]; + + _LOGD(LOGD_BT, + "connecting to %s bluetooth device", + nm_bluetooth_capability_to_string(priv->connect_bt_type, sbuf, sizeof(sbuf))); + + cancellable = g_cancellable_new(); + + if (!nm_bluez_manager_connect(priv->bz_mgr, + priv->dbus_path, + priv->connect_bt_type, + 30000, + cancellable, + connect_bz_cb, + self, + &error)) { + _LOGD(LOGD_BT, "cannot connect to bluetooth device: %s", error->message); + *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv->connect_bz_cancellable = g_steal_pointer(&cancellable); + priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_PENDING; + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { + if (!priv->modem) { + gs_free NMModem **modems = NULL; + guint i, n; + + if (priv->connect_wait_modem_id == 0) + priv->connect_wait_modem_id = + g_timeout_add_seconds(30, connect_wait_modem_timeout, self); + + modems = nm_modem_manager_get_modems(priv->modem_manager, &n); + for (i = 0; i < n; i++) { + if (modem_try_claim(self, modems[i])) + break; + } + if (!priv->modem) + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; + if (priv->stage1_modem_prepare_state == NM_DEVICE_STAGE_STATE_INIT) { + priv->stage1_modem_prepare_state = NM_DEVICE_STAGE_STATE_PENDING; + return nm_modem_act_stage1_prepare(priv->modem, + nm_device_get_act_request(NM_DEVICE(self)), + out_failure_reason); + } + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage2_config (NMDevice *device, - NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBt * self = NM_DEVICE_BT(device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) - nm_modem_act_stage2_config (priv->modem); + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) + nm_modem_act_stage2_config(priv->modem); - return NM_ACT_STAGE_RETURN_SUCCESS; + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); - - nm_assert_addr_family (addr_family); - - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start (priv->modem, - device, - NM_DEVICE_CLASS (nm_device_bt_parent_class), - out_failure_reason); - } else { - return nm_modem_stage3_ip6_config_start (priv->modem, - device, - out_failure_reason); - } - } - - return NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + + nm_assert_addr_family(addr_family); + + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { + if (addr_family == AF_INET) { + return nm_modem_stage3_ip4_config_start(priv->modem, + device, + NM_DEVICE_CLASS(nm_device_bt_parent_class), + out_failure_reason); + } else { + return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); + } + } + + return NM_DEVICE_CLASS(nm_device_bt_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); - - nm_clear_g_signal_handler (nm_device_get_platform (device), &priv->connect_watch_link_id); - nm_clear_g_source (&priv->connect_watch_link_idle_id); - priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_INIT; - nm_clear_g_source (&priv->connect_wait_modem_id); - nm_clear_g_cancellable (&priv->connect_bz_cancellable); - - priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_INIT; - - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (priv->modem) { - nm_modem_deactivate (priv->modem, device); - - /* Since we're killing the Modem object before it'll get the - * state change signal, simulate the state change here. - */ - nm_modem_device_state_changed (priv->modem, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_ACTIVATED); - modem_cleanup (NM_DEVICE_BT (device)); - } - } - - if (priv->connect_bt_type != NM_BT_CAPABILITY_NONE) { - priv->connect_bt_type = NM_BT_CAPABILITY_NONE; - nm_bluez_manager_disconnect (priv->bz_mgr, priv->dbus_path); - } - - nm_clear_g_free (&priv->connect_rfcomm_iface); - - if (NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate) - NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate (device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + + nm_clear_g_signal_handler(nm_device_get_platform(device), &priv->connect_watch_link_id); + nm_clear_g_source(&priv->connect_watch_link_idle_id); + priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_INIT; + nm_clear_g_source(&priv->connect_wait_modem_id); + nm_clear_g_cancellable(&priv->connect_bz_cancellable); + + priv->stage1_bt_state = NM_DEVICE_STAGE_STATE_INIT; + + if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { + if (priv->modem) { + nm_modem_deactivate(priv->modem, device); + + /* Since we're killing the Modem object before it'll get the + * state change signal, simulate the state change here. + */ + nm_modem_device_state_changed(priv->modem, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_ACTIVATED); + modem_cleanup(NM_DEVICE_BT(device)); + } + } + + if (priv->connect_bt_type != NM_BT_CAPABILITY_NONE) { + priv->connect_bt_type = NM_BT_CAPABILITY_NONE; + nm_bluez_manager_disconnect(priv->bz_mgr, priv->dbus_path); + } + + nm_clear_g_free(&priv->connect_rfcomm_iface); + + if (NM_DEVICE_CLASS(nm_device_bt_parent_class)->deactivate) + NM_DEVICE_CLASS(nm_device_bt_parent_class)->deactivate(device); } void -_nm_device_bt_notify_removed (NMDeviceBt *self) +_nm_device_bt_notify_removed(NMDeviceBt *self) { - g_signal_emit_by_name (self, NM_DEVICE_REMOVED); + g_signal_emit_by_name(self, NM_DEVICE_REMOVED); } /*****************************************************************************/ gboolean -_nm_device_bt_for_same_device (NMDeviceBt *self, - const char *dbus_path, - const char *bdaddr, - const char *name, - NMBluetoothCapabilities capabilities) +_nm_device_bt_for_same_device(NMDeviceBt * self, + const char * dbus_path, + const char * bdaddr, + const char * name, + NMBluetoothCapabilities capabilities) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - return nm_streq (priv->dbus_path, dbus_path) - && nm_streq (priv->bdaddr, bdaddr) - && capabilities == priv->capabilities - && (!name || nm_streq (priv->name, name)); + return nm_streq(priv->dbus_path, dbus_path) && nm_streq(priv->bdaddr, bdaddr) + && capabilities == priv->capabilities && (!name || nm_streq(priv->name, name)); } void -_nm_device_bt_notify_set_name (NMDeviceBt *self, const char *name) +_nm_device_bt_notify_set_name(NMDeviceBt *self, const char *name) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - nm_assert (name); + nm_assert(name); - if (!nm_streq (priv->name, name)) { - _LOGT (LOGD_BT, "set-name: %s", name); - g_free (priv->name); - priv->name = g_strdup (name); - _notify (self, PROP_BT_NAME); - } + if (!nm_streq(priv->name, name)) { + _LOGT(LOGD_BT, "set-name: %s", name); + g_free(priv->name); + priv->name = g_strdup(name); + _notify(self, PROP_BT_NAME); + } } /*****************************************************************************/ static gboolean -is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *dev, NMDeviceCheckDevAvailableFlags flags) { - NMDeviceBt *self = NM_DEVICE_BT (dev); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBt * self = NM_DEVICE_BT(dev); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - /* PAN doesn't need ModemManager, so devices that support it are always available */ - if (priv->capabilities & NM_BT_CAPABILITY_NAP) - return TRUE; + /* PAN doesn't need ModemManager, so devices that support it are always available */ + if (priv->capabilities & NM_BT_CAPABILITY_NAP) + return TRUE; - /* DUN requires ModemManager */ - return priv->mm_running; + /* DUN requires ModemManager */ + return priv->mm_running; } static void -set_mm_running (NMDeviceBt *self) +set_mm_running(NMDeviceBt *self) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - gboolean running; + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); + gboolean running; - running = (nm_modem_manager_name_owner_get (priv->modem_manager) != NULL); + running = (nm_modem_manager_name_owner_get(priv->modem_manager) != NULL); - if (priv->mm_running != running) { - _LOGD (LOGD_BT, "ModemManager now %s", - running ? "available" : "unavailable"); + if (priv->mm_running != running) { + _LOGD(LOGD_BT, "ModemManager now %s", running ? "available" : "unavailable"); - priv->mm_running = running; - nm_device_queue_recheck_available (NM_DEVICE (self), - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); - } + priv->mm_running = running; + nm_device_queue_recheck_available(NM_DEVICE(self), + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); + } } static void -mm_name_owner_changed_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) +mm_name_owner_changed_cb(GObject *object, GParamSpec *pspec, gpointer user_data) { - set_mm_running (user_data); + set_mm_running(user_data); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_BT_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_BT_CAPABILITIES: - g_value_set_uint (value, priv->capabilities); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_BT_NAME: + g_value_set_string(value, priv->name); + break; + case PROP_BT_CAPABILITIES: + g_value_set_uint(value, priv->capabilities); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_BT_BZ_MGR: - /* construct-only */ - priv->bz_mgr = g_object_ref (g_value_get_pointer (value)); - nm_assert (NM_IS_BLUEZ_MANAGER (priv->bz_mgr)); - break; - case PROP_BT_DBUS_PATH: - /* construct-only */ - priv->dbus_path = g_value_dup_string (value); - nm_assert (priv->dbus_path); - break; - case PROP_BT_BDADDR: - /* construct-only */ - priv->bdaddr = g_value_dup_string (value); - nm_assert (priv->bdaddr); - break; - case PROP_BT_NAME: - /* construct-only */ - priv->name = g_value_dup_string (value); - nm_assert (priv->name); - break; - case PROP_BT_CAPABILITIES: - /* construct-only */ - priv->capabilities = g_value_get_uint (value); - nm_assert (NM_IN_SET ((NMBluetoothCapabilities) priv->capabilities, NM_BT_CAPABILITY_DUN, - NM_BT_CAPABILITY_NAP, - NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_BT_BZ_MGR: + /* construct-only */ + priv->bz_mgr = g_object_ref(g_value_get_pointer(value)); + nm_assert(NM_IS_BLUEZ_MANAGER(priv->bz_mgr)); + break; + case PROP_BT_DBUS_PATH: + /* construct-only */ + priv->dbus_path = g_value_dup_string(value); + nm_assert(priv->dbus_path); + break; + case PROP_BT_BDADDR: + /* construct-only */ + priv->bdaddr = g_value_dup_string(value); + nm_assert(priv->bdaddr); + break; + case PROP_BT_NAME: + /* construct-only */ + priv->name = g_value_dup_string(value); + nm_assert(priv->name); + break; + case PROP_BT_CAPABILITIES: + /* construct-only */ + priv->capabilities = g_value_get_uint(value); + nm_assert(NM_IN_SET((NMBluetoothCapabilities) priv->capabilities, + NM_BT_CAPABILITY_DUN, + NM_BT_CAPABILITY_NAP, + NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_bt_init (NMDeviceBt *self) -{ -} +nm_device_bt_init(NMDeviceBt *self) +{} static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceBt *self = NM_DEVICE_BT (object); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBt * self = NM_DEVICE_BT(object); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_device_bt_parent_class)->constructed(object); - priv->modem_manager = g_object_ref (nm_modem_manager_get ()); + priv->modem_manager = g_object_ref(nm_modem_manager_get()); - nm_modem_manager_name_owner_ref (priv->modem_manager); + nm_modem_manager_name_owner_ref(priv->modem_manager); - g_signal_connect (priv->modem_manager, - NM_MODEM_MANAGER_MODEM_ADDED, - G_CALLBACK (mm_modem_added_cb), - self); + g_signal_connect(priv->modem_manager, + NM_MODEM_MANAGER_MODEM_ADDED, + G_CALLBACK(mm_modem_added_cb), + self); - g_signal_connect (priv->modem_manager, - "notify::"NM_MODEM_MANAGER_NAME_OWNER, - G_CALLBACK (mm_name_owner_changed_cb), - self); + g_signal_connect(priv->modem_manager, + "notify::" NM_MODEM_MANAGER_NAME_OWNER, + G_CALLBACK(mm_name_owner_changed_cb), + self); - set_mm_running (self); + set_mm_running(self); } NMDeviceBt * -nm_device_bt_new (NMBluezManager *bz_mgr, - const char *dbus_path, - const char *bdaddr, - const char *name, - NMBluetoothCapabilities capabilities) +nm_device_bt_new(NMBluezManager * bz_mgr, + const char * dbus_path, + const char * bdaddr, + const char * name, + NMBluetoothCapabilities capabilities) { - g_return_val_if_fail (NM_IS_BLUEZ_MANAGER (bz_mgr), NULL); - g_return_val_if_fail (dbus_path, NULL); - g_return_val_if_fail (bdaddr, NULL); - g_return_val_if_fail (name, NULL); - g_return_val_if_fail (capabilities != NM_BT_CAPABILITY_NONE, NULL); - - return g_object_new (NM_TYPE_DEVICE_BT, - NM_DEVICE_UDI, dbus_path, - NM_DEVICE_IFACE, bdaddr, - NM_DEVICE_DRIVER, "bluez", - NM_DEVICE_PERM_HW_ADDRESS, bdaddr, - NM_DEVICE_BT_BDADDR, bdaddr, - NM_DEVICE_BT_BZ_MGR, bz_mgr, - NM_DEVICE_BT_CAPABILITIES, (guint) capabilities, - NM_DEVICE_BT_DBUS_PATH, dbus_path, - NM_DEVICE_BT_NAME, name, - NM_DEVICE_TYPE_DESC, "Bluetooth", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BT, - NULL); + g_return_val_if_fail(NM_IS_BLUEZ_MANAGER(bz_mgr), NULL); + g_return_val_if_fail(dbus_path, NULL); + g_return_val_if_fail(bdaddr, NULL); + g_return_val_if_fail(name, NULL); + g_return_val_if_fail(capabilities != NM_BT_CAPABILITY_NONE, NULL); + + return g_object_new(NM_TYPE_DEVICE_BT, + NM_DEVICE_UDI, + dbus_path, + NM_DEVICE_IFACE, + bdaddr, + NM_DEVICE_DRIVER, + "bluez", + NM_DEVICE_PERM_HW_ADDRESS, + bdaddr, + NM_DEVICE_BT_BDADDR, + bdaddr, + NM_DEVICE_BT_BZ_MGR, + bz_mgr, + NM_DEVICE_BT_CAPABILITIES, + (guint) capabilities, + NM_DEVICE_BT_DBUS_PATH, + dbus_path, + NM_DEVICE_BT_NAME, + name, + NM_DEVICE_TYPE_DESC, + "Bluetooth", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_BT, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceBt *self = NM_DEVICE_BT (object); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + NMDeviceBt * self = NM_DEVICE_BT(object); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(self); - nm_clear_g_signal_handler (nm_device_get_platform (NM_DEVICE (self)), &priv->connect_watch_link_id); - nm_clear_g_source (&priv->connect_watch_link_idle_id); + nm_clear_g_signal_handler(nm_device_get_platform(NM_DEVICE(self)), + &priv->connect_watch_link_id); + nm_clear_g_source(&priv->connect_watch_link_idle_id); - nm_clear_g_source (&priv->connect_wait_modem_id); - nm_clear_g_cancellable (&priv->connect_bz_cancellable); + nm_clear_g_source(&priv->connect_wait_modem_id); + nm_clear_g_cancellable(&priv->connect_bz_cancellable); - if (priv->modem_manager) { - g_signal_handlers_disconnect_by_func (priv->modem_manager, G_CALLBACK (mm_name_owner_changed_cb), self); - g_signal_handlers_disconnect_by_func (priv->modem_manager, G_CALLBACK (mm_modem_added_cb), self); - nm_modem_manager_name_owner_unref (priv->modem_manager); - g_clear_object (&priv->modem_manager); - } + if (priv->modem_manager) { + g_signal_handlers_disconnect_by_func(priv->modem_manager, + G_CALLBACK(mm_name_owner_changed_cb), + self); + g_signal_handlers_disconnect_by_func(priv->modem_manager, + G_CALLBACK(mm_modem_added_cb), + self); + nm_modem_manager_name_owner_unref(priv->modem_manager); + g_clear_object(&priv->modem_manager); + } - modem_cleanup (self); + modem_cleanup(self); - G_OBJECT_CLASS (nm_device_bt_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_bt_parent_class)->dispose(object); - g_clear_object (&priv->bz_mgr); + g_clear_object(&priv->bz_mgr); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(object); - g_free (priv->connect_rfcomm_iface); - g_free (priv->dbus_path); - g_free (priv->name); - g_free (priv->bdaddr); + g_free(priv->connect_rfcomm_iface); + g_free(priv->dbus_path); + g_free(priv->name); + g_free(priv->bdaddr); - G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_device_bt_parent_class)->finalize(object); } static const NMDBusInterfaceInfoExtended interface_info_device_bluetooth = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Name", "s", NM_DEVICE_BT_NAME), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("BtCapabilities", "u", NM_DEVICE_BT_CAPABILITIES), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Name", "s", NM_DEVICE_BT_NAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("BtCapabilities", + "u", + NM_DEVICE_BT_CAPABILITIES), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_bt_class_init (NMDeviceBtClass *klass) +nm_device_bt_class_init(NMDeviceBtClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bluetooth); - - device_class->connection_type_check_compatible = NM_SETTING_BLUETOOTH_SETTING_NAME; - - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->can_auto_connect = can_auto_connect; - device_class->deactivate = deactivate; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->is_available = is_available; - device_class->get_configured_mtu = nm_modem_get_configured_mtu; - - device_class->state_changed = device_state_changed; - - obj_properties[PROP_BT_BZ_MGR] = - g_param_spec_pointer (NM_DEVICE_BT_BZ_MGR, "", "", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BT_BDADDR] = - g_param_spec_string (NM_DEVICE_BT_BDADDR, "", "", - NULL, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BT_DBUS_PATH] = - g_param_spec_string (NM_DEVICE_BT_DBUS_PATH, "", "", - NULL, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BT_NAME] = - g_param_spec_string (NM_DEVICE_BT_NAME, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BT_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, "", "", - NM_BT_CAPABILITY_NONE, G_MAXUINT, NM_BT_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[PPP_STATS] = - g_signal_new (NM_DEVICE_BT_PPP_STATS, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_UINT /*guint32 in_bytes*/, - G_TYPE_UINT /*guint32 out_bytes*/); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_bluetooth); + + device_class->connection_type_check_compatible = NM_SETTING_BLUETOOTH_SETTING_NAME; + + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->can_auto_connect = can_auto_connect; + device_class->deactivate = deactivate; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + device_class->is_available = is_available; + device_class->get_configured_mtu = nm_modem_get_configured_mtu; + + device_class->state_changed = device_state_changed; + + obj_properties[PROP_BT_BZ_MGR] = + g_param_spec_pointer(NM_DEVICE_BT_BZ_MGR, + "", + "", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BT_BDADDR] = + g_param_spec_string(NM_DEVICE_BT_BDADDR, + "", + "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BT_DBUS_PATH] = + g_param_spec_string(NM_DEVICE_BT_DBUS_PATH, + "", + "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BT_NAME] = + g_param_spec_string(NM_DEVICE_BT_NAME, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BT_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_BT_CAPABILITIES, + "", + "", + NM_BT_CAPABILITY_NONE, + G_MAXUINT, + NM_BT_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[PPP_STATS] = g_signal_new(NM_DEVICE_BT_PPP_STATS, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_UINT /*guint32 in_bytes*/, + G_TYPE_UINT /*guint32 out_bytes*/); } diff --git a/src/devices/bluetooth/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h index ecb5781b..e8a35a21 100644 --- a/src/devices/bluetooth/nm-device-bt.h +++ b/src/devices/bluetooth/nm-device-bt.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 Red Hat, Inc. */ @@ -8,12 +8,14 @@ #include "devices/nm-device.h" -#define NM_TYPE_DEVICE_BT (nm_device_bt_get_type ()) -#define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BT, NMDeviceBt)) -#define NM_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) -#define NM_IS_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BT)) -#define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT)) -#define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) +#define NM_TYPE_DEVICE_BT (nm_device_bt_get_type()) +#define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BT, NMDeviceBt)) +#define NM_DEVICE_BT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) +#define NM_IS_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BT)) +#define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BT)) +#define NM_DEVICE_BT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) #define NM_DEVICE_BT_BDADDR "bt-bdaddr" #define NM_DEVICE_BT_BZ_MGR "bt-bz-mgr" @@ -21,40 +23,37 @@ #define NM_DEVICE_BT_DBUS_PATH "bt-dbus-path" #define NM_DEVICE_BT_NAME "bt-name" -#define NM_DEVICE_BT_PPP_STATS "ppp-stats" +#define NM_DEVICE_BT_PPP_STATS "ppp-stats" -typedef struct _NMDeviceBt NMDeviceBt; +typedef struct _NMDeviceBt NMDeviceBt; typedef struct _NMDeviceBtClass NMDeviceBtClass; -GType nm_device_bt_get_type (void); +GType nm_device_bt_get_type(void); struct _NMBluezManager; -NMDeviceBt *nm_device_bt_new (struct _NMBluezManager *bz_mgr, - const char *dbus_path, - const char *bdaddr, - const char *name, - NMBluetoothCapabilities capabilities); +NMDeviceBt *nm_device_bt_new(struct _NMBluezManager *bz_mgr, + const char * dbus_path, + const char * bdaddr, + const char * name, + NMBluetoothCapabilities capabilities); -gboolean _nm_device_bt_for_same_device (NMDeviceBt *device, - const char *dbus_path, - const char *bdaddr, - const char *name, - NMBluetoothCapabilities capabilities); +gboolean _nm_device_bt_for_same_device(NMDeviceBt * device, + const char * dbus_path, + const char * bdaddr, + const char * name, + NMBluetoothCapabilities capabilities); -NMBluetoothCapabilities nm_device_bt_get_capabilities (NMDeviceBt *device); +NMBluetoothCapabilities nm_device_bt_get_capabilities(NMDeviceBt *device); struct _NMModem; -gboolean nm_device_bt_modem_added (NMDeviceBt *device, - struct _NMModem *modem, - const char *driver); +gboolean nm_device_bt_modem_added(NMDeviceBt *device, struct _NMModem *modem, const char *driver); -void _nm_device_bt_notify_removed (NMDeviceBt *self); +void _nm_device_bt_notify_removed(NMDeviceBt *self); -void _nm_device_bt_notify_set_name (NMDeviceBt *self, const char *name); +void _nm_device_bt_notify_set_name(NMDeviceBt *self, const char *name); -void _nm_device_bt_notify_set_connected (NMDeviceBt *self, - gboolean connected); +void _nm_device_bt_notify_set_connected(NMDeviceBt *self, gboolean connected); #endif /* __NETWORKMANAGER_DEVICE_BT_H__ */ diff --git a/src/devices/bluetooth/tests/nm-bt-test.c b/src/devices/bluetooth/tests/nm-bt-test.c index 02cfd228..a57bb076 100644 --- a/src/devices/bluetooth/tests/nm-bt-test.c +++ b/src/devices/bluetooth/tests/nm-bt-test.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ #include "nm-default.h" @@ -11,25 +11,27 @@ /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_BT -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, \ - NULL, NULL, \ - "bt%s%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - NM_PRINT_FMT_QUOTED (gl.argv_cmd, "[", gl.argv_cmd, "]", "") \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "bt%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_PRINT_FMT_QUOTED(gl.argv_cmd, "[", gl.argv_cmd, "]", "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) /*****************************************************************************/ struct { - int argc; - const char *const*argv; - const char *argv_cmd; - GMainLoop *loop; + int argc; + const char *const *argv; + const char * argv_cmd; + GMainLoop * loop; } gl; typedef struct _MainCmdInfo { - const char *name; - int (*main_func) (const struct _MainCmdInfo *main_cmd_info); + const char *name; + int (*main_func)(const struct _MainCmdInfo *main_cmd_info); } MainCmdInfo; /*****************************************************************************/ @@ -37,184 +39,185 @@ typedef struct _MainCmdInfo { #if WITH_BLUEZ5_DUN typedef struct { - NMBluez5DunContext *dun_context; - GCancellable *cancellable; - guint timeout_id; - guint sig_term_id; - guint sig_int_id; + NMBluez5DunContext *dun_context; + GCancellable * cancellable; + guint timeout_id; + guint sig_term_id; + guint sig_int_id; } DunConnectData; static void -_dun_connect_cb (NMBluez5DunContext *context, - const char *rfcomm_dev, - GError *error, - gpointer user_data) +_dun_connect_cb(NMBluez5DunContext *context, + const char * rfcomm_dev, + GError * error, + gpointer user_data) { - DunConnectData *dun_connect_data = user_data; + DunConnectData *dun_connect_data = user_data; - g_assert (dun_connect_data); - g_assert (!dun_connect_data->dun_context); - g_assert ((!!error) != (!!rfcomm_dev)); + g_assert(dun_connect_data); + g_assert(!dun_connect_data->dun_context); + g_assert((!!error) != (!!rfcomm_dev)); - if (rfcomm_dev && !context) { - _LOGI ("dun-connect notifies path \"%s\". Wait longer...", rfcomm_dev); - return; - } + if (rfcomm_dev && !context) { + _LOGI("dun-connect notifies path \"%s\". Wait longer...", rfcomm_dev); + return; + } - if (rfcomm_dev) { - g_assert (context); - _LOGI ("dun-connect completed with path \"%s\"", rfcomm_dev); - } else { - g_assert (!context); - _LOGI ("dun-connect failed with error: %s", error->message); - } + if (rfcomm_dev) { + g_assert(context); + _LOGI("dun-connect completed with path \"%s\"", rfcomm_dev); + } else { + g_assert(!context); + _LOGI("dun-connect failed with error: %s", error->message); + } - dun_connect_data->dun_context = context; + dun_connect_data->dun_context = context; - g_main_loop_quit (gl.loop); + g_main_loop_quit(gl.loop); } static void -_dun_notify_tty_hangup_cb (NMBluez5DunContext *context, - gpointer user_data) +_dun_notify_tty_hangup_cb(NMBluez5DunContext *context, gpointer user_data) { - _LOGI ("dun-connect: notified TTY hangup"); + _LOGI("dun-connect: notified TTY hangup"); } static gboolean -_timeout_cb (gpointer user_data) +_timeout_cb(gpointer user_data) { - DunConnectData *dun_connect_data = user_data; + DunConnectData *dun_connect_data = user_data; - _LOGI ("timeout"); - dun_connect_data->timeout_id = 0; - if (dun_connect_data->cancellable) - g_cancellable_cancel (dun_connect_data->cancellable); - return G_SOURCE_REMOVE; + _LOGI("timeout"); + dun_connect_data->timeout_id = 0; + if (dun_connect_data->cancellable) + g_cancellable_cancel(dun_connect_data->cancellable); + return G_SOURCE_REMOVE; } static gboolean -_sig_xxx_cb (DunConnectData *dun_connect_data, int sigid) +_sig_xxx_cb(DunConnectData *dun_connect_data, int sigid) { - _LOGI ("signal %s received", sigid == SIGTERM ? "SIGTERM" : "SIGINT"); - g_main_loop_quit (gl.loop); - return G_SOURCE_CONTINUE; + _LOGI("signal %s received", sigid == SIGTERM ? "SIGTERM" : "SIGINT"); + g_main_loop_quit(gl.loop); + return G_SOURCE_CONTINUE; } static gboolean -_sig_term_cb (gpointer user_data) +_sig_term_cb(gpointer user_data) { - return _sig_xxx_cb (user_data, SIGTERM); + return _sig_xxx_cb(user_data, SIGTERM); } static gboolean -_sig_int_cb (gpointer user_data) +_sig_int_cb(gpointer user_data) { - return _sig_xxx_cb (user_data, SIGINT); + return _sig_xxx_cb(user_data, SIGINT); } #endif static int -do_dun_connect (const MainCmdInfo *main_cmd_info) +do_dun_connect(const MainCmdInfo *main_cmd_info) { #if WITH_BLUEZ5_DUN - gs_unref_object GCancellable *cancellable = NULL; - gs_free_error GError *error = NULL; - const char *adapter; - const char *remote; - DunConnectData dun_connect_data = { }; + gs_unref_object GCancellable *cancellable = NULL; + gs_free_error GError *error = NULL; + const char * adapter; + const char * remote; + DunConnectData dun_connect_data = {}; - if (gl.argc < 4) { - _LOGE ("missing arguments \"adapter\" and \"remote\""); - return -1; - } + if (gl.argc < 4) { + _LOGE("missing arguments \"adapter\" and \"remote\""); + return -1; + } - adapter = gl.argv[2]; - remote = gl.argv[3]; + adapter = gl.argv[2]; + remote = gl.argv[3]; - cancellable = g_cancellable_new (); - dun_connect_data.cancellable = cancellable; + cancellable = g_cancellable_new(); + dun_connect_data.cancellable = cancellable; - if (!nm_bluez5_dun_connect (adapter, - remote, - cancellable, - _dun_connect_cb, - &dun_connect_data, - _dun_notify_tty_hangup_cb, - &dun_connect_data, - &error)) { - _LOGE ("connect failed to start: %s", error->message); - return -1; - } + if (!nm_bluez5_dun_connect(adapter, + remote, + cancellable, + _dun_connect_cb, + &dun_connect_data, + _dun_notify_tty_hangup_cb, + &dun_connect_data, + &error)) { + _LOGE("connect failed to start: %s", error->message); + return -1; + } - dun_connect_data.timeout_id = g_timeout_add (60000, _timeout_cb, &dun_connect_data); + dun_connect_data.timeout_id = g_timeout_add(60000, _timeout_cb, &dun_connect_data); - g_main_loop_run (gl.loop); + g_main_loop_run(gl.loop); - nm_clear_g_source (&dun_connect_data.timeout_id); + nm_clear_g_source(&dun_connect_data.timeout_id); - if (dun_connect_data.dun_context) { + if (dun_connect_data.dun_context) { + dun_connect_data.sig_term_id = g_unix_signal_add(SIGTERM, _sig_term_cb, &dun_connect_data); + dun_connect_data.sig_int_id = g_unix_signal_add(SIGINT, _sig_int_cb, &dun_connect_data); - dun_connect_data.sig_term_id = g_unix_signal_add (SIGTERM, _sig_term_cb, &dun_connect_data); - dun_connect_data.sig_int_id = g_unix_signal_add (SIGINT, _sig_int_cb, &dun_connect_data); + g_main_loop_run(gl.loop); - g_main_loop_run (gl.loop); + nm_clear_g_source(&dun_connect_data.sig_term_id); + nm_clear_g_source(&dun_connect_data.sig_int_id); - nm_clear_g_source (&dun_connect_data.sig_term_id); - nm_clear_g_source (&dun_connect_data.sig_int_id); + nm_bluez5_dun_disconnect(g_steal_pointer(&dun_connect_data.dun_context)); + } - nm_bluez5_dun_disconnect (g_steal_pointer (&dun_connect_data.dun_context)); - } - - return 0; + return 0; #else - _LOGE ("compiled without bluetooth DUN support"); - return 1; + _LOGE("compiled without bluetooth DUN support"); + return 1; #endif } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) +main(int argc, char **argv) { - static const MainCmdInfo main_cmd_infos[] = { - { .name = "dun-connect", .main_func = do_dun_connect, }, - }; - int exit_code = 0; - guint i; - - if (!g_getenv ("G_MESSAGES_DEBUG")) - g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); - - nmtst_init_with_logging (&argc, &argv, "DEBUG", "ALL"); - - nm_logging_init (NULL, TRUE); - - gl.argv = (const char *const*) argv; - gl.argc = argc; - gl.loop = g_main_loop_new (NULL, FALSE); - - _LOGI ("bluetooth test util start"); - - gl.argv_cmd = argc >= 2 ? argv[1] : NULL; - - for (i = 0; i < G_N_ELEMENTS (main_cmd_infos); i++) { - if (nm_streq0 (main_cmd_infos[i].name, gl.argv_cmd)) { - _LOGD ("start \"%s\"", gl.argv_cmd); - exit_code = main_cmd_infos[i].main_func (&main_cmd_infos[i]); - _LOGD ("completed with %d", exit_code); - break; - } - } - if (gl.argv_cmd && i >= G_N_ELEMENTS (main_cmd_infos)) { - nm_log_err (LOGD_BT, "invalid command \"%s\"", gl.argv_cmd); - exit_code = -1; - } - - nm_clear_pointer (&gl.loop, g_main_loop_unref); - - return exit_code; + static const MainCmdInfo main_cmd_infos[] = { + { + .name = "dun-connect", + .main_func = do_dun_connect, + }, + }; + int exit_code = 0; + guint i; + + if (!g_getenv("G_MESSAGES_DEBUG")) + g_setenv("G_MESSAGES_DEBUG", "all", TRUE); + + nmtst_init_with_logging(&argc, &argv, "DEBUG", "ALL"); + + nm_logging_init(NULL, TRUE); + + gl.argv = (const char *const *) argv; + gl.argc = argc; + gl.loop = g_main_loop_new(NULL, FALSE); + + _LOGI("bluetooth test util start"); + + gl.argv_cmd = argc >= 2 ? argv[1] : NULL; + + for (i = 0; i < G_N_ELEMENTS(main_cmd_infos); i++) { + if (nm_streq0(main_cmd_infos[i].name, gl.argv_cmd)) { + _LOGD("start \"%s\"", gl.argv_cmd); + exit_code = main_cmd_infos[i].main_func(&main_cmd_infos[i]); + _LOGD("completed with %d", exit_code); + break; + } + } + if (gl.argv_cmd && i >= G_N_ELEMENTS(main_cmd_infos)) { + nm_log_err(LOGD_BT, "invalid command \"%s\"", gl.argv_cmd); + exit_code = -1; + } + + nm_clear_pointer(&gl.loop, g_main_loop_unref); + + return exit_code; } diff --git a/src/devices/nm-acd-manager.c b/src/devices/nm-acd-manager.c index 1c6c42a0..c9992ff5 100644 --- a/src/devices/nm-acd-manager.c +++ b/src/devices/nm-acd-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2018 Red Hat, Inc. */ @@ -19,123 +19,125 @@ /*****************************************************************************/ typedef enum { - STATE_INIT, - STATE_PROBING, - STATE_PROBE_DONE, - STATE_ANNOUNCING, + STATE_INIT, + STATE_PROBING, + STATE_PROBE_DONE, + STATE_ANNOUNCING, } State; typedef struct { - in_addr_t address; - gboolean duplicate; - NAcdProbe *probe; + in_addr_t address; + gboolean duplicate; + NAcdProbe *probe; } AddressInfo; struct _NMAcdManager { - int ifindex; - guint8 hwaddr[ETH_ALEN]; - State state; - GHashTable *addresses; - guint completed; - NAcd *acd; - GSource *event_source; - - NMAcdCallbacks callbacks; - gpointer user_data; + int ifindex; + guint8 hwaddr[ETH_ALEN]; + State state; + GHashTable *addresses; + guint completed; + NAcd * acd; + GSource * event_source; + + NMAcdCallbacks callbacks; + gpointer user_data; }; /*****************************************************************************/ -#define _NMLOG_DOMAIN LOGD_IP4 -#define _NMLOG_PREFIX_NAME "acd" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - char _sbuf[64]; \ - \ - nm_log ((level), _NMLOG_DOMAIN, \ - self && self->ifindex > 0 ? nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex) : NULL, \ - NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - self ? nm_sprintf_buf (_sbuf, "[%p,%d]", self, self->ifindex) : "" \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG_DOMAIN LOGD_IP4 +#define _NMLOG_PREFIX_NAME "acd" +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + char _sbuf[64]; \ + \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + self && self->ifindex > 0 \ + ? nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex) \ + : NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + self ? nm_sprintf_buf(_sbuf, "[%p,%d]", self, self->ifindex) \ + : "" _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ static const char * -_acd_event_to_string (unsigned int event) +_acd_event_to_string(unsigned int event) { - switch (event) { - case N_ACD_EVENT_READY: - return "ready"; - case N_ACD_EVENT_USED: - return "used"; - case N_ACD_EVENT_DEFENDED: - return "defended"; - case N_ACD_EVENT_CONFLICT: - return "conflict"; - case N_ACD_EVENT_DOWN: - return "down"; - } - return NULL; + switch (event) { + case N_ACD_EVENT_READY: + return "ready"; + case N_ACD_EVENT_USED: + return "used"; + case N_ACD_EVENT_DEFENDED: + return "defended"; + case N_ACD_EVENT_CONFLICT: + return "conflict"; + case N_ACD_EVENT_DOWN: + return "down"; + } + return NULL; } #define ACD_EVENT_TO_STRING_BUF_SIZE 50 static const char * -_acd_event_to_string_buf (unsigned event, char buffer[static ACD_EVENT_TO_STRING_BUF_SIZE]) +_acd_event_to_string_buf(unsigned event, char buffer[static ACD_EVENT_TO_STRING_BUF_SIZE]) { - const char *s; + const char *s; - s = _acd_event_to_string (event); - if (s) - return s; + s = _acd_event_to_string(event); + if (s) + return s; - g_snprintf (buffer, ACD_EVENT_TO_STRING_BUF_SIZE, "(%u)", event); - return buffer; + g_snprintf(buffer, ACD_EVENT_TO_STRING_BUF_SIZE, "(%u)", event); + return buffer; } static const char * -acd_error_to_string (int error) +acd_error_to_string(int error) { - if (error < 0) - return nm_strerror_native (-error); - - switch (error) { - case _N_ACD_E_SUCCESS: - return "success"; - case N_ACD_E_PREEMPTED: - return "preempted"; - case N_ACD_E_INVALID_ARGUMENT: - return "invalid argument"; - } - - g_return_val_if_reached (NULL); + if (error < 0) + return nm_strerror_native(-error); + + switch (error) { + case _N_ACD_E_SUCCESS: + return "success"; + case N_ACD_E_PREEMPTED: + return "preempted"; + case N_ACD_E_INVALID_ARGUMENT: + return "invalid argument"; + } + + g_return_val_if_reached(NULL); } static int -acd_error_to_nmerr (int error, gboolean always_fail) +acd_error_to_nmerr(int error, gboolean always_fail) { - if (error < 0) - return -nm_errno_native (error); - - if (always_fail) { - if (NM_IN_SET (error, N_ACD_E_PREEMPTED, - N_ACD_E_INVALID_ARGUMENT)) - return -NME_UNSPEC; - g_return_val_if_reached (-NME_UNSPEC); - } - - /* so, @error is either zero (indicating success) or one - * of the special status codes like N_ACD_E_*. In both cases, - * return the positive value here. */ - if (NM_IN_SET (error, _N_ACD_E_SUCCESS, - N_ACD_E_PREEMPTED, - N_ACD_E_INVALID_ARGUMENT)) - return error; - - g_return_val_if_reached (error); + if (error < 0) + return -nm_errno_native(error); + + if (always_fail) { + if (NM_IN_SET(error, N_ACD_E_PREEMPTED, N_ACD_E_INVALID_ARGUMENT)) + return -NME_UNSPEC; + g_return_val_if_reached(-NME_UNSPEC); + } + + /* so, @error is either zero (indicating success) or one + * of the special status codes like N_ACD_E_*. In both cases, + * return the positive value here. */ + if (NM_IN_SET(error, _N_ACD_E_SUCCESS, N_ACD_E_PREEMPTED, N_ACD_E_INVALID_ARGUMENT)) + return error; + + g_return_val_if_reached(error); } /*****************************************************************************/ @@ -150,164 +152,157 @@ acd_error_to_nmerr (int error, gboolean always_fail) * Returns: %TRUE on success, %FALSE if the address was already in the list */ gboolean -nm_acd_manager_add_address (NMAcdManager *self, in_addr_t address) +nm_acd_manager_add_address(NMAcdManager *self, in_addr_t address) { - AddressInfo *info; + AddressInfo *info; - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (self->state == STATE_INIT, FALSE); + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(self->state == STATE_INIT, FALSE); - if (g_hash_table_lookup (self->addresses, GUINT_TO_POINTER (address))) - return FALSE; + if (g_hash_table_lookup(self->addresses, GUINT_TO_POINTER(address))) + return FALSE; - info = g_slice_new0 (AddressInfo); - info->address = address; + info = g_slice_new0(AddressInfo); + info->address = address; - g_hash_table_insert (self->addresses, GUINT_TO_POINTER (address), info); + g_hash_table_insert(self->addresses, GUINT_TO_POINTER(address), info); - return TRUE; + return TRUE; } static gboolean -acd_event (int fd, - GIOCondition condition, - gpointer data) +acd_event(int fd, GIOCondition condition, gpointer data) { - NMAcdManager *self = data; - NAcdEvent *event; - AddressInfo *info; - gboolean emit_probe_terminated = FALSE; - char address_str[INET_ADDRSTRLEN]; - int r; - - if (n_acd_dispatch (self->acd)) - return G_SOURCE_CONTINUE; - - while ( !n_acd_pop_event (self->acd, &event) - && event) { - char to_string_buffer[ACD_EVENT_TO_STRING_BUF_SIZE]; - gs_free char *hwaddr_str = NULL; - gboolean check_probing_done = FALSE; - - switch (event->event) { - case N_ACD_EVENT_READY: - n_acd_probe_get_userdata (event->ready.probe, (void **) &info); - info->duplicate = FALSE; - if (self->state == STATE_ANNOUNCING) { - /* fake probe ended, start announcing */ - r = n_acd_probe_announce (info->probe, N_ACD_DEFEND_ONCE); - if (r) { - _LOGW ("couldn't announce address %s on interface '%s': %s", - _nm_utils_inet4_ntop (info->address, address_str), - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - } else { - _LOGD ("announcing address %s", - _nm_utils_inet4_ntop (info->address, address_str)); - } - } - check_probing_done = TRUE; - break; - case N_ACD_EVENT_USED: - n_acd_probe_get_userdata (event->used.probe, (void **) &info); - info->duplicate = TRUE; - check_probing_done = TRUE; - break; - case N_ACD_EVENT_DEFENDED: - n_acd_probe_get_userdata (event->defended.probe, (void **) &info); - _LOGD ("defended address %s from host %s", - _nm_utils_inet4_ntop (info->address, address_str), - (hwaddr_str = nm_utils_hwaddr_ntoa (event->defended.sender, - event->defended.n_sender))); - break; - case N_ACD_EVENT_CONFLICT: - n_acd_probe_get_userdata (event->conflict.probe, (void **) &info); - _LOGW ("conflict for address %s detected with host %s on interface '%s'", - _nm_utils_inet4_ntop (info->address, address_str), - (hwaddr_str = nm_utils_hwaddr_ntoa (event->defended.sender, - event->defended.n_sender)), - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex)); - break; - default: - _LOGD ("unhandled event '%s'", _acd_event_to_string_buf (event->event, to_string_buffer)); - break; - } - - if ( check_probing_done - && self->state == STATE_PROBING - && ++self->completed == g_hash_table_size (self->addresses)) { - self->state = STATE_PROBE_DONE; - emit_probe_terminated = TRUE; - } - } - - if (emit_probe_terminated) { - if (self->callbacks.probe_terminated_callback) { - self->callbacks.probe_terminated_callback (self, - self->user_data); - } - } - - return G_SOURCE_CONTINUE; + NMAcdManager *self = data; + NAcdEvent * event; + AddressInfo * info; + gboolean emit_probe_terminated = FALSE; + char address_str[INET_ADDRSTRLEN]; + int r; + + if (n_acd_dispatch(self->acd)) + return G_SOURCE_CONTINUE; + + while (!n_acd_pop_event(self->acd, &event) && event) { + char to_string_buffer[ACD_EVENT_TO_STRING_BUF_SIZE]; + gs_free char *hwaddr_str = NULL; + gboolean check_probing_done = FALSE; + + switch (event->event) { + case N_ACD_EVENT_READY: + n_acd_probe_get_userdata(event->ready.probe, (void **) &info); + info->duplicate = FALSE; + if (self->state == STATE_ANNOUNCING) { + /* fake probe ended, start announcing */ + r = n_acd_probe_announce(info->probe, N_ACD_DEFEND_ONCE); + if (r) { + _LOGW("couldn't announce address %s on interface '%s': %s", + _nm_utils_inet4_ntop(info->address, address_str), + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + } else { + _LOGD("announcing address %s", + _nm_utils_inet4_ntop(info->address, address_str)); + } + } + check_probing_done = TRUE; + break; + case N_ACD_EVENT_USED: + n_acd_probe_get_userdata(event->used.probe, (void **) &info); + info->duplicate = TRUE; + check_probing_done = TRUE; + break; + case N_ACD_EVENT_DEFENDED: + n_acd_probe_get_userdata(event->defended.probe, (void **) &info); + _LOGD("defended address %s from host %s", + _nm_utils_inet4_ntop(info->address, address_str), + (hwaddr_str = + nm_utils_hwaddr_ntoa(event->defended.sender, event->defended.n_sender))); + break; + case N_ACD_EVENT_CONFLICT: + n_acd_probe_get_userdata(event->conflict.probe, (void **) &info); + _LOGW("conflict for address %s detected with host %s on interface '%s'", + _nm_utils_inet4_ntop(info->address, address_str), + (hwaddr_str = + nm_utils_hwaddr_ntoa(event->defended.sender, event->defended.n_sender)), + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex)); + break; + default: + _LOGD("unhandled event '%s'", _acd_event_to_string_buf(event->event, to_string_buffer)); + break; + } + + if (check_probing_done && self->state == STATE_PROBING + && ++self->completed == g_hash_table_size(self->addresses)) { + self->state = STATE_PROBE_DONE; + emit_probe_terminated = TRUE; + } + } + + if (emit_probe_terminated) { + if (self->callbacks.probe_terminated_callback) { + self->callbacks.probe_terminated_callback(self, self->user_data); + } + } + + return G_SOURCE_CONTINUE; } static gboolean -acd_probe_add (NMAcdManager *self, - AddressInfo *info, - guint64 timeout) +acd_probe_add(NMAcdManager *self, AddressInfo *info, guint64 timeout) { - NAcdProbeConfig *probe_config; - int r; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - r = n_acd_probe_config_new (&probe_config); - if (r) { - _LOGW ("could not create probe config for %s on interface '%s': %s", - _nm_utils_inet4_ntop (info->address, sbuf), - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - return FALSE; - } - - n_acd_probe_config_set_ip (probe_config, (struct in_addr) { info->address }); - n_acd_probe_config_set_timeout (probe_config, timeout); - - r = n_acd_probe (self->acd, &info->probe, probe_config); - if (r) { - _LOGW ("could not start probe for %s on interface '%s': %s", - _nm_utils_inet4_ntop (info->address, sbuf), - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - n_acd_probe_config_free (probe_config); - return FALSE; - } - - n_acd_probe_set_userdata (info->probe, info); - n_acd_probe_config_free (probe_config); - - return TRUE; + NAcdProbeConfig *probe_config; + int r; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + r = n_acd_probe_config_new(&probe_config); + if (r) { + _LOGW("could not create probe config for %s on interface '%s': %s", + _nm_utils_inet4_ntop(info->address, sbuf), + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + return FALSE; + } + + n_acd_probe_config_set_ip(probe_config, (struct in_addr){info->address}); + n_acd_probe_config_set_timeout(probe_config, timeout); + + r = n_acd_probe(self->acd, &info->probe, probe_config); + if (r) { + _LOGW("could not start probe for %s on interface '%s': %s", + _nm_utils_inet4_ntop(info->address, sbuf), + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + n_acd_probe_config_free(probe_config); + return FALSE; + } + + n_acd_probe_set_userdata(info->probe, info); + n_acd_probe_config_free(probe_config); + + return TRUE; } static int -acd_init (NMAcdManager *self) +acd_init(NMAcdManager *self) { - NAcdConfig *config; - int r; + NAcdConfig *config; + int r; - if (self->acd) - return 0; + if (self->acd) + return 0; - r = n_acd_config_new (&config); - if (r) - return r; + r = n_acd_config_new(&config); + if (r) + return r; - n_acd_config_set_ifindex (config, self->ifindex); - n_acd_config_set_transport (config, N_ACD_TRANSPORT_ETHERNET); - n_acd_config_set_mac (config, self->hwaddr, ETH_ALEN); + n_acd_config_set_ifindex(config, self->ifindex); + n_acd_config_set_transport(config, N_ACD_TRANSPORT_ETHERNET); + n_acd_config_set_mac(config, self->hwaddr, ETH_ALEN); - r = n_acd_new (&self->acd, config); - n_acd_config_free (config); - return r; + r = n_acd_new(&self->acd, config); + n_acd_config_free(config); + return r; } /** @@ -322,44 +317,40 @@ acd_init (NMAcdManager *self) * Returns: 0 on success or a negative NetworkManager error code (NME_*). */ int -nm_acd_manager_start_probe (NMAcdManager *self, guint timeout) +nm_acd_manager_start_probe(NMAcdManager *self, guint timeout) { - GHashTableIter iter; - AddressInfo *info; - gboolean success = FALSE; - int fd, r; - - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (self->state == STATE_INIT, FALSE); - - r = acd_init (self); - if (r) { - _LOGW ("couldn't init ACD for probing on interface '%s': %s", - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - return acd_error_to_nmerr (r, TRUE); - } - - self->completed = 0; - - g_hash_table_iter_init (&iter, self->addresses); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) - success |= acd_probe_add (self, info, timeout); - - if (success) - self->state = STATE_PROBING; - - nm_assert (!self->event_source); - n_acd_get_fd (self->acd, &fd); - self->event_source = nm_g_unix_fd_source_new (fd, - G_IO_IN, - G_PRIORITY_DEFAULT, - acd_event, - self, - NULL); - g_source_attach (self->event_source, NULL); - - return success ? 0 : -NME_UNSPEC; + GHashTableIter iter; + AddressInfo * info; + gboolean success = FALSE; + int fd, r; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(self->state == STATE_INIT, FALSE); + + r = acd_init(self); + if (r) { + _LOGW("couldn't init ACD for probing on interface '%s': %s", + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + return acd_error_to_nmerr(r, TRUE); + } + + self->completed = 0; + + g_hash_table_iter_init(&iter, self->addresses); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info)) + success |= acd_probe_add(self, info, timeout); + + if (success) + self->state = STATE_PROBING; + + nm_assert(!self->event_source); + n_acd_get_fd(self->acd, &fd); + self->event_source = + nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL); + g_source_attach(self->event_source, NULL); + + return success ? 0 : -NME_UNSPEC; } /** @@ -373,17 +364,17 @@ nm_acd_manager_start_probe (NMAcdManager *self, guint timeout) * Returns: %TRUE if the address is not duplicate, %FALSE otherwise */ gboolean -nm_acd_manager_check_address (NMAcdManager *self, in_addr_t address) +nm_acd_manager_check_address(NMAcdManager *self, in_addr_t address) { - AddressInfo *info; + AddressInfo *info; - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (NM_IN_SET (self->state, STATE_INIT, STATE_PROBE_DONE), FALSE); + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(NM_IN_SET(self->state, STATE_INIT, STATE_PROBE_DONE), FALSE); - info = g_hash_table_lookup (self->addresses, GUINT_TO_POINTER (address)); - g_return_val_if_fail (info, FALSE); + info = g_hash_table_lookup(self->addresses, GUINT_TO_POINTER(address)); + g_return_val_if_fail(info, FALSE); - return !info->duplicate; + return !info->duplicate; } /** @@ -395,115 +386,110 @@ nm_acd_manager_check_address (NMAcdManager *self, in_addr_t address) * Returns: a negative NetworkManager error number or zero on success. */ int -nm_acd_manager_announce_addresses (NMAcdManager *self) +nm_acd_manager_announce_addresses(NMAcdManager *self) { - GHashTableIter iter; - AddressInfo *info; - int r; - int fd; - gboolean success = TRUE; - - r = acd_init (self); - if (r) { - _LOGW ("couldn't init ACD for announcing addresses on interface '%s': %s", - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - return acd_error_to_nmerr (r, TRUE); - } - - if (self->state == STATE_INIT) { - /* n-acd can't announce without probing, therefore let's - * start a fake probe with zero timeout and then perform - * the announcement. */ - g_hash_table_iter_init (&iter, self->addresses); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) { - if (!acd_probe_add (self, info, 0)) - success = FALSE; - } - self->state = STATE_ANNOUNCING; - } else if (self->state == STATE_ANNOUNCING) { - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - g_hash_table_iter_init (&iter, self->addresses); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) { - if (info->duplicate) - continue; - r = n_acd_probe_announce (info->probe, N_ACD_DEFEND_ONCE); - if (r) { - _LOGW ("couldn't announce address %s on interface '%s': %s", - _nm_utils_inet4_ntop (info->address, sbuf), - nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), - acd_error_to_string (r)); - success = FALSE; - } else - _LOGD ("announcing address %s", _nm_utils_inet4_ntop (info->address, sbuf)); - } - } - - if (!self->event_source) { - n_acd_get_fd (self->acd, &fd); - self->event_source = nm_g_unix_fd_source_new (fd, - G_IO_IN, - G_PRIORITY_DEFAULT, - acd_event, - self, - NULL); - g_source_attach (self->event_source, NULL); - } - - return success ? 0 : -NME_UNSPEC; + GHashTableIter iter; + AddressInfo * info; + int r; + int fd; + gboolean success = TRUE; + + r = acd_init(self); + if (r) { + _LOGW("couldn't init ACD for announcing addresses on interface '%s': %s", + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + return acd_error_to_nmerr(r, TRUE); + } + + if (self->state == STATE_INIT) { + /* n-acd can't announce without probing, therefore let's + * start a fake probe with zero timeout and then perform + * the announcement. */ + g_hash_table_iter_init(&iter, self->addresses); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info)) { + if (!acd_probe_add(self, info, 0)) + success = FALSE; + } + self->state = STATE_ANNOUNCING; + } else if (self->state == STATE_ANNOUNCING) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_hash_table_iter_init(&iter, self->addresses); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &info)) { + if (info->duplicate) + continue; + r = n_acd_probe_announce(info->probe, N_ACD_DEFEND_ONCE); + if (r) { + _LOGW("couldn't announce address %s on interface '%s': %s", + _nm_utils_inet4_ntop(info->address, sbuf), + nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), + acd_error_to_string(r)); + success = FALSE; + } else + _LOGD("announcing address %s", _nm_utils_inet4_ntop(info->address, sbuf)); + } + } + + if (!self->event_source) { + n_acd_get_fd(self->acd, &fd); + self->event_source = + nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL); + g_source_attach(self->event_source, NULL); + } + + return success ? 0 : -NME_UNSPEC; } static void -destroy_address_info (gpointer data) +destroy_address_info(gpointer data) { - AddressInfo *info = (AddressInfo *) data; + AddressInfo *info = (AddressInfo *) data; - n_acd_probe_free (info->probe); + n_acd_probe_free(info->probe); - g_slice_free (AddressInfo, info); + g_slice_free(AddressInfo, info); } /*****************************************************************************/ NMAcdManager * -nm_acd_manager_new (int ifindex, - const guint8 *hwaddr, - guint hwaddr_len, - const NMAcdCallbacks *callbacks, - gpointer user_data) +nm_acd_manager_new(int ifindex, + const guint8 * hwaddr, + guint hwaddr_len, + const NMAcdCallbacks *callbacks, + gpointer user_data) { - NMAcdManager *self; + NMAcdManager *self; - g_return_val_if_fail (ifindex > 0, NULL); - g_return_val_if_fail (hwaddr, NULL); - g_return_val_if_fail (hwaddr_len == ETH_ALEN, NULL); + g_return_val_if_fail(ifindex > 0, NULL); + g_return_val_if_fail(hwaddr, NULL); + g_return_val_if_fail(hwaddr_len == ETH_ALEN, NULL); - self = g_slice_new0 (NMAcdManager); + self = g_slice_new0(NMAcdManager); - if (callbacks) - self->callbacks = *callbacks; - self->user_data = user_data; + if (callbacks) + self->callbacks = *callbacks; + self->user_data = user_data; - self->addresses = g_hash_table_new_full (nm_direct_hash, NULL, - NULL, destroy_address_info); - self->state = STATE_INIT; - self->ifindex = ifindex; - memcpy (self->hwaddr, hwaddr, ETH_ALEN); - return self; + self->addresses = g_hash_table_new_full(nm_direct_hash, NULL, NULL, destroy_address_info); + self->state = STATE_INIT; + self->ifindex = ifindex; + memcpy(self->hwaddr, hwaddr, ETH_ALEN); + return self; } void -nm_acd_manager_free (NMAcdManager *self) +nm_acd_manager_free(NMAcdManager *self) { - g_return_if_fail (self); + g_return_if_fail(self); - if (self->callbacks.user_data_destroy) - self->callbacks.user_data_destroy (self->user_data); + if (self->callbacks.user_data_destroy) + self->callbacks.user_data_destroy(self->user_data); - nm_clear_pointer (&self->addresses, g_hash_table_destroy); - nm_clear_g_source_inst (&self->event_source); - nm_clear_pointer (&self->acd, n_acd_unref); + nm_clear_pointer(&self->addresses, g_hash_table_destroy); + nm_clear_g_source_inst(&self->event_source); + nm_clear_pointer(&self->acd, n_acd_unref); - g_slice_free (NMAcdManager, self); + g_slice_free(NMAcdManager, self); } diff --git a/src/devices/nm-acd-manager.h b/src/devices/nm-acd-manager.h index 4afe509d..21001c74 100644 --- a/src/devices/nm-acd-manager.h +++ b/src/devices/nm-acd-manager.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2018 Red Hat, Inc. */ @@ -11,25 +11,24 @@ typedef struct _NMAcdManager NMAcdManager; typedef struct { - void (*probe_terminated_callback) (NMAcdManager *self, - gpointer user_data); - GDestroyNotify user_data_destroy; + void (*probe_terminated_callback)(NMAcdManager *self, gpointer user_data); + GDestroyNotify user_data_destroy; } NMAcdCallbacks; -NMAcdManager *nm_acd_manager_new (int ifindex, - const guint8 *hwaddr, - guint hwaddr_len, - const NMAcdCallbacks *callbacks, - gpointer user_data); +NMAcdManager *nm_acd_manager_new(int ifindex, + const guint8 * hwaddr, + guint hwaddr_len, + const NMAcdCallbacks *callbacks, + gpointer user_data); -void nm_acd_manager_free (NMAcdManager *self); +void nm_acd_manager_free(NMAcdManager *self); -gboolean nm_acd_manager_add_address (NMAcdManager *self, in_addr_t address); -int nm_acd_manager_start_probe (NMAcdManager *self, guint timeout); -gboolean nm_acd_manager_check_address (NMAcdManager *self, in_addr_t address); -int nm_acd_manager_announce_addresses (NMAcdManager *self); +gboolean nm_acd_manager_add_address(NMAcdManager *self, in_addr_t address); +int nm_acd_manager_start_probe(NMAcdManager *self, guint timeout); +gboolean nm_acd_manager_check_address(NMAcdManager *self, in_addr_t address); +int nm_acd_manager_announce_addresses(NMAcdManager *self); -NM_AUTO_DEFINE_FCN0 (NMAcdManager *, _nm_auto_free_acdmgr, nm_acd_manager_free); -#define nm_auto_free_acdmgr nm_auto (_nm_auto_free_acdmgr) +NM_AUTO_DEFINE_FCN0(NMAcdManager *, _nm_auto_free_acdmgr, nm_acd_manager_free); +#define nm_auto_free_acdmgr nm_auto(_nm_auto_free_acdmgr) #endif /* __NM_ACD_MANAGER__ */ diff --git a/src/devices/nm-device-6lowpan.c b/src/devices/nm-device-6lowpan.c index 66ed5458..bf63fb73 100644 --- a/src/devices/nm-device-6lowpan.c +++ b/src/devices/nm-device-6lowpan.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -20,299 +20,320 @@ _LOG_DECLARE_SELF(NMDevice6Lowpan); /*****************************************************************************/ typedef struct { - gulong parent_state_id; + gulong parent_state_id; } NMDevice6LowpanPrivate; struct _NMDevice6Lowpan { - NMDevice parent; - NMDevice6LowpanPrivate _priv; + NMDevice parent; + NMDevice6LowpanPrivate _priv; }; struct _NMDevice6LowpanClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDevice6Lowpan, nm_device_6lowpan, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDevice6Lowpan, nm_device_6lowpan, NM_TYPE_DEVICE) -#define NM_DEVICE_6LOWPAN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDevice6Lowpan, NM_IS_DEVICE_6LOWPAN, NMDevice) +#define NM_DEVICE_6LOWPAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDevice6Lowpan, NM_IS_DEVICE_6LOWPAN, NMDevice) /*****************************************************************************/ static void -parent_state_changed (NMDevice *parent, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) +parent_state_changed(NMDevice * parent, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) { - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (user_data); + NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN(user_data); - nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); + nm_device_set_unmanaged_by_flags(NM_DEVICE(self), + NM_UNMANAGED_PARENT, + !nm_device_get_managed(parent, FALSE), + reason); } static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *device, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (device); - NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE (self); - - NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->parent_changed_notify (device, old_ifindex, old_parent, new_ifindex, new_parent); - - /* note that @self doesn't have to clear @parent_state_id on dispose, - * because NMDevice's dispose() will unset the parent, which in turn calls - * parent_changed_notify(). */ - nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); - - if (new_parent) { - priv->parent_state_id = g_signal_connect (new_parent, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (parent_state_changed), - device); - - /* Set parent-dependent unmanaged flag */ - nm_device_set_unmanaged_by_flags (device, - NM_UNMANAGED_PARENT, - !nm_device_get_managed (new_parent, FALSE), - NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); - } - - if (new_ifindex > 0) { - /* Recheck availability now that the parent has changed */ - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_PARENT_CHANGED, - NM_DEVICE_STATE_REASON_PARENT_CHANGED); - } + NMDevice6Lowpan * self = NM_DEVICE_6LOWPAN(device); + NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE(self); + + NM_DEVICE_CLASS(nm_device_6lowpan_parent_class) + ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent); + + /* note that @self doesn't have to clear @parent_state_id on dispose, + * because NMDevice's dispose() will unset the parent, which in turn calls + * parent_changed_notify(). */ + nm_clear_g_signal_handler(old_parent, &priv->parent_state_id); + + if (new_parent) { + priv->parent_state_id = g_signal_connect(new_parent, + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(parent_state_changed), + device); + + /* Set parent-dependent unmanaged flag */ + nm_device_set_unmanaged_by_flags(device, + NM_UNMANAGED_PARENT, + !nm_device_get_managed(new_parent, FALSE), + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); + } + + if (new_ifindex > 0) { + /* Recheck availability now that the parent has changed */ + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_PARENT_CHANGED, + NM_DEVICE_STATE_REASON_PARENT_CHANGED); + } } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMSetting6Lowpan *s_6lowpan; - int parent_ifindex; - int r; - - s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - g_return_val_if_fail (s_6lowpan, FALSE); - - parent_ifindex = parent ? nm_device_get_ifindex (parent) : 0; - - if (parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "6LoWPAN devices can not be created without a parent interface"); - g_return_val_if_fail (!parent, FALSE); - return FALSE; - } - - r = nm_platform_link_6lowpan_add (nm_device_get_platform (device), iface, parent_ifindex, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create 6lowpan interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - nm_device_parent_set_ifindex (device, parent_ifindex); - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMSetting6Lowpan *s_6lowpan; + int parent_ifindex; + int r; + + s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); + g_return_val_if_fail(s_6lowpan, FALSE); + + parent_ifindex = parent ? nm_device_get_ifindex(parent) : 0; + + if (parent_ifindex <= 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "6LoWPAN devices can not be created without a parent interface"); + g_return_val_if_fail(!parent, FALSE); + return FALSE; + } + + r = nm_platform_link_6lowpan_add(nm_device_get_platform(device), + iface, + parent_ifindex, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create 6lowpan interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + nm_device_parent_set_ifindex(device, parent_ifindex); + + return TRUE; } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (device); - int parent = 0; - int ifindex; + NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN(device); + int parent = 0; + int ifindex; - NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->link_changed (device, pllink); + NM_DEVICE_CLASS(nm_device_6lowpan_parent_class)->link_changed(device, pllink); - ifindex = nm_device_get_ifindex (device); - if (!nm_platform_link_6lowpan_get_properties (nm_device_get_platform (device), ifindex, &parent)) { - _LOGW (LOGD_DEVICE, "could not get 6lowpan properties"); - return; - } + ifindex = nm_device_get_ifindex(device); + if (!nm_platform_link_6lowpan_get_properties(nm_device_get_platform(device), + ifindex, + &parent)) { + _LOGW(LOGD_DEVICE, "could not get 6lowpan properties"); + return; + } - nm_device_parent_set_ifindex (device, parent); + nm_device_parent_set_ifindex(device, parent); } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - if (!nm_device_parent_get_device (device)) - return FALSE; - return NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->is_available (device, flags); + if (!nm_device_parent_get_device(device)) + return FALSE; + return NM_DEVICE_CLASS(nm_device_6lowpan_parent_class)->is_available(device, flags); } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSetting6Lowpan *s_6lowpan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_6LOWPAN_SETTING_NAME, - existing_connections, - NULL, - _("6LOWPAN connection"), - NULL, - NULL, - TRUE); - - s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - if (!s_6lowpan) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A '6lowpan' setting is required."); - return FALSE; - } - - /* If there's no 6LoWPAN interface, no parent, and no hardware address in the - * settings, then there's not enough information to complete the setting. - */ - if ( !nm_setting_6lowpan_get_parent (s_6lowpan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "The '6lowpan' setting had no interface name, parent, or hardware address."); - return FALSE; - } - - return TRUE; + NMSetting6Lowpan *s_6lowpan; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_6LOWPAN_SETTING_NAME, + existing_connections, + NULL, + _("6LOWPAN connection"), + NULL, + NULL, + TRUE); + + s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); + if (!s_6lowpan) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A '6lowpan' setting is required."); + return FALSE; + } + + /* If there's no 6LoWPAN interface, no parent, and no hardware address in the + * settings, then there's not enough information to complete the setting. + */ + if (!nm_setting_6lowpan_get_parent(s_6lowpan) + && !nm_device_match_parent_hwaddr(device, connection, TRUE)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "The '6lowpan' setting had no interface name, parent, or hardware address."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSetting6Lowpan *s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - - if (!s_6lowpan) { - s_6lowpan = (NMSetting6Lowpan *) nm_setting_6lowpan_new (); - nm_connection_add_setting (connection, (NMSetting *) s_6lowpan); - } - - g_object_set (s_6lowpan, - NM_SETTING_6LOWPAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_6lowpan_get_parent (s_6lowpan)), - NULL); + NMSetting6Lowpan *s_6lowpan = + NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); + + if (!s_6lowpan) { + s_6lowpan = (NMSetting6Lowpan *) nm_setting_6lowpan_new(); + nm_connection_add_setting(connection, (NMSetting *) s_6lowpan); + } + + g_object_set( + s_6lowpan, + NM_SETTING_6LOWPAN_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_6lowpan_get_parent(s_6lowpan)), + NULL); } /*****************************************************************************/ static void -nm_device_6lowpan_init (NMDevice6Lowpan *self) -{ -} +nm_device_6lowpan_init(NMDevice6Lowpan *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_6lowpan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_6LOWPAN, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Parent", "o", NM_DEVICE_PARENT), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_6LOWPAN, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), ), ), }; static void -nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass) +nm_device_6lowpan_class_init(NMDevice6LowpanClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_6lowpan); - - device_class->connection_type_supported = NM_SETTING_6LOWPAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_6LOWPAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_6LOWPAN); - - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->complete_connection = complete_connection; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->link_changed = link_changed; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - device_class->update_connection = update_connection; + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_6lowpan); + + device_class->connection_type_supported = NM_SETTING_6LOWPAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_6LOWPAN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_6LOWPAN); + + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->complete_connection = complete_connection; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->link_changed = link_changed; + device_class->is_available = is_available; + device_class->parent_changed_notify = parent_changed_notify; + device_class->update_connection = update_connection; } /*****************************************************************************/ -#define NM_TYPE_6LOWPAN_DEVICE_FACTORY (nm_6lowpan_device_factory_get_type ()) -#define NM_6LOWPAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_6LOWPAN_DEVICE_FACTORY, NM6LowpanDeviceFactory)) +#define NM_TYPE_6LOWPAN_DEVICE_FACTORY (nm_6lowpan_device_factory_get_type()) +#define NM_6LOWPAN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_6LOWPAN_DEVICE_FACTORY, NM6LowpanDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_6LOWPAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "6LoWPAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_6LOWPAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_6LOWPAN, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_6LOWPAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "6LoWPAN", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_6LOWPAN, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_6LOWPAN, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSetting6Lowpan *s_6lowpan; + NMSetting6Lowpan *s_6lowpan; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - g_assert (s_6lowpan); + s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); + g_assert(s_6lowpan); - return nm_setting_6lowpan_get_parent (s_6lowpan); + return nm_setting_6lowpan_get_parent(s_6lowpan); } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - NMSetting6Lowpan *s_6lowpan; - const char *ifname; + NMSetting6Lowpan *s_6lowpan; + const char * ifname; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - g_assert (s_6lowpan); + s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); + g_assert(s_6lowpan); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); - return g_strdup (ifname); + ifname = nm_connection_get_interface_name(connection); + return g_strdup(ifname); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (6LOWPAN, 6Lowpan, 6lowpan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_6LOWPAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_6LOWPAN_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + 6LOWPAN, + 6Lowpan, + 6lowpan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_6LOWPAN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_6LOWPAN_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-6lowpan.h b/src/devices/nm-device-6lowpan.h index 7d427235..60207d76 100644 --- a/src/devices/nm-device-6lowpan.h +++ b/src/devices/nm-device-6lowpan.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -8,16 +8,19 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_6LOWPAN (nm_device_6lowpan_get_type ()) -#define NM_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6Lowpan)) -#define NM_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) -#define NM_IS_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_6LOWPAN)) -#define NM_IS_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_6LOWPAN)) -#define NM_DEVICE_6LOWPAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) +#define NM_TYPE_DEVICE_6LOWPAN (nm_device_6lowpan_get_type()) +#define NM_DEVICE_6LOWPAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6Lowpan)) +#define NM_DEVICE_6LOWPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) +#define NM_IS_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_6LOWPAN)) +#define NM_IS_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_6LOWPAN)) +#define NM_DEVICE_6LOWPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) -typedef struct _NMDevice6Lowpan NMDevice6Lowpan; +typedef struct _NMDevice6Lowpan NMDevice6Lowpan; typedef struct _NMDevice6LowpanClass NMDevice6LowpanClass; -GType nm_device_6lowpan_get_type (void); +GType nm_device_6lowpan_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_6LOWPAN_H__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 71332ba3..3ef14a9e 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 - 2018 Red Hat, Inc. */ @@ -22,220 +22,255 @@ _LOG_DECLARE_SELF(NMDeviceBond); /*****************************************************************************/ +#define OPTIONS_APPLY_SUBSET \ + NM_SETTING_BOND_OPTION_MIIMON, NM_SETTING_BOND_OPTION_UPDELAY, \ + NM_SETTING_BOND_OPTION_DOWNDELAY, NM_SETTING_BOND_OPTION_ARP_INTERVAL, \ + NM_SETTING_BOND_OPTION_ARP_VALIDATE, NM_SETTING_BOND_OPTION_PRIMARY, \ + NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, \ + NM_SETTING_BOND_OPTION_AD_SELECT, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, \ + NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, \ + NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, NM_SETTING_BOND_OPTION_LACP_RATE, \ + NM_SETTING_BOND_OPTION_LP_INTERVAL, NM_SETTING_BOND_OPTION_MIN_LINKS, \ + NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, \ + NM_SETTING_BOND_OPTION_RESEND_IGMP, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, \ + NM_SETTING_BOND_OPTION_USE_CARRIER, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \ + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP + +#define OPTIONS_REAPPLY_SUBSET \ + NM_SETTING_BOND_OPTION_MIIMON, NM_SETTING_BOND_OPTION_UPDELAY, \ + NM_SETTING_BOND_OPTION_DOWNDELAY, NM_SETTING_BOND_OPTION_ARP_INTERVAL, \ + NM_SETTING_BOND_OPTION_ARP_VALIDATE, NM_SETTING_BOND_OPTION_PRIMARY, \ + NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, \ + NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, \ + NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, NM_SETTING_BOND_OPTION_LP_INTERVAL, \ + NM_SETTING_BOND_OPTION_MIN_LINKS, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, \ + NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, NM_SETTING_BOND_OPTION_RESEND_IGMP, \ + NM_SETTING_BOND_OPTION_USE_CARRIER, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \ + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP + +#define OPTIONS_REAPPLY_FULL \ + OPTIONS_REAPPLY_SUBSET, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, \ + NM_SETTING_BOND_OPTION_ARP_IP_TARGET + +/*****************************************************************************/ + struct _NMDeviceBond { - NMDevice parent; + NMDevice parent; }; struct _NMDeviceBondClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingBond *s_bond; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_BOND_SETTING_NAME, - existing_connections, - NULL, - _("Bond connection"), - "bond", - NULL, - TRUE); - - s_bond = nm_connection_get_setting_bond (connection); - if (!s_bond) { - s_bond = (NMSettingBond *) nm_setting_bond_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bond)); - } - - return TRUE; + NMSettingBond *s_bond; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_BOND_SETTING_NAME, + existing_connections, + NULL, + _("Bond connection"), + "bond", + NULL, + TRUE); + + s_bond = nm_connection_get_setting_bond(connection); + if (!s_bond) { + s_bond = (NMSettingBond *) nm_setting_bond_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bond)); + } + + return TRUE; } /*****************************************************************************/ static gboolean -_set_bond_attr (NMDevice *device, const char *attr, const char *value) +_set_bond_attr(NMDevice *device, const char *attr, const char *value) { - NMDeviceBond *self = NM_DEVICE_BOND (device); - int ifindex = nm_device_get_ifindex (device); - gboolean ret; - - ret = nm_platform_sysctl_master_set_option (nm_device_get_platform (device), - ifindex, - attr, - value); - if (!ret) - _LOGW (LOGD_PLATFORM, "failed to set bonding attribute '%s' to '%s'", attr, value); - return ret; + NMDeviceBond *self = NM_DEVICE_BOND(device); + int ifindex = nm_device_get_ifindex(device); + gboolean ret; + + ret = + nm_platform_sysctl_master_set_option(nm_device_get_platform(device), ifindex, attr, value); + if (!ret) + _LOGW(LOGD_PLATFORM, "failed to set bonding attribute '%s' to '%s'", attr, value); + return ret; } -#define _set_bond_attr_take(device, attr, value) \ - G_STMT_START { \ - gs_free char *_tmp = (value); \ - \ - _set_bond_attr (device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, _tmp); \ - } G_STMT_END +#define _set_bond_attr_take(device, attr, value) \ + G_STMT_START \ + { \ + gs_free char *_tmp = (value); \ + \ + _set_bond_attr(device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, _tmp); \ + } \ + G_STMT_END #define _set_bond_attr_printf(device, attr, fmt, ...) \ - _set_bond_attr_take ((device), (attr), g_strdup_printf (fmt, __VA_ARGS__)) + _set_bond_attr_take((device), (attr), g_strdup_printf(fmt, __VA_ARGS__)) static gboolean -ignore_option (NMSettingBond *s_bond, const char *option, const char *value) +ignore_option(NMSettingBond *s_bond, const char *option, const char *value) { - const char *defvalue; - - if (nm_streq0 (option, NM_SETTING_BOND_OPTION_MIIMON)) { - /* The default value for miimon, when missing in the setting, is - * 0 if arp_interval is != 0, and 100 otherwise. So, let's ignore - * miimon=0 (which means that miimon is disabled) and accept any - * other value. Adding miimon=100 does not cause any harm. - */ - defvalue = "0"; - } else - defvalue = nm_setting_bond_get_option_default (s_bond, option); - - return nm_streq0 (value, defvalue); + const char *defvalue; + + if (nm_streq0(option, NM_SETTING_BOND_OPTION_MIIMON)) { + /* The default value for miimon, when missing in the setting, is + * 0 if arp_interval is != 0, and 100 otherwise. So, let's ignore + * miimon=0 (which means that miimon is disabled) and accept any + * other value. Adding miimon=100 does not cause any harm. + */ + defvalue = "0"; + } else + defvalue = nm_setting_bond_get_option_default(s_bond, option); + + return nm_streq0(value, defvalue); } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSettingBond *s_bond = nm_connection_get_setting_bond (connection); - int ifindex = nm_device_get_ifindex (device); - NMBondMode mode = NM_BOND_MODE_UNKNOWN; - const char **options; - - if (!s_bond) { - s_bond = (NMSettingBond *) nm_setting_bond_new (); - nm_connection_add_setting (connection, (NMSetting *) s_bond); - } - - /* Read bond options from sysfs and update the Bond setting to match */ - options = nm_setting_bond_get_valid_options (s_bond); - for (; *options; options++) { - char *p; - gs_free char *value = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), - ifindex, - *options); - - if ( value - && _nm_setting_bond_get_option_type (s_bond, *options) == NM_BOND_OPTION_TYPE_BOTH) { - p = strchr (value, ' '); - if (p) - *p = '\0'; - } - - if (mode == NM_BOND_MODE_UNKNOWN) { - if (value && nm_streq (*options, NM_SETTING_BOND_OPTION_MODE)) - mode = _nm_setting_bond_mode_from_string (value); - if (mode == NM_BOND_MODE_UNKNOWN) - continue; - } - - if (!_nm_setting_bond_option_supported (*options, mode)) - continue; - - if ( value - && value[0] - && !ignore_option (s_bond, *options, value)) { - /* Replace " " with "," for arp_ip_targets from the kernel */ - if (strcmp (*options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET) == 0) { - for (p = value; *p; p++) { - if (*p == ' ') - *p = ','; - } - } - - nm_setting_bond_add_option (s_bond, *options, value); - } - } + NMSettingBond *s_bond = nm_connection_get_setting_bond(connection); + int ifindex = nm_device_get_ifindex(device); + NMBondMode mode = NM_BOND_MODE_UNKNOWN; + const char ** options; + + if (!s_bond) { + s_bond = (NMSettingBond *) nm_setting_bond_new(); + nm_connection_add_setting(connection, (NMSetting *) s_bond); + } + + /* Read bond options from sysfs and update the Bond setting to match */ + options = nm_setting_bond_get_valid_options(NULL); + for (; options[0]; options++) { + const char * option = options[0]; + gs_free char *value = NULL; + char * p; + + if (NM_IN_STRSET(option, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE)) + continue; + + value = + nm_platform_sysctl_master_get_option(nm_device_get_platform(device), ifindex, option); + + if (value && _nm_setting_bond_get_option_type(s_bond, option) == NM_BOND_OPTION_TYPE_BOTH) { + p = strchr(value, ' '); + if (p) + *p = '\0'; + } + + if (mode == NM_BOND_MODE_UNKNOWN) { + if (value && nm_streq(option, NM_SETTING_BOND_OPTION_MODE)) + mode = _nm_setting_bond_mode_from_string(value); + if (mode == NM_BOND_MODE_UNKNOWN) + continue; + } + + if (!_nm_setting_bond_option_supported(option, mode)) + continue; + + if (value && value[0] && !ignore_option(s_bond, option, value)) { + /* Replace " " with "," for arp_ip_targets from the kernel */ + if (nm_streq(option, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) { + for (p = value; *p; p++) { + if (*p == ' ') + *p = ','; + } + } + + nm_setting_bond_add_option(s_bond, option, value); + } + } } static gboolean -master_update_slave_connection (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - GError **error) +master_update_slave_connection(NMDevice * self, + NMDevice * slave, + NMConnection *connection, + GError ** error) { - g_object_set (nm_connection_get_setting_connection (connection), - NM_SETTING_CONNECTION_MASTER, nm_device_get_iface (self), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); - return TRUE; + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, + nm_device_get_iface(self), + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); + return TRUE; } static void -set_arp_targets (NMDevice *device, - const char *cur_arp_ip_target, - const char *new_arp_ip_target) +set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new_arp_ip_target) { - gs_unref_ptrarray GPtrArray *free_list = NULL; - gs_free const char **cur_strv = NULL; - gs_free const char **new_strv = NULL; - gsize cur_len; - gsize new_len; - gsize i; - gsize j; - - cur_strv = nm_utils_strsplit_set_full (cur_arp_ip_target, NM_ASCII_SPACES, NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); - new_strv = nm_utils_bond_option_arp_ip_targets_split (new_arp_ip_target); - - cur_len = NM_PTRARRAY_LEN (cur_strv); - new_len = NM_PTRARRAY_LEN (new_strv); - - if (new_len > 0) { - for (j = 0, i = 0; i < new_len; i++) { - const char *s; - in_addr_t a4; - - s = new_strv[i]; - if (nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &a4)) { - char sbuf[INET_ADDRSTRLEN]; - - _nm_utils_inet4_ntop (a4, sbuf); - if (!nm_streq (s, sbuf)) { - if (!free_list) - free_list = g_ptr_array_new_with_free_func (g_free); - s = g_strdup (sbuf); - g_ptr_array_add (free_list, (gpointer) s); - } - } - - if (nm_utils_strv_find_first ((char **) new_strv, i, s) < 0) - new_strv[j++] = s; - } - new_strv[j] = NULL; - new_len = j; - } - - if ( cur_len == 0 - && new_len == 0) - return; - - if (_nm_utils_strv_equal ((char **) cur_strv, (char **) new_strv)) - return; - - for (i = 0; i < cur_len; i++) - _set_bond_attr_printf (device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "-%s", cur_strv[i]); - for (i = 0; i < new_len; i++) - _set_bond_attr_printf (device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "+%s", new_strv[i]); + gs_unref_ptrarray GPtrArray *free_list = NULL; + gs_free const char ** cur_strv = NULL; + gs_free const char ** new_strv = NULL; + gsize cur_len; + gsize new_len; + gsize i; + gsize j; + + cur_strv = nm_utils_strsplit_set_full(cur_arp_ip_target, + NM_ASCII_SPACES, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + new_strv = nm_utils_bond_option_arp_ip_targets_split(new_arp_ip_target); + + cur_len = NM_PTRARRAY_LEN(cur_strv); + new_len = NM_PTRARRAY_LEN(new_strv); + + if (new_len > 0) { + for (j = 0, i = 0; i < new_len; i++) { + const char *s; + in_addr_t a4; + + s = new_strv[i]; + if (nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &a4)) { + char sbuf[INET_ADDRSTRLEN]; + + _nm_utils_inet4_ntop(a4, sbuf); + if (!nm_streq(s, sbuf)) { + if (!free_list) + free_list = g_ptr_array_new_with_free_func(g_free); + s = g_strdup(sbuf); + g_ptr_array_add(free_list, (gpointer) s); + } + } + + if (nm_utils_strv_find_first((char **) new_strv, i, s) < 0) + new_strv[j++] = s; + } + new_strv[j] = NULL; + new_len = j; + } + + if (cur_len == 0 && new_len == 0) + return; + + if (_nm_utils_strv_equal((char **) cur_strv, (char **) new_strv)) + return; + + for (i = 0; i < cur_len; i++) + _set_bond_attr_printf(device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "-%s", cur_strv[i]); + for (i = 0; i < new_len; i++) + _set_bond_attr_printf(device, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "+%s", new_strv[i]); } /* @@ -243,497 +278,362 @@ set_arp_targets (NMDevice *device, * the default value if no value was set. */ static void -set_bond_attr_or_default (NMDevice *device, - NMSettingBond *s_bond, - const char *opt) +set_bond_attr_or_default(NMDevice *device, NMSettingBond *s_bond, const char *opt) { - NMDeviceBond *self = NM_DEVICE_BOND (device); - const char *value; - - value = nm_setting_bond_get_option_or_default (s_bond, opt); - if (!value) { - if ( _LOGT_ENABLED (LOGD_BOND) - && nm_setting_bond_get_option_by_name (s_bond, opt)) - _LOGT (LOGD_BOND, "bond option '%s' not set as it conflicts with other options", opt); - return; - } - - _set_bond_attr (device, opt, value); -} + NMDeviceBond *self = NM_DEVICE_BOND(device); + const char * value; -static void -set_bond_attr_active_slave (NMDevice *device, NMSettingBond *s_bond) -{ - NMDeviceBond *self = NM_DEVICE_BOND (device); - const NMPlatformLink *plink; - const char *value; - const char *error_reason; - int ifindex; - - value = nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); - if (!value) - return; - - if (!nm_str_is_empty (value)) { - ifindex = nm_device_get_ifindex (device); - plink = nm_platform_link_get_by_ifname (nm_device_get_platform (device), value); - if (!plink) - error_reason = "does not exist"; - else if (plink->master != ifindex) - error_reason = "is not yet enslaved"; - else if (!NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP)) - error_reason = "is not up"; - else - error_reason = NULL; - - if (error_reason) { - _LOGT (LOGD_BOND, "bond option 'active_slave' not set as device \"%s\" %s", value, error_reason); - return; - } - } - - _set_bond_attr (device, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, value); + value = nm_setting_bond_get_option_or_default(s_bond, opt); + if (!value) { + if (_LOGT_ENABLED(LOGD_BOND) && nm_setting_bond_get_option_by_name(s_bond, opt)) + _LOGT(LOGD_BOND, "bond option '%s' not set as it conflicts with other options", opt); + return; + } + + _set_bond_attr(device, opt, value); } static void -set_bond_attrs_or_default (NMDevice *device, NMSettingBond *s_bond, const char *const *attr_v) +set_bond_attrs_or_default(NMDevice *device, NMSettingBond *s_bond, const char *const *attr_v) { - nm_assert (NM_IS_DEVICE (device)); - nm_assert (s_bond); - nm_assert (attr_v); + nm_assert(NM_IS_DEVICE(device)); + nm_assert(s_bond); + nm_assert(attr_v); - for ( ; *attr_v ; ++attr_v) - set_bond_attr_or_default (device, s_bond, *attr_v); + for (; *attr_v; ++attr_v) + set_bond_attr_or_default(device, s_bond, *attr_v); } static void -set_bond_arp_ip_targets (NMDevice *device, NMSettingBond *s_bond) +set_bond_arp_ip_targets(NMDevice *device, NMSettingBond *s_bond) { - int ifindex = nm_device_get_ifindex (device); - gs_free char *cur_arp_ip_target = NULL; - - /* ARP targets: clear and initialize the list */ - cur_arp_ip_target = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), - ifindex, - NM_SETTING_BOND_OPTION_ARP_IP_TARGET); - set_arp_targets (device, - cur_arp_ip_target, - nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)); + int ifindex = nm_device_get_ifindex(device); + gs_free char *cur_arp_ip_target = NULL; + + /* ARP targets: clear and initialize the list */ + cur_arp_ip_target = nm_platform_sysctl_master_get_option(nm_device_get_platform(device), + ifindex, + NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + set_arp_targets( + device, + cur_arp_ip_target, + nm_setting_bond_get_option_or_default(s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)); } static gboolean -apply_bonding_config (NMDeviceBond *self) +apply_bonding_config(NMDeviceBond *self) { - NMDevice *device = NM_DEVICE (self); - NMSettingBond *s_bond; - NMBondMode mode; - const char *mode_str; - - s_bond = nm_device_get_applied_setting (device, NM_TYPE_SETTING_BOND); - g_return_val_if_fail (s_bond, FALSE); - - mode_str = nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_MODE); - mode = _nm_setting_bond_mode_from_string (mode_str); - g_return_val_if_fail (mode != NM_BOND_MODE_UNKNOWN, FALSE); - - /* Set mode first, as some other options (e.g. arp_interval) are valid - * only for certain modes. - */ - set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MODE); - - set_bond_arp_ip_targets (device, s_bond); - set_bond_attr_active_slave (device, s_bond); - - set_bond_attrs_or_default (device, - s_bond, - NM_MAKE_STRV (NM_SETTING_BOND_OPTION_MIIMON, - NM_SETTING_BOND_OPTION_UPDELAY, - NM_SETTING_BOND_OPTION_DOWNDELAY, - NM_SETTING_BOND_OPTION_ARP_INTERVAL, - NM_SETTING_BOND_OPTION_ARP_VALIDATE, - NM_SETTING_BOND_OPTION_PRIMARY, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, - NM_SETTING_BOND_OPTION_AD_SELECT, - NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, - NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, - NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, - NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, - NM_SETTING_BOND_OPTION_LACP_RATE, - NM_SETTING_BOND_OPTION_LP_INTERVAL, - NM_SETTING_BOND_OPTION_MIN_LINKS, - NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, - NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, - NM_SETTING_BOND_OPTION_RESEND_IGMP, - NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, - NM_SETTING_BOND_OPTION_USE_CARRIER, - NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, - NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)); - return TRUE; + NMDevice * device = NM_DEVICE(self); + NMSettingBond *s_bond; + NMBondMode mode; + const char * mode_str; + + s_bond = nm_device_get_applied_setting(device, NM_TYPE_SETTING_BOND); + g_return_val_if_fail(s_bond, FALSE); + + mode_str = nm_setting_bond_get_option_or_default(s_bond, NM_SETTING_BOND_OPTION_MODE); + mode = _nm_setting_bond_mode_from_string(mode_str); + g_return_val_if_fail(mode != NM_BOND_MODE_UNKNOWN, FALSE); + + /* Set mode first, as some other options (e.g. arp_interval) are valid + * only for certain modes. + */ + set_bond_attr_or_default(device, s_bond, NM_SETTING_BOND_OPTION_MODE); + + set_bond_arp_ip_targets(device, s_bond); + + set_bond_attrs_or_default(device, s_bond, NM_MAKE_STRV(OPTIONS_APPLY_SUBSET)); + return TRUE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceBond *self = NM_DEVICE_BOND (device); - NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - - /* Interface must be down to set bond options */ - nm_device_take_down (device, TRUE); - if (!apply_bonding_config (self)) - ret = NM_ACT_STAGE_RETURN_FAILURE; - else { - if (!nm_device_hw_addr_set_cloned (device, - nm_device_get_applied_connection (device), - FALSE)) - ret = NM_ACT_STAGE_RETURN_FAILURE; - } - nm_device_bring_up (device, TRUE, NULL); - - return ret; + NMDeviceBond * self = NM_DEVICE_BOND(device); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + + /* Interface must be down to set bond options */ + nm_device_take_down(device, TRUE); + if (!apply_bonding_config(self)) + ret = NM_ACT_STAGE_RETURN_FAILURE; + else { + if (!nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE)) + ret = NM_ACT_STAGE_RETURN_FAILURE; + } + nm_device_bring_up(device, TRUE, NULL); + + return ret; } static gboolean -enslave_slave (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - NMDeviceBond *self = NM_DEVICE_BOND (device); - gboolean success = TRUE; - const char *slave_iface = nm_device_get_ip_iface (slave); - NMConnection *master_con; - - nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND); - - if (configure) { - nm_device_take_down (slave, TRUE); - success = nm_platform_link_enslave (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - nm_device_get_ip_ifindex (slave)); - nm_device_bring_up (slave, TRUE, NULL); - - if (!success) - return FALSE; - - _LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface); - - /* The active_slave option can be set only after the interface is enslaved */ - master_con = nm_device_get_applied_connection (device); - if (master_con) { - NMSettingBond *s_bond = nm_connection_get_setting_bond (master_con); - const char *active; - - if (s_bond) { - active = nm_setting_bond_get_option_or_default (s_bond, - NM_SETTING_BOND_OPTION_ACTIVE_SLAVE); - if (nm_streq0 (active, nm_device_get_iface (slave))) { - nm_platform_sysctl_master_set_option (nm_device_get_platform (device), - nm_device_get_ifindex (device), - NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, - active); - _LOGD (LOGD_BOND, "setting slave %s as active one for master %s", - active, nm_device_get_iface (device)); - } - } - } - } else - _LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface); - - return TRUE; -} + NMDeviceBond *self = NM_DEVICE_BOND(device); -static void -release_slave (NMDevice *device, - NMDevice *slave, - gboolean configure) -{ - NMDeviceBond *self = NM_DEVICE_BOND (device); - gboolean success; - gs_free char *address = NULL; - int ifindex_slave; - int ifindex; - - if (configure) { - ifindex = nm_device_get_ifindex (device); - if ( ifindex <= 0 - || !nm_platform_link_get (nm_device_get_platform (device), ifindex)) - configure = FALSE; - } - - ifindex_slave = nm_device_get_ip_ifindex (slave); - - if (ifindex_slave <= 0) - _LOGD (LOGD_BOND, "bond slave %s is already released", nm_device_get_ip_iface (slave)); - - if (configure) { - /* When the last slave is released the bond MAC will be set to a random - * value by kernel; remember the current one and restore it afterwards. - */ - address = g_strdup (nm_device_get_hw_address (device)); - - if (ifindex_slave > 0) { - success = nm_platform_link_release (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - ifindex_slave); - - if (success) { - _LOGI (LOGD_BOND, "released bond slave %s", - nm_device_get_ip_iface (slave)); - } else { - _LOGW (LOGD_BOND, "failed to release bond slave %s", - nm_device_get_ip_iface (slave)); - } - } - - nm_platform_process_events (nm_device_get_platform (device)); - if (nm_device_update_hw_address (device)) - nm_device_hw_addr_set (device, address, "restore", FALSE); - - /* Kernel bonding code "closes" the slave when releasing it, (which clears - * IFF_UP), so we must bring it back up here to ensure carrier changes and - * other state is noticed by the now-released slave. - */ - if (ifindex_slave > 0) { - if (!nm_device_bring_up (slave, TRUE, NULL)) - _LOGW (LOGD_BOND, "released bond slave could not be brought up."); - } - } else { - if (ifindex_slave > 0) { - _LOGI (LOGD_BOND, "bond slave %s was released", - nm_device_get_ip_iface (slave)); - } - } + nm_device_master_check_slave_physical_port(device, slave, LOGD_BOND); + + if (configure) { + gboolean success; + + nm_device_take_down(slave, TRUE); + success = nm_platform_link_enslave(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + nm_device_get_ip_ifindex(slave)); + nm_device_bring_up(slave, TRUE, NULL); + + if (!success) { + _LOGI(LOGD_BOND, "enslaved bond slave %s: failed", nm_device_get_ip_iface(slave)); + return FALSE; + } + + _LOGI(LOGD_BOND, "enslaved bond slave %s", nm_device_get_ip_iface(slave)); + } else + _LOGI(LOGD_BOND, "bond slave %s was enslaved", nm_device_get_ip_iface(slave)); + + return TRUE; } -static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +static void +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - const char *iface = nm_device_get_iface (device); - int r; - - g_assert (iface); - - r = nm_platform_link_bond_add (nm_device_get_platform (device), iface, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create bond interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - return TRUE; + NMDeviceBond *self = NM_DEVICE_BOND(device); + gboolean success; + gs_free char *address = NULL; + int ifindex_slave; + int ifindex; + + if (configure) { + ifindex = nm_device_get_ifindex(device); + if (ifindex <= 0 || !nm_platform_link_get(nm_device_get_platform(device), ifindex)) + configure = FALSE; + } + + ifindex_slave = nm_device_get_ip_ifindex(slave); + + if (ifindex_slave <= 0) + _LOGD(LOGD_BOND, "bond slave %s is already released", nm_device_get_ip_iface(slave)); + + if (configure) { + /* When the last slave is released the bond MAC will be set to a random + * value by kernel; remember the current one and restore it afterwards. + */ + address = g_strdup(nm_device_get_hw_address(device)); + + if (ifindex_slave > 0) { + success = nm_platform_link_release(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + ifindex_slave); + + if (success) { + _LOGI(LOGD_BOND, "released bond slave %s", nm_device_get_ip_iface(slave)); + } else { + _LOGW(LOGD_BOND, "failed to release bond slave %s", nm_device_get_ip_iface(slave)); + } + } + + nm_platform_process_events(nm_device_get_platform(device)); + if (nm_device_update_hw_address(device)) + nm_device_hw_addr_set(device, address, "restore", FALSE); + + /* Kernel bonding code "closes" the slave when releasing it, (which clears + * IFF_UP), so we must bring it back up here to ensure carrier changes and + * other state is noticed by the now-released slave. + */ + if (ifindex_slave > 0) { + if (!nm_device_bring_up(slave, TRUE, NULL)) + _LOGW(LOGD_BOND, "released bond slave could not be brought up."); + } + } else { + if (ifindex_slave > 0) { + _LOGI(LOGD_BOND, "bond slave %s was released", nm_device_get_ip_iface(slave)); + } + } } static gboolean -check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char **option_list; - - option_list = nm_setting_bond_get_valid_options (NULL); - - for (; *option_list; ++option_list) { - const char *name = *option_list; - - /* We support changes to these */ - if (NM_IN_STRSET (name, - NM_SETTING_BOND_OPTION_PRIMARY, - NM_SETTING_BOND_OPTION_MIIMON, - NM_SETTING_BOND_OPTION_UPDELAY, - NM_SETTING_BOND_OPTION_DOWNDELAY, - NM_SETTING_BOND_OPTION_ARP_INTERVAL, - NM_SETTING_BOND_OPTION_ARP_VALIDATE, - NM_SETTING_BOND_OPTION_PRIMARY, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, - NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, - NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, - NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, - NM_SETTING_BOND_OPTION_LP_INTERVAL, - NM_SETTING_BOND_OPTION_MIN_LINKS, - NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, - NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, - NM_SETTING_BOND_OPTION_RESEND_IGMP, - NM_SETTING_BOND_OPTION_USE_CARRIER, - NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, - NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)) { - continue; - } - - /* Reject any other changes */ - if (!nm_streq0 (nm_setting_bond_get_option_normalized (s_a, name), - nm_setting_bond_get_option_normalized (s_b, name))) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Can't reapply '%s' bond option", - name); - return FALSE; - } - } - - return TRUE; + const char *iface = nm_device_get_iface(device); + int r; + + g_assert(iface); + + r = nm_platform_link_bond_add(nm_device_get_platform(device), iface, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create bond interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + return TRUE; } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) { - NMDeviceClass *device_class; - - /* Only handle bond setting here, delegate other settings to parent class */ - if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) { - if (!nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_BOND_SETTING_NAME, - error, - NM_SETTING_BOND_OPTIONS)) - return FALSE; - - return check_changed_options (NM_SETTING_BOND (s_old), NM_SETTING_BOND (s_new), error); - } - - device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class); - return device_class->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); + NMDeviceClass *device_class; + + /* Only handle bond setting here, delegate other settings to parent class */ + if (nm_streq(setting_name, NM_SETTING_BOND_SETTING_NAME)) { + NMSettingBond *s_a = NM_SETTING_BOND(s_old); + NMSettingBond *s_b = NM_SETTING_BOND(s_new); + const char ** option_list; + + if (!nm_device_hash_check_invalid_keys(diffs, + NM_SETTING_BOND_SETTING_NAME, + error, + NM_SETTING_BOND_OPTIONS)) + return FALSE; + + option_list = nm_setting_bond_get_valid_options(NULL); + + for (; *option_list; ++option_list) { + const char *name = *option_list; + + /* We support changes to these */ + if (NM_IN_STRSET(name, OPTIONS_REAPPLY_FULL)) + continue; + + /* Reject any other changes */ + if (!nm_streq0(nm_setting_bond_get_option_normalized(s_a, name), + nm_setting_bond_get_option_normalized(s_b, name))) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply '%s' bond option", + name); + return FALSE; + } + } + + return TRUE; + } + + device_class = NM_DEVICE_CLASS(nm_device_bond_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) +reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new) { - NMDeviceBond *self = NM_DEVICE_BOND (device); - NMSettingBond *s_bond; - const char *value; - NMBondMode mode; - - NM_DEVICE_CLASS (nm_device_bond_parent_class)->reapply_connection (device, - con_old, - con_new); - - _LOGD (LOGD_BOND, "reapplying bond settings"); - s_bond = nm_connection_get_setting_bond (con_new); - g_return_if_fail (s_bond); - - value = nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_MODE); - mode = _nm_setting_bond_mode_from_string (value); - g_return_if_fail (mode != NM_BOND_MODE_UNKNOWN); - - /* Below we set only the bond options that kernel allows to modify - * while keeping the bond interface up */ - - set_bond_attr_active_slave (device, s_bond); - set_bond_arp_ip_targets (device, s_bond); - - set_bond_attrs_or_default (device, - s_bond, - NM_MAKE_STRV (NM_SETTING_BOND_OPTION_PRIMARY, - NM_SETTING_BOND_OPTION_MIIMON, - NM_SETTING_BOND_OPTION_UPDELAY, - NM_SETTING_BOND_OPTION_DOWNDELAY, - NM_SETTING_BOND_OPTION_ARP_INTERVAL, - NM_SETTING_BOND_OPTION_ARP_VALIDATE, - NM_SETTING_BOND_OPTION_PRIMARY, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM, - NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, - NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, - NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS, - NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, - NM_SETTING_BOND_OPTION_LP_INTERVAL, - NM_SETTING_BOND_OPTION_MIN_LINKS, - NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, - NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, - NM_SETTING_BOND_OPTION_RESEND_IGMP, - NM_SETTING_BOND_OPTION_USE_CARRIER, - NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, - NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)); + NMDeviceBond * self = NM_DEVICE_BOND(device); + NMSettingBond *s_bond; + const char * value; + NMBondMode mode; + + NM_DEVICE_CLASS(nm_device_bond_parent_class)->reapply_connection(device, con_old, con_new); + + _LOGD(LOGD_BOND, "reapplying bond settings"); + s_bond = nm_connection_get_setting_bond(con_new); + g_return_if_fail(s_bond); + + value = nm_setting_bond_get_option_or_default(s_bond, NM_SETTING_BOND_OPTION_MODE); + mode = _nm_setting_bond_mode_from_string(value); + g_return_if_fail(mode != NM_BOND_MODE_UNKNOWN); + + /* Below we set only the bond options that kernel allows to modify + * while keeping the bond interface up */ + + set_bond_arp_ip_targets(device, s_bond); + + set_bond_attrs_or_default(device, s_bond, NM_MAKE_STRV(OPTIONS_REAPPLY_SUBSET)); } /*****************************************************************************/ static void -nm_device_bond_init (NMDeviceBond * self) +nm_device_bond_init(NMDeviceBond *self) { - nm_assert (nm_device_is_master (NM_DEVICE (self))); + nm_assert(nm_device_is_master(NM_DEVICE(self))); } static const NMDBusInterfaceInfoExtended interface_info_device_bond = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_BOND, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_BOND, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", + "ao", + NM_DEVICE_SLAVES), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_bond_class_init (NMDeviceBondClass *klass) +nm_device_bond_class_init(NMDeviceBondClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bond); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_bond); - device_class->connection_type_supported = NM_SETTING_BOND_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_BOND_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_BOND); + device_class->connection_type_supported = NM_SETTING_BOND_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_BOND_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BOND); - device_class->is_master = TRUE; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->complete_connection = complete_connection; + device_class->is_master = TRUE; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; + device_class->update_connection = update_connection; + device_class->master_update_slave_connection = master_update_slave_connection; - device_class->create_and_realize = create_and_realize; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; + device_class->create_and_realize = create_and_realize; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = reapply_connection; } /*****************************************************************************/ -#define NM_TYPE_BOND_DEVICE_FACTORY (nm_bond_device_factory_get_type ()) -#define NM_BOND_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BOND_DEVICE_FACTORY, NMBondDeviceFactory)) +#define NM_TYPE_BOND_DEVICE_FACTORY (nm_bond_device_factory_get_type()) +#define NM_BOND_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_BOND_DEVICE_FACTORY, NMBondDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bonding", - NM_DEVICE_TYPE_DESC, "Bond", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_BOND, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_BOND, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_DRIVER, + "bonding", + NM_DEVICE_TYPE_DESC, + "Bond", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_BOND, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_BOND, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (BOND, Bond, bond, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BOND) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BOND_SETTING_NAME), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + BOND, + Bond, + bond, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_BOND) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_BOND_SETTING_NAME), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-bond.h b/src/devices/nm-device-bond.h index 7964f2a2..46be7c23 100644 --- a/src/devices/nm-device-bond.h +++ b/src/devices/nm-device-bond.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 Red Hat, Inc. */ @@ -8,16 +8,18 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type ()) -#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) -#define NM_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) -#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BOND)) -#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) -#define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type()) +#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) +#define NM_DEVICE_BOND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BOND)) +#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BOND)) +#define NM_DEVICE_BOND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) -typedef struct _NMDeviceBond NMDeviceBond; +typedef struct _NMDeviceBond NMDeviceBond; typedef struct _NMDeviceBondClass NMDeviceBondClass; -GType nm_device_bond_get_type (void); +GType nm_device_bond_get_type(void); #endif /* NM_DEVICE_BOND_H */ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 544e6614..3c27b349 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 - 2015 Red Hat, Inc. */ @@ -21,17 +21,17 @@ _LOG_DECLARE_SELF(NMDeviceBridge); /*****************************************************************************/ struct _NMDeviceBridge { - NMDevice parent; - GCancellable *bt_cancellable; - bool vlan_configured:1; - bool bt_registered:1; + NMDevice parent; + GCancellable *bt_cancellable; + bool vlan_configured : 1; + bool bt_registered : 1; }; struct _NMDeviceBridgeClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) /*****************************************************************************/ @@ -40,1100 +40,1192 @@ const NMBtVTableNetworkServer *nm_bt_vtable_network_server = NULL; /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - NMSettingBluetooth *s_bt; - - if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_available (device, connection, flags, specific_object, error)) - return FALSE; - - s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); - if (s_bt) { - const char *bdaddr; - - if (!nm_bt_vtable_network_server) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "bluetooth plugin not available to activate NAP profile"); - return FALSE; - } - - bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, - bdaddr, - ( self->bt_cancellable - || self->bt_registered) - ? device - : NULL)) { - if (bdaddr) - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no suitable NAP device \"%s\" available", bdaddr); - else - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no suitable NAP device available"); - return FALSE; - } - } - - return TRUE; + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + NMSettingBluetooth *s_bt; + + if (!NM_DEVICE_CLASS(nm_device_bridge_parent_class) + ->check_connection_available(device, connection, flags, specific_object, error)) + return FALSE; + + s_bt = _nm_connection_get_setting_bluetooth_for_nap(connection); + if (s_bt) { + const char *bdaddr; + + if (!nm_bt_vtable_network_server) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "bluetooth plugin not available to activate NAP profile"); + return FALSE; + } + + bdaddr = nm_setting_bluetooth_get_bdaddr(s_bt); + if (!nm_bt_vtable_network_server->is_available( + nm_bt_vtable_network_server, + bdaddr, + (self->bt_cancellable || self->bt_registered) ? device : NULL)) { + if (bdaddr) + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "no suitable NAP device \"%s\" available", + bdaddr); + else + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "no suitable NAP device available"); + return FALSE; + } + } + + return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingBridge *s_bridge; - const char *mac_address; - - if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if ( nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME) - && _nm_connection_get_setting_bluetooth_for_nap (connection)) { - s_bridge = nm_connection_get_setting_bridge (connection); - if (!s_bridge) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "missing bridge setting for bluetooth NAP profile"); - return FALSE; - } - - /* a bluetooth NAP connection is handled by the bridge. - * - * Proceed... */ - } else { - s_bridge = _nm_connection_check_main_setting (connection, NM_SETTING_BRIDGE_SETTING_NAME, error); - if (!s_bridge) - return FALSE; - } - - mac_address = nm_setting_bridge_get_mac_address (s_bridge); - if (mac_address && nm_device_is_real (device)) { - const char *hw_addr; - - hw_addr = nm_device_get_hw_address (device); - if (!hw_addr || !nm_utils_hwaddr_matches (hw_addr, -1, mac_address, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "mac address mismatches"); - return FALSE; - } - } - - return TRUE; + NMSettingBridge *s_bridge; + const char * mac_address; + + if (!NM_DEVICE_CLASS(nm_device_bridge_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_connection_is_type(connection, NM_SETTING_BLUETOOTH_SETTING_NAME) + && _nm_connection_get_setting_bluetooth_for_nap(connection)) { + s_bridge = nm_connection_get_setting_bridge(connection); + if (!s_bridge) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "missing bridge setting for bluetooth NAP profile"); + return FALSE; + } + + /* a bluetooth NAP connection is handled by the bridge. + * + * Proceed... */ + } else { + s_bridge = + _nm_connection_check_main_setting(connection, NM_SETTING_BRIDGE_SETTING_NAME, error); + if (!s_bridge) + return FALSE; + } + + mac_address = nm_setting_bridge_get_mac_address(s_bridge); + if (mac_address && nm_device_is_real(device)) { + const char *hw_addr; + + hw_addr = nm_device_get_hw_address(device); + if (!hw_addr || !nm_utils_hwaddr_matches(hw_addr, -1, mac_address, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "mac address mismatches"); + return FALSE; + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingBridge *s_bridge; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_BRIDGE_SETTING_NAME, - existing_connections, - NULL, - _("Bridge connection"), - "bridge", - NULL, - TRUE); - - s_bridge = nm_connection_get_setting_bridge (connection); - if (!s_bridge) { - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - } - - return TRUE; + NMSettingBridge *s_bridge; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_BRIDGE_SETTING_NAME, + existing_connections, + NULL, + _("Bridge connection"), + "bridge", + NULL, + TRUE); + + s_bridge = nm_connection_get_setting_bridge(connection); + if (!s_bridge) { + s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); + nm_connection_add_setting(connection, NM_SETTING(s_bridge)); + } + + return TRUE; } static void -from_sysfs_group_address (const char *value, GValue *out) +to_sysfs_group_address_sys(const char *group_address, NMEtherAddr *out_addr) { - if (!nm_utils_hwaddr_matches (value, -1, "01:80:C2:00:00:00", -1)) - g_value_set_string (out, value); + if (group_address == NULL) { + *out_addr = (NMEtherAddr) NM_ETHER_ADDR_INIT(NM_BRIDGE_GROUP_ADDRESS_DEF_BIN); + return; + } + if (!nm_utils_hwaddr_aton(group_address, out_addr, ETH_ALEN)) + nm_assert_not_reached(); +} + +static void +from_sysfs_group_address(const char *value, GValue *out) +{ + if (!nm_utils_hwaddr_matches(value, -1, NM_BRIDGE_GROUP_ADDRESS_DEF_STR, -1)) + g_value_set_string(out, value); } static const char * -to_sysfs_group_address (GValue *value) +to_sysfs_group_address(GValue *value) { - return g_value_get_string (value) ?: "01:80:C2:00:00:00"; + return g_value_get_string(value) ?: NM_BRIDGE_GROUP_ADDRESS_DEF_STR; +} + +static int +to_sysfs_vlan_protocol_sys(const char *value) +{ + if (nm_streq0(value, "802.1ad")) + return ETH_P_8021AD; + + return ETH_P_8021Q; } static void -from_sysfs_vlan_protocol (const char *value, GValue *out) +from_sysfs_vlan_protocol(const char *value, GValue *out) { - switch (_nm_utils_ascii_str_to_uint64 (value, 16, 0, G_MAXUINT, -1)) { - case ETH_P_8021Q: - /* default value */ - break; - case ETH_P_8021AD: - g_value_set_string (out, "802.1ad"); - break; - } + switch (_nm_utils_ascii_str_to_uint64(value, 16, 0, G_MAXUINT, -1)) { + case ETH_P_8021Q: + /* default value */ + break; + case ETH_P_8021AD: + g_value_set_string(out, "802.1ad"); + break; + } } static const char * -to_sysfs_vlan_protocol (GValue *value) +to_sysfs_vlan_protocol(GValue *value) { - const char *str = g_value_get_string (value); + const char *str = g_value_get_string(value); + + if (nm_streq0(str, "802.1ad")) { + G_STATIC_ASSERT_EXPR(ETH_P_8021AD == 0x88A8); + return "0x88A8"; + } - if (nm_streq0 (str, "802.1ad")) { - G_STATIC_ASSERT_EXPR (ETH_P_8021AD == 0x88A8); - return "0x88A8"; - } + G_STATIC_ASSERT_EXPR(ETH_P_8021Q == 0x8100); + return "0x8100"; +} - G_STATIC_ASSERT_EXPR (ETH_P_8021Q == 0x8100); - return "0x8100"; +static int +to_sysfs_multicast_router_sys(const char *value) +{ + if (nm_streq0(value, "disabled")) + return 0; + if (nm_streq0(value, "auto")) + return 1; + if (nm_streq0(value, "enabled")) + return 2; + + return 1; } static const char * -to_sysfs_multicast_router (GValue *value) +to_sysfs_multicast_router(GValue *value) { - const char *str = g_value_get_string (value); + const char *str = g_value_get_string(value); - if (nm_streq0 (str, "disabled")) - return "0"; - if (nm_streq0 (str, "auto")) - return "1"; - if (nm_streq0 (str, "enabled")) - return "2"; + if (nm_streq0(str, "disabled")) + return "0"; + if (nm_streq0(str, "auto")) + return "1"; + if (nm_streq0(str, "enabled")) + return "2"; - return "1"; + return "1"; } static void -from_sysfs_multicast_router (const char *value, GValue *out) +from_sysfs_multicast_router(const char *value, GValue *out) { - switch (_nm_utils_ascii_str_to_uint64 (value, 10, 0, G_MAXUINT, -1)) { - case 0: - g_value_set_string (out, "disabled"); - break; - case 2: - g_value_set_string (out, "enabled"); - break; - case 1: - default: - /* default value */ - break; - } + switch (_nm_utils_ascii_str_to_uint64(value, 10, 0, G_MAXUINT, -1)) { + case 0: + g_value_set_string(out, "disabled"); + break; + case 2: + g_value_set_string(out, "enabled"); + break; + case 1: + default: + /* default value */ + break; + } } /*****************************************************************************/ +#define _DEFAULT_IF_ZERO(val, def_val) \ + ({ \ + typeof(val) _val = (val); \ + typeof(val) _def_val = (def_val); \ + \ + (_val == 0) ? _def_val : _val; \ + }) typedef struct { - const char *name; - const char *sysname; - const char *(*to_sysfs) (GValue *value); - void (*from_sysfs) (const char *value, GValue *out); - guint64 nm_min; - guint64 nm_max; - guint64 nm_default; - bool default_if_zero; - bool user_hz_compensate; - bool only_with_stp; + const char *name; + const char *sysname; + const char *(*to_sysfs)(GValue *value); + void (*from_sysfs)(const char *value, GValue *out); + guint64 nm_min; + guint64 nm_max; + guint64 nm_default; + bool default_if_zero; + bool user_hz_compensate; + bool only_with_stp; } Option; #define OPTION(_name, _sysname, ...) \ - { \ - .name = ""_name"", \ - .sysname = ""_sysname"", \ - __VA_ARGS__ \ - } + { \ + .name = ""_name \ + "", \ + .sysname = ""_sysname \ + "", \ + __VA_ARGS__ \ + } -#define OPTION_TYPE_INT(min, max, def) \ - .nm_min = (min), .nm_max = (max), .nm_default = (def) +#define OPTION_TYPE_INT(min, max, def) .nm_min = (min), .nm_max = (max), .nm_default = (def) -#define OPTION_TYPE_BOOL(def) \ - OPTION_TYPE_INT (FALSE, TRUE, def) +#define OPTION_TYPE_BOOL(def) OPTION_TYPE_INT(FALSE, TRUE, def) -#define OPTION_TYPE_TOFROM(to, fro) \ - .to_sysfs = (to), .from_sysfs = (fro) +#define OPTION_TYPE_TOFROM(to, fro) .to_sysfs = (to), .from_sysfs = (fro) static const Option master_options[] = { - OPTION (NM_SETTING_BRIDGE_STP, /* this must stay as the first item */ - "stp_state", - OPTION_TYPE_BOOL (NM_BRIDGE_STP_DEF), - ), - OPTION (NM_SETTING_BRIDGE_PRIORITY, - "priority", - OPTION_TYPE_INT (NM_BRIDGE_PRIORITY_MIN, NM_BRIDGE_PRIORITY_MAX, NM_BRIDGE_PRIORITY_DEF), - .default_if_zero = TRUE, - .only_with_stp = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_FORWARD_DELAY, - "forward_delay", - OPTION_TYPE_INT (NM_BRIDGE_FORWARD_DELAY_MIN, NM_BRIDGE_FORWARD_DELAY_MAX, NM_BRIDGE_FORWARD_DELAY_DEF), - .default_if_zero = TRUE, - .user_hz_compensate = TRUE, - .only_with_stp = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_HELLO_TIME, - "hello_time", - OPTION_TYPE_INT (NM_BRIDGE_HELLO_TIME_MIN, NM_BRIDGE_HELLO_TIME_MAX, NM_BRIDGE_HELLO_TIME_DEF), - .default_if_zero = TRUE, - .user_hz_compensate = TRUE, - .only_with_stp = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_MAX_AGE, - "max_age", - OPTION_TYPE_INT (NM_BRIDGE_MAX_AGE_MIN, NM_BRIDGE_MAX_AGE_MAX, NM_BRIDGE_MAX_AGE_DEF), - .default_if_zero = TRUE, - .user_hz_compensate = TRUE, - .only_with_stp = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_AGEING_TIME, - "ageing_time", - OPTION_TYPE_INT (NM_BRIDGE_AGEING_TIME_MIN, NM_BRIDGE_AGEING_TIME_MAX, NM_BRIDGE_AGEING_TIME_DEF), - .default_if_zero = TRUE, - .user_hz_compensate = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, - "group_fwd_mask", - OPTION_TYPE_INT (0, 0xFFFF, 0), - .default_if_zero = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, - "hash_max", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_HASH_MAX_MIN, NM_BRIDGE_MULTICAST_HASH_MAX_MAX, NM_BRIDGE_MULTICAST_HASH_MAX_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, - "multicast_last_member_count", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MIN, NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MAX, NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, - "multicast_last_member_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MIN, NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MAX, NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, - "multicast_membership_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MIN, NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MAX, NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_QUERIER, - "multicast_querier", - OPTION_TYPE_BOOL (NM_BRIDGE_MULTICAST_QUERIER_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, - "multicast_querier_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MIN, NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MAX, NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, - "multicast_query_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MIN, NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MAX, NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, - "multicast_query_response_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MIN, NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MAX, NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, - "multicast_query_use_ifaddr", - OPTION_TYPE_BOOL (NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_SNOOPING, - "multicast_snooping", - OPTION_TYPE_BOOL (NM_BRIDGE_MULTICAST_SNOOPING_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_ROUTER, - "multicast_router", - OPTION_TYPE_TOFROM (to_sysfs_multicast_router, from_sysfs_multicast_router), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, - "multicast_startup_query_count", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MIN, NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MAX, NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF), - ), - OPTION (NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, - "multicast_startup_query_interval", - OPTION_TYPE_INT (NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MIN, NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MAX, NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF), - ), - OPTION (NM_SETTING_BRIDGE_GROUP_ADDRESS, - "group_addr", - OPTION_TYPE_TOFROM (to_sysfs_group_address, from_sysfs_group_address), - ), - OPTION (NM_SETTING_BRIDGE_VLAN_PROTOCOL, - "vlan_protocol", - OPTION_TYPE_TOFROM (to_sysfs_vlan_protocol, from_sysfs_vlan_protocol), - ), - OPTION (NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, - "vlan_stats_enabled", - OPTION_TYPE_BOOL (NM_BRIDGE_VLAN_STATS_ENABLED_DEF) - ), - { 0, } -}; + OPTION(NM_SETTING_BRIDGE_STP, /* this must stay as the first item */ + "stp_state", + OPTION_TYPE_BOOL(NM_BRIDGE_STP_DEF), ), + OPTION(NM_SETTING_BRIDGE_PRIORITY, + "priority", + OPTION_TYPE_INT(NM_BRIDGE_PRIORITY_MIN, NM_BRIDGE_PRIORITY_MAX, NM_BRIDGE_PRIORITY_DEF), + .default_if_zero = TRUE, + .only_with_stp = TRUE, ), + OPTION(NM_SETTING_BRIDGE_FORWARD_DELAY, + "forward_delay", + OPTION_TYPE_INT(NM_BRIDGE_FORWARD_DELAY_MIN, + NM_BRIDGE_FORWARD_DELAY_MAX, + NM_BRIDGE_FORWARD_DELAY_DEF), + .default_if_zero = TRUE, + .user_hz_compensate = TRUE, + .only_with_stp = TRUE, ), + OPTION(NM_SETTING_BRIDGE_HELLO_TIME, + "hello_time", + OPTION_TYPE_INT(NM_BRIDGE_HELLO_TIME_MIN, + NM_BRIDGE_HELLO_TIME_MAX, + NM_BRIDGE_HELLO_TIME_DEF), + .default_if_zero = TRUE, + .user_hz_compensate = TRUE, + .only_with_stp = TRUE, ), + OPTION(NM_SETTING_BRIDGE_MAX_AGE, + "max_age", + OPTION_TYPE_INT(NM_BRIDGE_MAX_AGE_MIN, NM_BRIDGE_MAX_AGE_MAX, NM_BRIDGE_MAX_AGE_DEF), + .default_if_zero = TRUE, + .user_hz_compensate = TRUE, + .only_with_stp = TRUE, ), + OPTION(NM_SETTING_BRIDGE_AGEING_TIME, + "ageing_time", + OPTION_TYPE_INT(NM_BRIDGE_AGEING_TIME_MIN, + NM_BRIDGE_AGEING_TIME_MAX, + NM_BRIDGE_AGEING_TIME_DEF), + .default_if_zero = TRUE, + .user_hz_compensate = TRUE, ), + OPTION(NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, "group_fwd_mask", OPTION_TYPE_INT(0, 0xFFFF, 0), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, + "hash_max", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_HASH_MAX_MIN, + NM_BRIDGE_MULTICAST_HASH_MAX_MAX, + NM_BRIDGE_MULTICAST_HASH_MAX_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT, + "multicast_last_member_count", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MIN, + NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_MAX, + NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL, + "multicast_last_member_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL, + "multicast_membership_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_QUERIER, + "multicast_querier", + OPTION_TYPE_BOOL(NM_BRIDGE_MULTICAST_QUERIER_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL, + "multicast_querier_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL, + "multicast_query_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERY_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL, + "multicast_query_response_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, + "multicast_query_use_ifaddr", + OPTION_TYPE_BOOL(NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_SNOOPING, + "multicast_snooping", + OPTION_TYPE_BOOL(NM_BRIDGE_MULTICAST_SNOOPING_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_ROUTER, + "multicast_router", + OPTION_TYPE_TOFROM(to_sysfs_multicast_router, from_sysfs_multicast_router), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT, + "multicast_startup_query_count", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MIN, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_MAX, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF), ), + OPTION(NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL, + "multicast_startup_query_interval", + OPTION_TYPE_INT(NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MIN, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_MAX, + NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF), ), + OPTION(NM_SETTING_BRIDGE_GROUP_ADDRESS, + "group_addr", + OPTION_TYPE_TOFROM(to_sysfs_group_address, from_sysfs_group_address), ), + OPTION(NM_SETTING_BRIDGE_VLAN_PROTOCOL, + "vlan_protocol", + OPTION_TYPE_TOFROM(to_sysfs_vlan_protocol, from_sysfs_vlan_protocol), ), + OPTION(NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, + "vlan_stats_enabled", + OPTION_TYPE_BOOL(NM_BRIDGE_VLAN_STATS_ENABLED_DEF)), + { + 0, + }}; static const Option slave_options[] = { - OPTION (NM_SETTING_BRIDGE_PORT_PRIORITY, - "priority", - OPTION_TYPE_INT (NM_BRIDGE_PORT_PRIORITY_MIN, NM_BRIDGE_PORT_PRIORITY_MAX, NM_BRIDGE_PORT_PRIORITY_DEF), - .default_if_zero = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_PORT_PATH_COST, - "path_cost", - OPTION_TYPE_INT (NM_BRIDGE_PORT_PATH_COST_MIN, NM_BRIDGE_PORT_PATH_COST_MAX, NM_BRIDGE_PORT_PATH_COST_DEF), - .default_if_zero = TRUE, - ), - OPTION (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, - "hairpin_mode", - OPTION_TYPE_BOOL (FALSE), - ), - { 0 } -}; + OPTION(NM_SETTING_BRIDGE_PORT_PRIORITY, + "priority", + OPTION_TYPE_INT(NM_BRIDGE_PORT_PRIORITY_MIN, + NM_BRIDGE_PORT_PRIORITY_MAX, + NM_BRIDGE_PORT_PRIORITY_DEF), + .default_if_zero = TRUE, ), + OPTION(NM_SETTING_BRIDGE_PORT_PATH_COST, + "path_cost", + OPTION_TYPE_INT(NM_BRIDGE_PORT_PATH_COST_MIN, + NM_BRIDGE_PORT_PATH_COST_MAX, + NM_BRIDGE_PORT_PATH_COST_DEF), + .default_if_zero = TRUE, ), + OPTION(NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin_mode", OPTION_TYPE_BOOL(FALSE), ), + {0}}; static void -commit_option (NMDevice *device, NMSetting *setting, const Option *option, gboolean slave) +commit_option(NMDevice *device, NMSetting *setting, const Option *option, gboolean slave) { - int ifindex = nm_device_get_ifindex (device); - nm_auto_unset_gvalue GValue val = G_VALUE_INIT; - GParamSpec *pspec; - const char *value; - char value_buf[100]; - - if (slave) - nm_assert (NM_IS_SETTING_BRIDGE_PORT (setting)); - else - nm_assert (NM_IS_SETTING_BRIDGE (setting)); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), option->name); - nm_assert (pspec); - - g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property ((GObject *) setting, option->name, &val); - - if (option->to_sysfs) { - value = option->to_sysfs (&val); - goto out; - } - - switch (pspec->value_type) { - case G_TYPE_BOOLEAN: - value = g_value_get_boolean (&val) ? "1" : "0"; - break; - case G_TYPE_UINT64: - case G_TYPE_UINT: { - guint64 uval; - - if (pspec->value_type == G_TYPE_UINT64) - uval = g_value_get_uint64 (&val); - else - uval = (guint) g_value_get_uint (&val); - - /* zero means "unspecified" for some NM properties but isn't in the - * allowed kernel range, so reset the property to the default value. - */ - if ( option->default_if_zero - && uval == 0) { - if (pspec->value_type == G_TYPE_UINT64) - uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT64 (pspec); - else - uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT (pspec); - } - - /* Linux kernel bridge interfaces use 'centiseconds' for time-based values. - * In reality it's not centiseconds, but depends on HZ and USER_HZ, which - * is almost always works out to be a multiplier of 100, so we can assume - * centiseconds. See clock_t_to_jiffies(). - */ - if (option->user_hz_compensate) - uval *= 100; - - if (pspec->value_type == G_TYPE_UINT64) - nm_sprintf_buf (value_buf, "%"G_GUINT64_FORMAT, uval); - else - nm_sprintf_buf (value_buf, "%u", (guint) uval); - - value = value_buf; - } - break; - case G_TYPE_STRING: - value = g_value_get_string (&val); - break; - default: - nm_assert_not_reached (); - value = NULL; - break; - } + int ifindex = nm_device_get_ifindex(device); + nm_auto_unset_gvalue GValue val = G_VALUE_INIT; + GParamSpec * pspec; + const char * value; + char value_buf[100]; + + if (slave) + nm_assert(NM_IS_SETTING_BRIDGE_PORT(setting)); + else + nm_assert(NM_IS_SETTING_BRIDGE(setting)); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), option->name); + nm_assert(pspec); + + g_value_init(&val, G_PARAM_SPEC_VALUE_TYPE(pspec)); + g_object_get_property((GObject *) setting, option->name, &val); + + if (option->to_sysfs) { + value = option->to_sysfs(&val); + goto out; + } + + switch (pspec->value_type) { + case G_TYPE_BOOLEAN: + value = g_value_get_boolean(&val) ? "1" : "0"; + break; + case G_TYPE_UINT64: + case G_TYPE_UINT: + { + guint64 uval; + + if (pspec->value_type == G_TYPE_UINT64) + uval = g_value_get_uint64(&val); + else + uval = (guint) g_value_get_uint(&val); + + /* zero means "unspecified" for some NM properties but isn't in the + * allowed kernel range, so reset the property to the default value. + */ + if (option->default_if_zero && uval == 0) { + if (pspec->value_type == G_TYPE_UINT64) + uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT64(pspec); + else + uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT(pspec); + } + + /* Linux kernel bridge interfaces use 'centiseconds' for time-based values. + * In reality it's not centiseconds, but depends on HZ and USER_HZ, which + * is almost always works out to be a multiplier of 100, so we can assume + * centiseconds. See clock_t_to_jiffies(). + */ + if (option->user_hz_compensate) + uval *= 100; + + if (pspec->value_type == G_TYPE_UINT64) + nm_sprintf_buf(value_buf, "%" G_GUINT64_FORMAT, uval); + else + nm_sprintf_buf(value_buf, "%u", (guint) uval); + + value = value_buf; + } break; + case G_TYPE_STRING: + value = g_value_get_string(&val); + break; + default: + nm_assert_not_reached(); + value = NULL; + break; + } out: - if (!value) - return; - - if (slave) { - nm_platform_sysctl_slave_set_option (nm_device_get_platform (device), - ifindex, - option->sysname, - value); - } else { - nm_platform_sysctl_master_set_option (nm_device_get_platform (device), - ifindex, - option->sysname, - value); - } + if (!value) + return; + + if (slave) { + nm_platform_sysctl_slave_set_option(nm_device_get_platform(device), + ifindex, + option->sysname, + value); + } else { + nm_platform_sysctl_master_set_option(nm_device_get_platform(device), + ifindex, + option->sysname, + value); + } } static const NMPlatformBridgeVlan ** -setting_vlans_to_platform (GPtrArray *array) +setting_vlans_to_platform(GPtrArray *array) { - NMPlatformBridgeVlan **arr; - NMPlatformBridgeVlan *p_data; - guint i; - - if (!array || !array->len) - return NULL; - - G_STATIC_ASSERT_EXPR (_nm_alignof (NMPlatformBridgeVlan *) >= _nm_alignof (NMPlatformBridgeVlan)); - arr = g_malloc ( (sizeof (NMPlatformBridgeVlan *) * (array->len + 1)) - + (sizeof (NMPlatformBridgeVlan ) * (array->len ))); - p_data = (NMPlatformBridgeVlan *) &arr[array->len + 1]; - - for (i = 0; i < array->len; i++) { - NMBridgeVlan *vlan = array->pdata[i]; - guint16 vid_start, vid_end; - - nm_bridge_vlan_get_vid_range (vlan, &vid_start, &vid_end); - - p_data[i] = (NMPlatformBridgeVlan) { - .vid_start = vid_start, - .vid_end = vid_end, - .pvid = nm_bridge_vlan_is_pvid (vlan), - .untagged = nm_bridge_vlan_is_untagged (vlan), - }; - arr[i] = &p_data[i]; - } - arr[i] = NULL; - return (const NMPlatformBridgeVlan **) arr; + NMPlatformBridgeVlan **arr; + NMPlatformBridgeVlan * p_data; + guint i; + + if (!array || !array->len) + return NULL; + + G_STATIC_ASSERT_EXPR(_nm_alignof(NMPlatformBridgeVlan *) >= _nm_alignof(NMPlatformBridgeVlan)); + arr = g_malloc((sizeof(NMPlatformBridgeVlan *) * (array->len + 1)) + + (sizeof(NMPlatformBridgeVlan) * (array->len))); + p_data = (NMPlatformBridgeVlan *) &arr[array->len + 1]; + + for (i = 0; i < array->len; i++) { + NMBridgeVlan *vlan = array->pdata[i]; + guint16 vid_start, vid_end; + + nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); + + p_data[i] = (NMPlatformBridgeVlan){ + .vid_start = vid_start, + .vid_end = vid_end, + .pvid = nm_bridge_vlan_is_pvid(vlan), + .untagged = nm_bridge_vlan_is_untagged(vlan), + }; + arr[i] = &p_data[i]; + } + arr[i] = NULL; + return (const NMPlatformBridgeVlan **) arr; } static void -commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) +commit_slave_options(NMDevice *device, NMSettingBridgePort *setting) { - const Option *option; - NMSetting *s; - gs_unref_object NMSetting *s_clear = NULL; + const Option * option; + NMSetting * s; + gs_unref_object NMSetting *s_clear = NULL; - if (setting) - s = NM_SETTING (setting); - else - s = s_clear = nm_setting_bridge_port_new (); + if (setting) + s = NM_SETTING(setting); + else + s = s_clear = nm_setting_bridge_port_new(); - for (option = slave_options; option->name; option++) - commit_option (device, s, option, TRUE); + for (option = slave_options; option->name; option++) + commit_option(device, s, option, TRUE); } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); - int ifindex = nm_device_get_ifindex (device); - const Option *option; - gs_free char *stp = NULL; - int stp_value; - - if (!s_bridge) { - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - nm_connection_add_setting (connection, (NMSetting *) s_bridge); - } - - option = master_options; - nm_assert (nm_streq (option->sysname, "stp_state")); - - stp = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), ifindex, option->sysname); - stp_value = _nm_utils_ascii_str_to_int64 (stp, 10, option->nm_min, option->nm_max, option->nm_default); - g_object_set (s_bridge, option->name, stp_value, NULL); - option++; - - for (; option->name; option++) { - nm_auto_unset_gvalue GValue value = G_VALUE_INIT; - gs_free char *str = NULL; - GParamSpec *pspec; - - str = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), ifindex, option->sysname); - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (s_bridge), option->name); - - if (!stp_value && option->only_with_stp) - continue; - - if (!str) { - _LOGW (LOGD_BRIDGE, "failed to read bridge setting '%s'", option->sysname); - continue; - } - - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - - if (option->from_sysfs) { - option->from_sysfs (str, &value); - goto out; - } - - switch (pspec->value_type) { - case G_TYPE_UINT64: - case G_TYPE_UINT: { - guint64 uvalue; - - /* See comments in set_sysfs_uint() about centiseconds. */ - if (option->user_hz_compensate) { - uvalue = _nm_utils_ascii_str_to_int64 (str, 10, - option->nm_min * 100, - option->nm_max * 100, - option->nm_default * 100); - uvalue /= 100; - } else { - uvalue = _nm_utils_ascii_str_to_uint64 (str, 10, - option->nm_min, - option->nm_max, - option->nm_default); - } - - if (pspec->value_type == G_TYPE_UINT64) - g_value_set_uint64(&value, uvalue); - else - g_value_set_uint (&value, (guint) uvalue); - } - break; - case G_TYPE_BOOLEAN: { - gboolean bvalue; - - bvalue = _nm_utils_ascii_str_to_int64 (str, 10, - option->nm_min, - option->nm_max, - option->nm_default); - g_value_set_boolean (&value, bvalue); - } - break; - case G_TYPE_STRING: - g_value_set_string (&value, str); - break; - default: - nm_assert_not_reached (); - break; - } + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + NMSettingBridge *s_bridge = nm_connection_get_setting_bridge(connection); + int ifindex = nm_device_get_ifindex(device); + const Option * option; + gs_free char * stp = NULL; + int stp_value; + + if (!s_bridge) { + s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); + nm_connection_add_setting(connection, (NMSetting *) s_bridge); + } + + option = master_options; + nm_assert(nm_streq(option->sysname, "stp_state")); + + stp = nm_platform_sysctl_master_get_option(nm_device_get_platform(device), + ifindex, + option->sysname); + stp_value = + _nm_utils_ascii_str_to_int64(stp, 10, option->nm_min, option->nm_max, option->nm_default); + g_object_set(s_bridge, option->name, stp_value, NULL); + option++; + + for (; option->name; option++) { + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + gs_free char * str = NULL; + GParamSpec * pspec; + + str = nm_platform_sysctl_master_get_option(nm_device_get_platform(device), + ifindex, + option->sysname); + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(s_bridge), option->name); + + if (!stp_value && option->only_with_stp) + continue; + + if (!str) { + _LOGW(LOGD_BRIDGE, "failed to read bridge setting '%s'", option->sysname); + continue; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + if (option->from_sysfs) { + option->from_sysfs(str, &value); + goto out; + } + + switch (pspec->value_type) { + case G_TYPE_UINT64: + case G_TYPE_UINT: + { + guint64 uvalue; + + /* See comments in set_sysfs_uint() about centiseconds. */ + if (option->user_hz_compensate) { + uvalue = _nm_utils_ascii_str_to_int64(str, + 10, + option->nm_min * 100, + option->nm_max * 100, + option->nm_default * 100); + uvalue /= 100; + } else { + uvalue = _nm_utils_ascii_str_to_uint64(str, + 10, + option->nm_min, + option->nm_max, + option->nm_default); + } + + if (pspec->value_type == G_TYPE_UINT64) + g_value_set_uint64(&value, uvalue); + else + g_value_set_uint(&value, (guint) uvalue); + } break; + case G_TYPE_BOOLEAN: + { + gboolean bvalue; + + bvalue = _nm_utils_ascii_str_to_int64(str, + 10, + option->nm_min, + option->nm_max, + option->nm_default); + g_value_set_boolean(&value, bvalue); + } break; + case G_TYPE_STRING: + g_value_set_string(&value, str); + break; + default: + nm_assert_not_reached(); + break; + } out: - g_object_set_property (G_OBJECT (s_bridge), option->name, &value); - } + g_object_set_property(G_OBJECT(s_bridge), option->name, &value); + } } static gboolean -master_update_slave_connection (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - GError **error) +master_update_slave_connection(NMDevice * device, + NMDevice * slave, + NMConnection *connection, + GError ** error) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - NMSettingConnection *s_con; - NMSettingBridgePort *s_port; - int ifindex_slave = nm_device_get_ifindex (slave); - const char *iface = nm_device_get_iface (device); - const Option *option; - - g_return_val_if_fail (ifindex_slave > 0, FALSE); - - s_con = nm_connection_get_setting_connection (connection); - s_port = nm_connection_get_setting_bridge_port (connection); - if (!s_port) { - s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_port)); - } - - for (option = slave_options; option->name; option++) { - gs_free char *str = nm_platform_sysctl_slave_get_option (nm_device_get_platform (device), ifindex_slave, option->sysname); - uint value; - - if (str) { - /* See comments in set_sysfs_uint() about centiseconds. */ - if (option->user_hz_compensate) { - value = _nm_utils_ascii_str_to_int64 (str, 10, - option->nm_min * 100, - option->nm_max * 100, - option->nm_default * 100); - value /= 100; - } else { - value = _nm_utils_ascii_str_to_int64 (str, 10, - option->nm_min, - option->nm_max, - option->nm_default); - } - g_object_set (s_port, option->name, value, NULL); - } else - _LOGW (LOGD_BRIDGE, "failed to read bridge port setting '%s'", option->sysname); - } - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, iface, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); - return TRUE; + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + NMSettingConnection *s_con; + NMSettingBridgePort *s_port; + int ifindex_slave = nm_device_get_ifindex(slave); + const char * iface = nm_device_get_iface(device); + const Option * option; + + g_return_val_if_fail(ifindex_slave > 0, FALSE); + + s_con = nm_connection_get_setting_connection(connection); + s_port = nm_connection_get_setting_bridge_port(connection); + if (!s_port) { + s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new(); + nm_connection_add_setting(connection, NM_SETTING(s_port)); + } + + for (option = slave_options; option->name; option++) { + gs_free char *str = nm_platform_sysctl_slave_get_option(nm_device_get_platform(device), + ifindex_slave, + option->sysname); + uint value; + + if (str) { + /* See comments in set_sysfs_uint() about centiseconds. */ + if (option->user_hz_compensate) { + value = _nm_utils_ascii_str_to_int64(str, + 10, + option->nm_min * 100, + option->nm_max * 100, + option->nm_default * 100); + value /= 100; + } else { + value = _nm_utils_ascii_str_to_int64(str, + 10, + option->nm_min, + option->nm_max, + option->nm_default); + } + g_object_set(s_port, option->name, value, NULL); + } else + _LOGW(LOGD_BRIDGE, "failed to read bridge port setting '%s'", option->sysname); + } + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, + iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); + return TRUE; } static gboolean -bridge_set_vlan_options (NMDevice *device, NMSettingBridge *s_bridge) +bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - gconstpointer hwaddr; - size_t length; - gboolean enabled; - guint16 pvid; - NMPlatform *plat; - int ifindex; - gs_unref_ptrarray GPtrArray *vlans = NULL; - gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; - - if (self->vlan_configured) - return TRUE; - - plat = nm_device_get_platform (device); - ifindex = nm_device_get_ifindex (device); - enabled = nm_setting_bridge_get_vlan_filtering (s_bridge); - - if (!enabled) { - nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0"); - nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "1"); - nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, NULL); - return TRUE; - } - - hwaddr = nm_platform_link_get_address (plat, ifindex, &length); - g_return_val_if_fail (length == ETH_ALEN, FALSE); - if (nm_utils_hwaddr_matches (hwaddr, ETH_ALEN, nm_ip_addr_zero.addr_eth, ETH_ALEN)) { - /* We need a non-zero MAC address to set the default pvid. - * Retry later. */ - return TRUE; - } - - self->vlan_configured = TRUE; - - /* Filtering must be disabled to change the default PVID */ - if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0")) - return FALSE; - - /* Clear the default PVID so that we later can force the re-creation of - * default PVID VLANs by writing the option again. */ - if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "0")) - return FALSE; - - /* Clear all existing VLANs */ - if (!nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, NULL)) - return FALSE; - - /* Now set the default PVID. After this point the kernel creates - * a PVID VLAN on each port, including the bridge itself. */ - pvid = nm_setting_bridge_get_vlan_default_pvid (s_bridge); - if (pvid) { - char value[32]; - - nm_sprintf_buf (value, "%u", pvid); - if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", value)) - return FALSE; - } - - /* Create VLANs only after setting the default PVID, so that - * any PVID VLAN overrides the bridge's default PVID. */ - g_object_get (s_bridge, NM_SETTING_BRIDGE_VLANS, &vlans, NULL); - plat_vlans = setting_vlans_to_platform (vlans); - if ( plat_vlans - && !nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, plat_vlans)) - return FALSE; - - if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "1")) - return FALSE; - - return TRUE; + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + gconstpointer hwaddr; + size_t length; + gboolean enabled; + guint16 pvid; + NMPlatform * plat; + int ifindex; + gs_unref_ptrarray GPtrArray *vlans = NULL; + gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; + + if (self->vlan_configured) + return TRUE; + + plat = nm_device_get_platform(device); + ifindex = nm_device_get_ifindex(device); + enabled = nm_setting_bridge_get_vlan_filtering(s_bridge); + + if (!enabled) { + nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "0"); + nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", "1"); + nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL); + return TRUE; + } + + hwaddr = nm_platform_link_get_address(plat, ifindex, &length); + g_return_val_if_fail(length == ETH_ALEN, FALSE); + if (nm_utils_hwaddr_matches(hwaddr, length, &nm_ether_addr_zero, ETH_ALEN)) { + /* We need a non-zero MAC address to set the default pvid. + * Retry later. */ + return TRUE; + } + + self->vlan_configured = TRUE; + + /* Filtering must be disabled to change the default PVID */ + if (!nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "0")) + return FALSE; + + /* Clear the default PVID so that we later can force the re-creation of + * default PVID VLANs by writing the option again. */ + if (!nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", "0")) + return FALSE; + + /* Clear all existing VLANs */ + if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL)) + return FALSE; + + /* Now set the default PVID. After this point the kernel creates + * a PVID VLAN on each port, including the bridge itself. */ + pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); + if (pvid) { + char value[32]; + + nm_sprintf_buf(value, "%u", pvid); + if (!nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", value)) + return FALSE; + } + + /* Create VLANs only after setting the default PVID, so that + * any PVID VLAN overrides the bridge's default PVID. */ + g_object_get(s_bridge, NM_SETTING_BRIDGE_VLANS, &vlans, NULL); + plat_vlans = setting_vlans_to_platform(vlans); + if (plat_vlans && !nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, plat_vlans)) + return FALSE; + + if (!nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "1")) + return FALSE; + + return TRUE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMConnection *connection; - NMSetting *s_bridge; - const Option *option; + NMConnection *connection; + NMSetting * s_bridge; + const Option *option; - connection = nm_device_get_applied_connection (device); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); + connection = nm_device_get_applied_connection(device); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); - s_bridge = (NMSetting *) nm_connection_get_setting_bridge (connection); - g_return_val_if_fail (s_bridge, NM_ACT_STAGE_RETURN_FAILURE); + s_bridge = (NMSetting *) nm_connection_get_setting_bridge(connection); + g_return_val_if_fail(s_bridge, NM_ACT_STAGE_RETURN_FAILURE); - for (option = master_options; option->name; option++) - commit_option (device, s_bridge, option, FALSE); + for (option = master_options; option->name; option++) + commit_option(device, s_bridge, option, FALSE); - if (!bridge_set_vlan_options (device, (NMSettingBridge *) s_bridge)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } + if (!bridge_set_vlan_options(device, (NMSettingBridge *) s_bridge)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } - return NM_ACT_STAGE_RETURN_SUCCESS; + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -_bt_register_bridge_cb (GError *error, - gpointer user_data) +_bt_register_bridge_cb(GError *error, gpointer user_data) { - NMDeviceBridge *self; + NMDeviceBridge *self; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - self = user_data; + self = user_data; - g_clear_object (&self->bt_cancellable); + g_clear_object(&self->bt_cancellable); - if (error) { - _LOGD (LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message); - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - return; - } + if (error) { + _LOGD(LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_BT_FAILED); + return; + } - nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self), FALSE); + nm_device_activate_schedule_stage2_device_config(NM_DEVICE(self), FALSE); } void -_nm_device_bridge_notify_unregister_bt_nap (NMDevice *device, - const char *reason) +_nm_device_bridge_notify_unregister_bt_nap(NMDevice *device, const char *reason) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); - _LOGD (LOGD_DEVICE, "bluetooth NAP server unregistered from bridge: %s%s", - reason, - self->bt_registered ? "" : " (was no longer registered)"); + _LOGD(LOGD_DEVICE, + "bluetooth NAP server unregistered from bridge: %s%s", + reason, + self->bt_registered ? "" : " (was no longer registered)"); - nm_clear_g_cancellable (&self->bt_cancellable); + nm_clear_g_cancellable(&self->bt_cancellable); - if (self->bt_registered) { - self->bt_registered = FALSE; - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_BT_FAILED); - } + if (self->bt_registered) { + self->bt_registered = FALSE; + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); + } } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - NMConnection *connection; - NMSettingBluetooth *s_bt; - gs_free_error GError *error = NULL; - - connection = nm_device_get_applied_connection (device); - - s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); - if (!s_bt) - return NM_ACT_STAGE_RETURN_SUCCESS; - - if (!nm_bt_vtable_network_server) { - _LOGD (LOGD_DEVICE, "bluetooth NAP server failed because bluetooth plugin not available"); - *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (self->bt_cancellable) - return NM_ACT_STAGE_RETURN_POSTPONE; - - if (self->bt_registered) - return NM_ACT_STAGE_RETURN_POSTPONE; - - self->bt_cancellable = g_cancellable_new (); - if (!nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server, - nm_setting_bluetooth_get_bdaddr (s_bt), - device, - self->bt_cancellable, - _bt_register_bridge_cb, - device, - &error)) { - _LOGD (LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message); - *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - self->bt_registered = TRUE; - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + NMConnection * connection; + NMSettingBluetooth *s_bt; + gs_free_error GError *error = NULL; + + connection = nm_device_get_applied_connection(device); + + s_bt = _nm_connection_get_setting_bluetooth_for_nap(connection); + if (!s_bt) + return NM_ACT_STAGE_RETURN_SUCCESS; + + if (!nm_bt_vtable_network_server) { + _LOGD(LOGD_DEVICE, "bluetooth NAP server failed because bluetooth plugin not available"); + *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (self->bt_cancellable) + return NM_ACT_STAGE_RETURN_POSTPONE; + + if (self->bt_registered) + return NM_ACT_STAGE_RETURN_POSTPONE; + + self->bt_cancellable = g_cancellable_new(); + if (!nm_bt_vtable_network_server->register_bridge(nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr(s_bt), + device, + self->bt_cancellable, + _bt_register_bridge_cb, + device, + &error)) { + _LOGD(LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message); + *out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + self->bt_registered = TRUE; + return NM_ACT_STAGE_RETURN_POSTPONE; } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); - _LOGD (LOGD_DEVICE, "deactivate bridge%s", - self->bt_registered ? " (registered as NAP bluetooth device)" : ""); + _LOGD(LOGD_DEVICE, + "deactivate bridge%s", + self->bt_registered ? " (registered as NAP bluetooth device)" : ""); - self->vlan_configured = FALSE; + self->vlan_configured = FALSE; - nm_clear_g_cancellable (&self->bt_cancellable); + nm_clear_g_cancellable(&self->bt_cancellable); - if (self->bt_registered) { - self->bt_registered = FALSE; - nm_bt_vtable_network_server->unregister_bridge (nm_bt_vtable_network_server, - device); - } + if (self->bt_registered) { + self->bt_registered = FALSE; + nm_bt_vtable_network_server->unregister_bridge(nm_bt_vtable_network_server, device); + } } static gboolean -enslave_slave (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - NMConnection *master_connection; - NMSettingBridge *s_bridge; - NMSettingBridgePort *s_port; + NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); + NMConnection * master_connection; + NMSettingBridge * s_bridge; + NMSettingBridgePort *s_port; - if (configure) { - if (!nm_platform_link_enslave (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave))) - return FALSE; + if (configure) { + if (!nm_platform_link_enslave(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + nm_device_get_ip_ifindex(slave))) + return FALSE; - master_connection = nm_device_get_applied_connection (device); - nm_assert (master_connection); - s_bridge = nm_connection_get_setting_bridge (master_connection); - nm_assert (s_bridge); - s_port = nm_connection_get_setting_bridge_port (connection); + master_connection = nm_device_get_applied_connection(device); + nm_assert(master_connection); + s_bridge = nm_connection_get_setting_bridge(master_connection); + nm_assert(s_bridge); + s_port = nm_connection_get_setting_bridge_port(connection); - bridge_set_vlan_options (device, s_bridge); + bridge_set_vlan_options(device, s_bridge); - if (nm_setting_bridge_get_vlan_filtering (s_bridge)) { - gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; - gs_unref_ptrarray GPtrArray *vlans = NULL; + if (nm_setting_bridge_get_vlan_filtering(s_bridge)) { + gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; + gs_unref_ptrarray GPtrArray *vlans = NULL; - if (s_port) - g_object_get (s_port, NM_SETTING_BRIDGE_PORT_VLANS, &vlans, NULL); + if (s_port) + g_object_get(s_port, NM_SETTING_BRIDGE_PORT_VLANS, &vlans, NULL); - plat_vlans = setting_vlans_to_platform (vlans); + plat_vlans = setting_vlans_to_platform(vlans); - /* Since the link was just enslaved, there are no existing VLANs - * (except for the default one) and so there's no need to flush. */ + /* Since the link was just enslaved, there are no existing VLANs + * (except for the default one) and so there's no need to flush. */ - if ( plat_vlans - && !nm_platform_link_set_bridge_vlans (nm_device_get_platform (slave), - nm_device_get_ifindex (slave), - TRUE, - plat_vlans)) - return FALSE; - } + if (plat_vlans + && !nm_platform_link_set_bridge_vlans(nm_device_get_platform(slave), + nm_device_get_ifindex(slave), + TRUE, + plat_vlans)) + return FALSE; + } - commit_slave_options (slave, s_port); + commit_slave_options(slave, s_port); - _LOGI (LOGD_BRIDGE, "attached bridge port %s", - nm_device_get_ip_iface (slave)); - } else { - _LOGI (LOGD_BRIDGE, "bridge port %s was attached", - nm_device_get_ip_iface (slave)); - } + _LOGI(LOGD_BRIDGE, "attached bridge port %s", nm_device_get_ip_iface(slave)); + } else { + _LOGI(LOGD_BRIDGE, "bridge port %s was attached", nm_device_get_ip_iface(slave)); + } - return TRUE; + return TRUE; } static void -release_slave (NMDevice *device, - NMDevice *slave, - gboolean configure) +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); - gboolean success; - int ifindex_slave; - int ifindex; - - if (configure) { - ifindex = nm_device_get_ifindex (device); - if ( ifindex <= 0 - || !nm_platform_link_get (nm_device_get_platform (device), ifindex)) - configure = FALSE; - } - - ifindex_slave = nm_device_get_ip_ifindex (slave); - - if (ifindex_slave <= 0) { - _LOGD (LOGD_TEAM, "bond slave %s is already released", nm_device_get_ip_iface (slave)); - return; - } - - if (configure) { - success = nm_platform_link_release (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - ifindex_slave); - - if (success) { - _LOGI (LOGD_BRIDGE, "detached bridge port %s", - nm_device_get_ip_iface (slave)); - } else { - _LOGW (LOGD_BRIDGE, "failed to detach bridge port %s", - nm_device_get_ip_iface (slave)); - } - } else { - _LOGI (LOGD_BRIDGE, "bridge port %s was detached", - nm_device_get_ip_iface (slave)); - } + NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); + gboolean success; + int ifindex_slave; + int ifindex; + + if (configure) { + ifindex = nm_device_get_ifindex(device); + if (ifindex <= 0 || !nm_platform_link_get(nm_device_get_platform(device), ifindex)) + configure = FALSE; + } + + ifindex_slave = nm_device_get_ip_ifindex(slave); + + if (ifindex_slave <= 0) { + _LOGD(LOGD_TEAM, "bond slave %s is already released", nm_device_get_ip_iface(slave)); + return; + } + + if (configure) { + success = nm_platform_link_release(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + ifindex_slave); + + if (success) { + _LOGI(LOGD_BRIDGE, "detached bridge port %s", nm_device_get_ip_iface(slave)); + } else { + _LOGW(LOGD_BRIDGE, "failed to detach bridge port %s", nm_device_get_ip_iface(slave)); + } + } else { + _LOGI(LOGD_BRIDGE, "bridge port %s was detached", nm_device_get_ip_iface(slave)); + } } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - NMSettingBridge *s_bridge; - const char *iface = nm_device_get_iface (device); - const char *hwaddr; - gs_free char *hwaddr_cloned = NULL; - guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; - int r; - - nm_assert (iface); - - s_bridge = nm_connection_get_setting_bridge (connection); - nm_assert (s_bridge); - - hwaddr = nm_setting_bridge_get_mac_address (s_bridge); - if ( !hwaddr - && nm_device_hw_addr_get_cloned (device, connection, FALSE, - &hwaddr_cloned, NULL, NULL)) { - /* FIXME: we set the MAC address when creating the interface, while the - * NMDevice is still unrealized. As we afterwards realize the device, it - * forgets the parameters for the cloned MAC address, and in stage 1 - * it might create a different MAC address. That should be fixed by - * better handling device realization. */ - hwaddr = hwaddr_cloned; - } - - if (hwaddr) { - if (!nm_utils_hwaddr_aton (hwaddr, mac_address, ETH_ALEN)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Invalid hardware address '%s'", - hwaddr); - g_return_val_if_reached (FALSE); - } - } - - r = nm_platform_link_bridge_add (nm_device_get_platform (device), - iface, - hwaddr ? mac_address : NULL, - hwaddr ? ETH_ALEN : 0, - out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create bridge interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + NMSettingBridge * s_bridge; + const char * iface = nm_device_get_iface(device); + const char * hwaddr; + gs_free char * hwaddr_cloned = NULL; + guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; + NMPlatformLnkBridge props; + int r; + + nm_assert(iface); + + s_bridge = nm_connection_get_setting_bridge(connection); + nm_assert(s_bridge); + + hwaddr = nm_setting_bridge_get_mac_address(s_bridge); + if (!hwaddr + && nm_device_hw_addr_get_cloned(device, connection, FALSE, &hwaddr_cloned, NULL, NULL)) { + /* FIXME: we set the MAC address when creating the interface, while the + * NMDevice is still unrealized. As we afterwards realize the device, it + * forgets the parameters for the cloned MAC address, and in stage 1 + * it might create a different MAC address. That should be fixed by + * better handling device realization. */ + hwaddr = hwaddr_cloned; + } + + if (hwaddr) { + if (!nm_utils_hwaddr_aton(hwaddr, mac_address, ETH_ALEN)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Invalid hardware address '%s'", + hwaddr); + g_return_val_if_reached(FALSE); + } + } + + props = (NMPlatformLnkBridge){ + .forward_delay = _DEFAULT_IF_ZERO(nm_setting_bridge_get_forward_delay(s_bridge) * 100u, + NM_BRIDGE_FORWARD_DELAY_DEF_SYS), + .hello_time = _DEFAULT_IF_ZERO(nm_setting_bridge_get_hello_time(s_bridge) * 100u, + NM_BRIDGE_HELLO_TIME_DEF_SYS), + .max_age = _DEFAULT_IF_ZERO(nm_setting_bridge_get_max_age(s_bridge) * 100u, + NM_BRIDGE_MAX_AGE_DEF_SYS), + .ageing_time = _DEFAULT_IF_ZERO(nm_setting_bridge_get_ageing_time(s_bridge) * 100u, + NM_BRIDGE_AGEING_TIME_DEF_SYS), + .stp_state = nm_setting_bridge_get_stp(s_bridge), + .priority = nm_setting_bridge_get_priority(s_bridge), + .vlan_protocol = to_sysfs_vlan_protocol_sys(nm_setting_bridge_get_vlan_protocol(s_bridge)), + .vlan_stats_enabled = nm_setting_bridge_get_vlan_stats_enabled(s_bridge), + .group_fwd_mask = nm_setting_bridge_get_group_forward_mask(s_bridge), + .mcast_snooping = nm_setting_bridge_get_multicast_snooping(s_bridge), + .mcast_router = + to_sysfs_multicast_router_sys(nm_setting_bridge_get_multicast_router(s_bridge)), + .mcast_query_use_ifaddr = nm_setting_bridge_get_multicast_query_use_ifaddr(s_bridge), + .mcast_querier = nm_setting_bridge_get_multicast_querier(s_bridge), + .mcast_hash_max = nm_setting_bridge_get_multicast_hash_max(s_bridge), + .mcast_last_member_count = nm_setting_bridge_get_multicast_last_member_count(s_bridge), + .mcast_startup_query_count = nm_setting_bridge_get_multicast_startup_query_count(s_bridge), + .mcast_last_member_interval = + nm_setting_bridge_get_multicast_last_member_interval(s_bridge), + .mcast_membership_interval = nm_setting_bridge_get_multicast_membership_interval(s_bridge), + .mcast_querier_interval = nm_setting_bridge_get_multicast_querier_interval(s_bridge), + .mcast_query_interval = nm_setting_bridge_get_multicast_query_interval(s_bridge), + .mcast_query_response_interval = + nm_setting_bridge_get_multicast_query_response_interval(s_bridge), + .mcast_startup_query_interval = + nm_setting_bridge_get_multicast_startup_query_interval(s_bridge), + }; + + to_sysfs_group_address_sys(nm_setting_bridge_get_group_address(s_bridge), &props.group_addr); + + r = nm_platform_link_bridge_add(nm_device_get_platform(device), + iface, + hwaddr ? mac_address : NULL, + hwaddr ? ETH_ALEN : 0, + &props, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create bridge interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -nm_device_bridge_init (NMDeviceBridge * self) +nm_device_bridge_init(NMDeviceBridge *self) { - nm_assert (nm_device_is_master (NM_DEVICE (self))); + nm_assert(nm_device_is_master(NM_DEVICE(self))); } static const NMDBusInterfaceInfoExtended interface_info_device_bridge = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_BRIDGE, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_BRIDGE, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", + "ao", + NM_DEVICE_SLAVES), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_bridge_class_init (NMDeviceBridgeClass *klass) +nm_device_bridge_class_init(NMDeviceBridgeClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bridge); - - device_class->connection_type_supported = NM_SETTING_BRIDGE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_BRIDGE); - - device_class->is_master = TRUE; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; - - device_class->create_and_realize = create_and_realize; - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->deactivate = deactivate; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_bridge); + + device_class->connection_type_supported = NM_SETTING_BRIDGE_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BRIDGE); + + device_class->is_master = TRUE; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + + device_class->update_connection = update_connection; + device_class->master_update_slave_connection = master_update_slave_connection; + + device_class->create_and_realize = create_and_realize; + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->deactivate = deactivate; + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; } /*****************************************************************************/ -#define NM_TYPE_BRIDGE_DEVICE_FACTORY (nm_bridge_device_factory_get_type ()) -#define NM_BRIDGE_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BRIDGE_DEVICE_FACTORY, NMBridgeDeviceFactory)) +#define NM_TYPE_BRIDGE_DEVICE_FACTORY (nm_bridge_device_factory_get_type()) +#define NM_BRIDGE_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_BRIDGE_DEVICE_FACTORY, NMBridgeDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bridge", - NM_DEVICE_TYPE_DESC, "Bridge", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_BRIDGE, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_BRIDGE, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_DRIVER, + "bridge", + NM_DEVICE_TYPE_DESC, + "Bridge", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_BRIDGE, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_BRIDGE, + NULL); } static gboolean -match_connection (NMDeviceFactory *factory, - NMConnection *connection) +match_connection(NMDeviceFactory *factory, NMConnection *connection) { - const char *type = nm_connection_get_connection_type (connection); + const char *type = nm_connection_get_connection_type(connection); - if (nm_streq (type, NM_SETTING_BRIDGE_SETTING_NAME)) - return TRUE; + if (nm_streq(type, NM_SETTING_BRIDGE_SETTING_NAME)) + return TRUE; - nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME)); + nm_assert(nm_streq(type, NM_SETTING_BLUETOOTH_SETTING_NAME)); - if (!_nm_connection_get_setting_bluetooth_for_nap (connection)) - return FALSE; + if (!_nm_connection_get_setting_bluetooth_for_nap(connection)) + return FALSE; - if (!g_type_from_name ("NMBluezManager")) { - /* bluetooth NAP connections are handled by bridge factory. However, - * it needs help from the bluetooth plugin, so if the plugin is not loaded, - * we claim not to support it. */ - return FALSE; - } + if (!g_type_from_name("NMBluezManager")) { + /* bluetooth NAP connections are handled by bridge factory. However, + * it needs help from the bluetooth plugin, so if the plugin is not loaded, + * we claim not to support it. */ + return FALSE; + } - return TRUE; + return TRUE; } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (BRIDGE, Bridge, bridge, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BRIDGE) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BLUETOOTH_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->match_connection = match_connection; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + BRIDGE, + Bridge, + bridge, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_BRIDGE) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BLUETOOTH_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->match_connection = match_connection;); diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index fb614d40..c942813e 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 Red Hat, Inc. */ @@ -8,21 +8,23 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_BRIDGE (nm_device_bridge_get_type ()) -#define NM_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridge)) -#define NM_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) -#define NM_IS_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BRIDGE)) -#define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BRIDGE)) -#define NM_DEVICE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) - -typedef struct _NMDeviceBridge NMDeviceBridge; +#define NM_TYPE_DEVICE_BRIDGE (nm_device_bridge_get_type()) +#define NM_DEVICE_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridge)) +#define NM_DEVICE_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) +#define NM_IS_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_BRIDGE)) +#define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_BRIDGE)) +#define NM_DEVICE_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) + +typedef struct _NMDeviceBridge NMDeviceBridge; typedef struct _NMDeviceBridgeClass NMDeviceBridgeClass; -GType nm_device_bridge_get_type (void); +GType nm_device_bridge_get_type(void); extern const NMBtVTableNetworkServer *nm_bt_vtable_network_server; -void _nm_device_bridge_notify_unregister_bt_nap (NMDevice *device, - const char *reason); +void _nm_device_bridge_notify_unregister_bt_nap(NMDevice *device, const char *reason); #endif /* __NETWORKMANAGER_DEVICE_BRIDGE_H__ */ diff --git a/src/devices/nm-device-dummy.c b/src/devices/nm-device-dummy.c index 465a293b..4f6b8cc2 100644 --- a/src/devices/nm-device-dummy.c +++ b/src/devices/nm-device-dummy.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -24,152 +24,160 @@ _LOG_DECLARE_SELF(NMDeviceDummy); /*****************************************************************************/ struct _NMDeviceDummy { - NMDevice parent; + NMDevice parent; }; struct _NMDeviceDummyClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceDummy, nm_device_dummy, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceDummy, nm_device_dummy, NM_TYPE_DEVICE) /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingDummy *s_dummy; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_DUMMY_SETTING_NAME, - existing_connections, - NULL, - _("Dummy connection"), - NULL, - NULL, - TRUE); - - s_dummy = nm_connection_get_setting_dummy (connection); - if (!s_dummy) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'dummy' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingDummy *s_dummy; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_DUMMY_SETTING_NAME, + existing_connections, + NULL, + _("Dummy connection"), + NULL, + NULL, + TRUE); + + s_dummy = nm_connection_get_setting_dummy(connection); + if (!s_dummy) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'dummy' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSettingDummy *s_dummy = nm_connection_get_setting_dummy (connection); + NMSettingDummy *s_dummy = nm_connection_get_setting_dummy(connection); - if (!s_dummy) { - s_dummy = (NMSettingDummy *) nm_setting_dummy_new (); - nm_connection_add_setting (connection, (NMSetting *) s_dummy); - } + if (!s_dummy) { + s_dummy = (NMSettingDummy *) nm_setting_dummy_new(); + nm_connection_add_setting(connection, (NMSetting *) s_dummy); + } } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMSettingDummy *s_dummy; - int r; - - s_dummy = nm_connection_get_setting_dummy (connection); - g_assert (s_dummy); - - r = nm_platform_link_dummy_add (nm_device_get_platform (device), iface, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create dummy interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMSettingDummy *s_dummy; + int r; + + s_dummy = nm_connection_get_setting_dummy(connection); + g_assert(s_dummy); + + r = nm_platform_link_dummy_add(nm_device_get_platform(device), iface, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create dummy interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -nm_device_dummy_init (NMDeviceDummy *self) -{ -} +nm_device_dummy_init(NMDeviceDummy *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_dummy = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_DUMMY, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_DUMMY, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_dummy_class_init (NMDeviceDummyClass *klass) +nm_device_dummy_class_init(NMDeviceDummyClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_dummy); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_dummy); - device_class->connection_type_supported = NM_SETTING_DUMMY_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_DUMMY_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_DUMMY); + device_class->connection_type_supported = NM_SETTING_DUMMY_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_DUMMY_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_DUMMY); - device_class->complete_connection = complete_connection; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->update_connection = update_connection; - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->complete_connection = complete_connection; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->update_connection = update_connection; + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; } /*****************************************************************************/ -#define NM_TYPE_DUMMY_DEVICE_FACTORY (nm_dummy_device_factory_get_type ()) -#define NM_DUMMY_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DUMMY_DEVICE_FACTORY, NMDummyDeviceFactory)) +#define NM_TYPE_DUMMY_DEVICE_FACTORY (nm_dummy_device_factory_get_type()) +#define NM_DUMMY_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DUMMY_DEVICE_FACTORY, NMDummyDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_DUMMY, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Dummy", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_DUMMY, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_DUMMY, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_DUMMY, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Dummy", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_DUMMY, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_DUMMY, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (DUMMY, Dummy, dummy, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_DUMMY) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_DUMMY_SETTING_NAME), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + DUMMY, + Dummy, + dummy, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_DUMMY) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_DUMMY_SETTING_NAME), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-dummy.h b/src/devices/nm-device-dummy.h index e95be72d..b3670ef9 100644 --- a/src/devices/nm-device-dummy.h +++ b/src/devices/nm-device-dummy.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -8,16 +8,19 @@ #include "nm-device-generic.h" -#define NM_TYPE_DEVICE_DUMMY (nm_device_dummy_get_type ()) -#define NM_DEVICE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummy)) -#define NM_DEVICE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) -#define NM_IS_DEVICE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_DUMMY)) -#define NM_IS_DEVICE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_DUMMY)) -#define NM_DEVICE_DUMMY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) +#define NM_TYPE_DEVICE_DUMMY (nm_device_dummy_get_type()) +#define NM_DEVICE_DUMMY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummy)) +#define NM_DEVICE_DUMMY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) +#define NM_IS_DEVICE_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_DUMMY)) +#define NM_IS_DEVICE_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_DUMMY)) +#define NM_DEVICE_DUMMY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_DUMMY, NMDeviceDummyClass)) -typedef struct _NMDeviceDummy NMDeviceDummy; +typedef struct _NMDeviceDummy NMDeviceDummy; typedef struct _NMDeviceDummyClass NMDeviceDummyClass; -GType nm_device_dummy_get_type (void); +GType nm_device_dummy_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_DUMMY_H__ */ diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c index 79673201..5c35db83 100644 --- a/src/devices/nm-device-ethernet-utils.c +++ b/src/devices/nm-device-ethernet-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -10,19 +10,17 @@ #include "settings/nm-settings-connection.h" char * -nm_device_ethernet_utils_get_default_wired_name (GHashTable *existing_ids) +nm_device_ethernet_utils_get_default_wired_name(GHashTable *existing_ids) { - char *temp; - int i; + char *temp; + int i; - /* Find the next available unique connection name */ - for (i = 1; i < G_MAXINT; i++) { - temp = g_strdup_printf (_("Wired connection %d"), i); - if ( !existing_ids - || !g_hash_table_contains (existing_ids, temp)) - return temp; - g_free (temp); - } - return NULL; + /* Find the next available unique connection name */ + for (i = 1; i < G_MAXINT; i++) { + temp = g_strdup_printf(_("Wired connection %d"), i); + if (!existing_ids || !g_hash_table_contains(existing_ids, temp)) + return temp; + g_free(temp); + } + return NULL; } - diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h index 0e16f4b8..d67b9fa1 100644 --- a/src/devices/nm-device-ethernet-utils.h +++ b/src/devices/nm-device-ethernet-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -6,6 +6,6 @@ #ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ #define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ -char *nm_device_ethernet_utils_get_default_wired_name (GHashTable *existing_ids); +char *nm_device_ethernet_utils_get_default_wired_name(GHashTable *existing_ids); -#endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ +#endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 9e7601f0..2569c426 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2014 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -48,1998 +48,2012 @@ _LOG_DECLARE_SELF(NMDeviceEthernet); /*****************************************************************************/ 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, + 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; typedef struct _NMDeviceEthernetPrivate { - /* 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; + /* 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; - guint32 speed; - gulong carrier_id; + guint32 speed; + gulong carrier_id; - struct { - NMSupplicantManager *mgr; - NMSupplMgrCreateIfaceHandle *create_handle; - NMSupplicantInterface *iface; + struct { + NMSupplicantManager * mgr; + NMSupplMgrCreateIfaceHandle *create_handle; + NMSupplicantInterface * iface; - gulong iface_state_id; - gulong auth_state_id; + gulong iface_state_id; + gulong auth_state_id; - guint con_timeout_id; + guint con_timeout_id; - guint lnk_timeout_id; + guint lnk_timeout_id; - bool is_associated:1; - } supplicant; + bool is_associated : 1; + } supplicant; - NMActRequestGetSecretsCallId *wired_secrets_id; + NMActRequestGetSecretsCallId *wired_secrets_id; - /* PPPoE */ - NMPPPManager *ppp_manager; - gint32 last_pppoe_time; - guint pppoe_wait_id; + /* PPPoE */ + NMPPPManager *ppp_manager; + gint32 last_pppoe_time; + guint pppoe_wait_id; - /* DCB */ - DcbWait dcb_wait; - guint dcb_timeout_id; + /* DCB */ + DcbWait dcb_wait; + guint dcb_timeout_id; - guint32 ethtool_prev_speed; + guint32 ethtool_prev_speed; - NMPlatformLinkDuplexType ethtool_prev_duplex:3; + NMPlatformLinkDuplexType ethtool_prev_duplex : 3; - bool dcb_handle_carrier_changes:1; + bool dcb_handle_carrier_changes : 1; - bool ethtool_prev_set:1; - bool ethtool_prev_autoneg:1; + bool ethtool_prev_set : 1; + bool ethtool_prev_autoneg : 1; } NMDeviceEthernetPrivate; -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceEthernet, - PROP_SPEED, - PROP_S390_SUBCHANNELS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceEthernet, PROP_SPEED, PROP_S390_SUBCHANNELS, ); /*****************************************************************************/ -G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) -#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMDevice) +#define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMDevice) /*****************************************************************************/ -static void wired_secrets_cancel (NMDeviceEthernet *self); +static void wired_secrets_cancel(NMDeviceEthernet *self); /*****************************************************************************/ static char * -get_link_basename (const char *parent_path, const char *name, GError **error) +get_link_basename(const char *parent_path, const char *name, GError **error) { - char *link_dest, *path; - char *result = NULL; - - path = g_strdup_printf ("%s/%s", parent_path, name); - link_dest = g_file_read_link (path, error); - if (link_dest) { - result = g_path_get_basename (link_dest); - g_free (link_dest); - } - g_free (path); - return result; + char *link_dest, *path; + char *result = NULL; + + path = g_strdup_printf("%s/%s", parent_path, name); + link_dest = g_file_read_link(path, error); + if (link_dest) { + result = g_path_get_basename(link_dest); + g_free(link_dest); + } + g_free(path); + return result; } static void -_update_s390_subchannels (NMDeviceEthernet *self) +_update_s390_subchannels(NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - struct udev_device *dev = NULL; - struct udev_device *parent = NULL; - const char *parent_path, *item; - int ifindex; - GDir *dir; - GError *error = NULL; - - 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; - } - - ifindex = nm_device_get_ifindex ((NMDevice *) self); - dev = nm_platform_link_get_udev_device (nm_device_get_platform (NM_DEVICE (self)), ifindex); - if (!dev) - return; - - /* Try for the "ccwgroup" parent */ - parent = udev_device_get_parent_with_subsystem_devtype (dev, "ccwgroup", NULL); - if (!parent) { - /* FIXME: whatever 'lcs' devices' subsystem is here... */ - - /* Not an s390 device */ - return; - } - - parent_path = udev_device_get_syspath (parent); - dir = g_dir_open (parent_path, 0, &error); - if (!dir) { - _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: failed to open directory '%s': %s", - parent_path, error->message); - g_clear_error (&error); - return; - } - - while ((item = g_dir_read_name (dir))) { - 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")) { - gs_free char *path = NULL, *value = NULL; - - path = g_strdup_printf ("%s/%s", parent_path, item); - value = nm_platform_sysctl_get (nm_device_get_platform (NM_DEVICE (self)), NMP_SYSCTL_PATHID_ABSOLUTE (path)); - - 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 - _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: error reading %s", path); - } - - if (error) { - _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: failed reading sysfs for %s (%s)", item, error->message); - g_clear_error (&error); - } - } - - g_dir_close (dir); - - 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); - - 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; - - _LOGI (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: found s390 '%s' subchannels [%s]", - nm_device_get_driver ((NMDevice *) self) ?: "(unknown driver)", - priv->subchannels); - - _notify (self, PROP_S390_SUBCHANNELS); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + struct udev_device * dev = NULL; + struct udev_device * parent = NULL; + const char * parent_path, *item; + int ifindex; + GDir * dir; + GError * error = NULL; + + 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; + } + + ifindex = nm_device_get_ifindex((NMDevice *) self); + dev = nm_platform_link_get_udev_device(nm_device_get_platform(NM_DEVICE(self)), ifindex); + if (!dev) + return; + + /* Try for the "ccwgroup" parent */ + parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccwgroup", NULL); + if (!parent) { + /* FIXME: whatever 'lcs' devices' subsystem is here... */ + + /* Not an s390 device */ + return; + } + + parent_path = udev_device_get_syspath(parent); + dir = g_dir_open(parent_path, 0, &error); + if (!dir) { + _LOGW(LOGD_DEVICE | LOGD_PLATFORM, + "update-s390: failed to open directory '%s': %s", + parent_path, + error->message); + g_clear_error(&error); + return; + } + + while ((item = g_dir_read_name(dir))) { + 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")) { + gs_free char *path = NULL, *value = NULL; + + path = g_strdup_printf("%s/%s", parent_path, item); + value = nm_platform_sysctl_get(nm_device_get_platform(NM_DEVICE(self)), + NMP_SYSCTL_PATHID_ABSOLUTE(path)); + + 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 + _LOGW(LOGD_DEVICE | LOGD_PLATFORM, "update-s390: error reading %s", path); + } + + if (error) { + _LOGW(LOGD_DEVICE | LOGD_PLATFORM, + "update-s390: failed reading sysfs for %s (%s)", + item, + error->message); + g_clear_error(&error); + } + } + + g_dir_close(dir); + + 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); + + 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; + + _LOGI(LOGD_DEVICE | LOGD_PLATFORM, + "update-s390: found s390 '%s' subchannels [%s]", + nm_device_get_driver((NMDevice *) self) ?: "(unknown driver)", + priv->subchannels); + + _notify(self, PROP_S390_SUBCHANNELS); } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - if (new_state > NM_DEVICE_STATE_ACTIVATED) - wired_secrets_cancel (NM_DEVICE_ETHERNET (device)); + if (new_state > NM_DEVICE_STATE_ACTIVATED) + wired_secrets_cancel(NM_DEVICE_ETHERNET(device)); } static void -nm_device_ethernet_init (NMDeviceEthernet *self) +nm_device_ethernet_init(NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv; + NMDeviceEthernetPrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); - self->_priv = priv; + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); + self->_priv = priv; - priv->s390_options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free); + priv->s390_options = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - int ifindex = nm_device_get_ifindex (device); - - if (ifindex > 0) { - if (nm_platform_link_supports_carrier_detect (nm_device_get_platform (device), ifindex)) - return NM_DEVICE_CAP_CARRIER_DETECT; - else { - _LOGI (LOGD_PLATFORM, "driver '%s' does not support carrier detection.", - nm_device_get_driver (device)); - } - } - - return NM_DEVICE_CAP_NONE; + NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device); + int ifindex = nm_device_get_ifindex(device); + + if (ifindex > 0) { + if (nm_platform_link_supports_carrier_detect(nm_device_get_platform(device), ifindex)) + return NM_DEVICE_CAP_CARRIER_DETECT; + else { + _LOGI(LOGD_PLATFORM, + "driver '%s' does not support carrier detection.", + nm_device_get_driver(device)); + } + } + + return NM_DEVICE_CAP_NONE; } static guint32 -_subchannels_count_num (const char * const *array) +_subchannels_count_num(const char *const *array) { - int i; + int i; - if (!array) - return 0; - for (i = 0; array[i]; i++) - /* NOP */; - return i; + if (!array) + return 0; + for (i = 0; array[i]; i++) + /* NOP */; + return i; } static gboolean -match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) +match_subchans(NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const char * const *subchans; - guint32 num1, num2; - int i; - - *try_mac = TRUE; - - subchans = nm_setting_wired_get_s390_subchannels (s_wired); - num1 = _subchannels_count_num (subchans); - num2 = _subchannels_count_num ((const char * const *) priv->subchannels_dbus); - /* connection has no subchannels */ - if (num1 == 0) - return TRUE; - /* connection requires subchannels but the device has none */ - if (num2 == 0) - return FALSE; - /* number of subchannels differ */ - if (num1 != num2) - return FALSE; - - /* Make sure each subchannel in the connection is a subchannel of this device */ - for (i = 0; subchans[i]; i++) { - const char *candidate = subchans[i]; - - if ( (priv->subchan1 && !strcmp (priv->subchan1, candidate)) - || (priv->subchan2 && !strcmp (priv->subchan2, candidate)) - || (priv->subchan3 && !strcmp (priv->subchan3, candidate))) - continue; - - return FALSE; /* a subchannel was not found */ - } - - *try_mac = FALSE; - return TRUE; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + const char *const * subchans; + guint32 num1, num2; + int i; + + *try_mac = TRUE; + + subchans = nm_setting_wired_get_s390_subchannels(s_wired); + num1 = _subchannels_count_num(subchans); + num2 = _subchannels_count_num((const char *const *) priv->subchannels_dbus); + /* connection has no subchannels */ + if (num1 == 0) + return TRUE; + /* connection requires subchannels but the device has none */ + if (num2 == 0) + return FALSE; + /* number of subchannels differ */ + if (num1 != num2) + return FALSE; + + /* Make sure each subchannel in the connection is a subchannel of this device */ + for (i = 0; subchans[i]; i++) { + const char *candidate = subchans[i]; + + if ((priv->subchan1 && !strcmp(priv->subchan1, candidate)) + || (priv->subchan2 && !strcmp(priv->subchan2, candidate)) + || (priv->subchan3 && !strcmp(priv->subchan3, candidate))) + continue; + + return FALSE; /* a subchannel was not found */ + } + + *try_mac = FALSE; + return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMSettingWired *s_wired; - - if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { - s_wired = nm_connection_get_setting_wired (connection); - } else { - s_wired = _nm_connection_check_main_setting (connection, NM_SETTING_WIRED_SETTING_NAME, error); - if (!s_wired) - return FALSE; - } - - if (s_wired) { - const char *mac, *perm_hw_addr; - gboolean try_mac = TRUE; - const char * const *mac_blacklist; - int i; - - 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"); - return FALSE; - } - - perm_hw_addr = nm_device_get_permanent_hw_address (device); - mac = nm_setting_wired_get_mac_address (s_wired); - if (perm_hw_addr) { - 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"); - return FALSE; - } - - /* 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)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "invalid MAC in blacklist"); - return FALSE; - } - - 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"); - return FALSE; - } - } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no permanent MAC address to match"); - return FALSE; - } - } - - return TRUE; + NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device); + NMSettingWired * s_wired; + + if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)) { + s_wired = nm_connection_get_setting_wired(connection); + } else { + s_wired = + _nm_connection_check_main_setting(connection, NM_SETTING_WIRED_SETTING_NAME, error); + if (!s_wired) + return FALSE; + } + + if (s_wired) { + const char * mac, *perm_hw_addr; + gboolean try_mac = TRUE; + const char *const *mac_blacklist; + int i; + + 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"); + return FALSE; + } + + perm_hw_addr = nm_device_get_permanent_hw_address(device); + mac = nm_setting_wired_get_mac_address(s_wired); + if (perm_hw_addr) { + 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"); + return FALSE; + } + + /* 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)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "invalid MAC in blacklist"); + return FALSE; + } + + 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"); + return FALSE; + } + } + } else if (mac) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has no permanent MAC address to match"); + return FALSE; + } + } + + return TRUE; } /*****************************************************************************/ /* 802.1X */ static void -supplicant_interface_release (NMDeviceEthernet *self) +supplicant_interface_release(NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); - nm_clear_pointer (&priv->supplicant.create_handle, nm_supplicant_manager_create_interface_cancel); + nm_clear_pointer(&priv->supplicant.create_handle, + nm_supplicant_manager_create_interface_cancel); - nm_clear_g_source (&priv->supplicant.lnk_timeout_id); - nm_clear_g_source (&priv->supplicant.con_timeout_id); - nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_state_id); - nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.auth_state_id); + nm_clear_g_source(&priv->supplicant.lnk_timeout_id); + nm_clear_g_source(&priv->supplicant.con_timeout_id); + nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id); + nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.auth_state_id); - if (priv->supplicant.iface) { - nm_supplicant_interface_disconnect (priv->supplicant.iface); - g_clear_object (&priv->supplicant.iface); - } + if (priv->supplicant.iface) { + nm_supplicant_interface_disconnect(priv->supplicant.iface); + g_clear_object(&priv->supplicant.iface); + } } static void -supplicant_auth_state_changed (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceEthernet *self) +supplicant_auth_state_changed(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceEthernet * self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSupplicantAuthState state; + 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); + 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)); - } + 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) +wired_auth_is_optional(NMDeviceEthernet *self) { - NMSetting8021x *s_8021x; + 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); + 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) +wired_auth_cond_fail(NMDeviceEthernet *self, NMDeviceStateReason reason) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - - if (wired_auth_is_optional (self)) { - _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_stage3_ip_config_start (device); - - 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); - } - return; - } - - supplicant_interface_release (self); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - reason); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + + if (wired_auth_is_optional(self)) { + _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_stage3_ip_config_start(device); + + 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); + } + return; + } + + supplicant_interface_release(self); + nm_device_state_changed(NM_DEVICE(self), NM_DEVICE_STATE_FAILED, reason); } static void -wired_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *connection, - GError *error, - gpointer user_data) +wired_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * connection, + GError * error, + gpointer user_data) { - NMDeviceEthernet *self = user_data; - NMDevice *device = user_data; - NMDeviceEthernetPrivate *priv; + NMDeviceEthernet * self = user_data; + NMDevice * device = user_data; + NMDeviceEthernetPrivate *priv; - g_return_if_fail (NM_IS_DEVICE_ETHERNET (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + 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); + priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); - g_return_if_fail (priv->wired_secrets_id == call_id); + g_return_if_fail(priv->wired_secrets_id == call_id); - priv->wired_secrets_id = NULL; + priv->wired_secrets_id = NULL; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - 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); - g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); + 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); + g_return_if_fail(nm_act_request_get_settings_connection(req) == connection); - if (error) { - _LOGW (LOGD_ETHER, "%s", error->message); - wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } + if (error) { + _LOGW(LOGD_ETHER, "%s", error->message); + wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } - supplicant_interface_release (self); - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + supplicant_interface_release(self); + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -wired_secrets_cancel (NMDeviceEthernet *self) +wired_secrets_cancel(NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (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); + 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) +wired_secrets_get_secrets(NMDeviceEthernet * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMActRequest *req; - - wired_secrets_cancel (self); - - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - 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); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMActRequest * req; + + wired_secrets_cancel(self); + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + + 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); } static gboolean -supplicant_lnk_timeout_cb (gpointer user_data) +supplicant_lnk_timeout_cb(gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMActRequest *req; - NMConnection *applied_connection; - const char *setting_name; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMActRequest * req; + NMConnection * applied_connection; + const char * setting_name; - priv->supplicant.lnk_timeout_id = 0; + priv->supplicant.lnk_timeout_id = 0; - req = nm_device_get_act_request (device); + req = nm_device_get_act_request(device); - if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { - wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); - return G_SOURCE_REMOVE; - } + if (nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) { + wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); + return G_SOURCE_REMOVE; + } - /* Disconnect event during initial authentication and credentials - * ARE checked - we are likely to have wrong key. Ask the user for - * another one. - */ - if (nm_device_get_state (device) != NM_DEVICE_STATE_CONFIG) - goto time_out; + /* Disconnect event during initial authentication and credentials + * ARE checked - we are likely to have wrong key. Ask the user for + * another one. + */ + if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG) + goto time_out; - nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); + 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); - if (!setting_name) - goto time_out; + applied_connection = nm_act_request_get_applied_connection(req); + setting_name = nm_connection_need_secrets(applied_connection, NULL); + if (!setting_name) + goto time_out; - _LOGI (LOGD_DEVICE | LOGD_ETHER, - "Activation: (ethernet) disconnected during authentication, asking for new key."); - if (!wired_auth_is_optional (self)) - supplicant_interface_release (self); + _LOGI(LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) disconnected during authentication, asking for new key."); + if (!wired_auth_is_optional(self)) + supplicant_interface_release(self); - nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - wired_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + nm_device_state_changed(device, + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + wired_secrets_get_secrets(self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; time_out: - _LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out."); - wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + _LOGW(LOGD_DEVICE | LOGD_ETHER, "link timed out."); + wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static NMSupplicantConfig * -build_supplicant_config (NMDeviceEthernet *self, - GError **error) +build_supplicant_config(NMDeviceEthernet *self, GError **error) { - const char *con_uuid; - NMSupplicantConfig *config = NULL; - NMSetting8021x *security; - NMConnection *connection; - guint32 mtu; + const char * con_uuid; + NMSupplicantConfig *config = NULL; + NMSetting8021x * security; + NMConnection * connection; + guint32 mtu; - connection = nm_device_get_applied_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection(NM_DEVICE(self)); - g_return_val_if_fail (connection, NULL); + g_return_val_if_fail(connection, NULL); - con_uuid = nm_connection_get_uuid (connection); - mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); + con_uuid = nm_connection_get_uuid(connection); + mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)), + nm_device_get_ifindex(NM_DEVICE(self))); - config = nm_supplicant_config_new (NM_SUPPL_CAP_MASK_NONE); + config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE); - security = nm_connection_get_setting_802_1x (connection); - 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); - } + security = nm_connection_get_setting_802_1x(connection); + 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); + } - return config; + return config; } static void -supplicant_iface_state_is_completed (NMDeviceEthernet *self, - NMSupplicantInterfaceState state) +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); - - /* If this is the initial association during device activation, - * schedule the next activation stage. - */ - 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."); - nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self)); - } - return; - } - - 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); + 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); + + /* If this is the initial association during device activation, + * schedule the next activation stage. + */ + 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."); + nm_device_activate_schedule_stage3_ip_config_start(NM_DEVICE(self)); + } + return; + } + + 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); } static void -supplicant_iface_assoc_cb (NMSupplicantInterface *iface, - GError *error, - gpointer user_data) +supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data) { - NMDeviceEthernet *self; - NMDeviceEthernetPrivate *priv; + NMDeviceEthernet * self; + NMDeviceEthernetPrivate *priv; - if (nm_utils_error_is_cancelled_or_disposing (error)) - return; + if (nm_utils_error_is_cancelled_or_disposing(error)) + return; - self = NM_DEVICE_ETHERNET (user_data); - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + self = NM_DEVICE_ETHERNET(user_data); + priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); - if (error) { - supplicant_interface_release (self); - nm_device_queue_state (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); - return; - } + if (error) { + supplicant_interface_release(self); + nm_device_queue_state(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); + return; + } - nm_assert (!priv->supplicant.lnk_timeout_id); - nm_assert (!priv->supplicant.is_associated); + 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)); + 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) +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; - - 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; - } - - nm_supplicant_interface_disconnect (priv->supplicant.iface); - nm_supplicant_interface_assoc (priv->supplicant.iface, - config, - supplicant_iface_assoc_cb, - self); - return TRUE; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + gs_unref_object NMSupplicantConfig *config = NULL; + gs_free_error GError *error = NULL; + + 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; + } + + nm_supplicant_interface_disconnect(priv->supplicant.iface); + nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self); + return TRUE; } static void -supplicant_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data) +supplicant_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSupplicantInterfaceState new_state = new_state_i; - NMSupplicantInterfaceState old_state = old_state_i; - - _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)); - - if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { - supplicant_interface_release (self); - wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return; - } - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - if (!supplicant_iface_start (self)) - return; - } - - if (priv->supplicant.is_associated) - supplicant_iface_state_is_completed (self, new_state); + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data); + NMDeviceEthernetPrivate * priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSupplicantInterfaceState new_state = new_state_i; + NMSupplicantInterfaceState old_state = old_state_i; + + _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)); + + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + supplicant_interface_release(self); + wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return; + } + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + if (!supplicant_iface_start(self)) + return; + } + + if (priv->supplicant.is_associated) + supplicant_iface_state_is_completed(self, new_state); } static gboolean -handle_auth_or_fail (NMDeviceEthernet *self, - NMActRequest *req, - gboolean new_secrets) +handle_auth_or_fail(NMDeviceEthernet *self, NMActRequest *req, gboolean new_secrets) { - const char *setting_name; - NMConnection *applied_connection; - - if (!nm_device_auth_retries_try_next (NM_DEVICE (self))) - return FALSE; - - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - - 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); - if (!setting_name) { - _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - return FALSE; - } - - _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); - - 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)); - return TRUE; + const char * setting_name; + NMConnection *applied_connection; + + if (!nm_device_auth_retries_try_next(NM_DEVICE(self))) + return FALSE; + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); + + 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); + if (!setting_name) { + _LOGI(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + return FALSE; + } + + _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); + + 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)); + return TRUE; } static gboolean -supplicant_connection_timeout_cb (gpointer user_data) +supplicant_connection_timeout_cb(gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMActRequest *req; - NMSettingsConnection *connection; - guint64 timestamp = 0; - gboolean new_secrets = TRUE; - - priv->supplicant.con_timeout_id = 0; - - /* 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. */ - _LOGW (LOGD_DEVICE | LOGD_ETHER, - "Activation: (ethernet) association took too long."); - - req = nm_device_get_act_request (device); - connection = nm_act_request_get_settings_connection (req); - - /* 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. */ - if (nm_settings_connection_get_timestamp (connection, ×tamp)) - new_secrets = !timestamp; - - if (!handle_auth_or_fail (self, req, new_secrets)) { - wired_auth_cond_fail (self, NM_DEVICE_STATE_REASON_NO_SECRETS); - return G_SOURCE_REMOVE; - } - - if ( !priv->supplicant.lnk_timeout_id - && priv->supplicant.iface) { - NMSupplicantInterfaceState state; - - state = nm_supplicant_interface_get_state (priv->supplicant.iface); - if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED - && nm_supplicant_interface_state_is_operational (state)) - priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self); - } - - return G_SOURCE_REMOVE; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMActRequest * req; + NMSettingsConnection * connection; + guint64 timestamp = 0; + gboolean new_secrets = TRUE; + + priv->supplicant.con_timeout_id = 0; + + /* 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. */ + _LOGW(LOGD_DEVICE | LOGD_ETHER, "Activation: (ethernet) association took too long."); + + req = nm_device_get_act_request(device); + connection = nm_act_request_get_settings_connection(req); + + /* 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. */ + if (nm_settings_connection_get_timestamp(connection, ×tamp)) + new_secrets = !timestamp; + + if (!handle_auth_or_fail(self, req, new_secrets)) { + wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_NO_SECRETS); + return G_SOURCE_REMOVE; + } + + if (!priv->supplicant.lnk_timeout_id && priv->supplicant.iface) { + NMSupplicantInterfaceState state; + + state = nm_supplicant_interface_get_state(priv->supplicant.iface); + if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED + && nm_supplicant_interface_state_is_operational(state)) + priv->supplicant.lnk_timeout_id = + g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self); + } + + return G_SOURCE_REMOVE; } static void -supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager, - NMSupplMgrCreateIfaceHandle *handle, - NMSupplicantInterface *iface, - GError *error, - gpointer user_data) +supplicant_interface_create_cb(NMSupplicantManager * supplicant_manager, + NMSupplMgrCreateIfaceHandle *handle, + NMSupplicantInterface * iface, + GError * error, + gpointer user_data) { - NMDeviceEthernet *self; - NMDeviceEthernetPrivate *priv; - guint timeout; - - if (nm_utils_error_is_cancelled (error)) - return; - - self = user_data; - priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - nm_assert (priv->supplicant.create_handle == handle); - priv->supplicant.create_handle = NULL; - - if (error) { - _LOGE (LOGD_DEVICE | LOGD_ETHER, - "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; - } - - priv->supplicant.iface = g_object_ref (iface); - priv->supplicant.is_associated = FALSE; - - priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface, - NM_SUPPLICANT_INTERFACE_STATE, - G_CALLBACK (supplicant_iface_state_cb), - self); - - timeout = nm_device_get_supplicant_timeout (NM_DEVICE (self)); - priv->supplicant.con_timeout_id = g_timeout_add_seconds (timeout, - supplicant_connection_timeout_cb, - self); - - if (nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (iface))) - supplicant_iface_start (self); + NMDeviceEthernet * self; + NMDeviceEthernetPrivate *priv; + guint timeout; + + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + + nm_assert(priv->supplicant.create_handle == handle); + priv->supplicant.create_handle = NULL; + + if (error) { + _LOGE(LOGD_DEVICE | LOGD_ETHER, + "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; + } + + priv->supplicant.iface = g_object_ref(iface); + priv->supplicant.is_associated = FALSE; + + priv->supplicant.iface_state_id = g_signal_connect(priv->supplicant.iface, + NM_SUPPLICANT_INTERFACE_STATE, + G_CALLBACK(supplicant_iface_state_cb), + self); + + timeout = nm_device_get_supplicant_timeout(NM_DEVICE(self)); + priv->supplicant.con_timeout_id = + g_timeout_add_seconds(timeout, supplicant_connection_timeout_cb, self); + + if (nm_supplicant_interface_state_is_operational(nm_supplicant_interface_get_state(iface))) + supplicant_iface_start(self); } static NMPlatformLinkDuplexType -link_duplex_to_platform (const char *duplex) +link_duplex_to_platform(const char *duplex) { - if (!duplex) - return NM_PLATFORM_LINK_DUPLEX_UNKNOWN; - if (nm_streq (duplex, "full")) - return NM_PLATFORM_LINK_DUPLEX_FULL; - if (nm_streq (duplex, "half")) - return NM_PLATFORM_LINK_DUPLEX_HALF; - g_return_val_if_reached (NM_PLATFORM_LINK_DUPLEX_UNKNOWN); + if (!duplex) + return NM_PLATFORM_LINK_DUPLEX_UNKNOWN; + if (nm_streq(duplex, "full")) + return NM_PLATFORM_LINK_DUPLEX_FULL; + if (nm_streq(duplex, "half")) + return NM_PLATFORM_LINK_DUPLEX_HALF; + g_return_val_if_reached(NM_PLATFORM_LINK_DUPLEX_UNKNOWN); } static void -link_negotiation_set (NMDevice *device) +link_negotiation_set(NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingWired *s_wired; - gboolean autoneg = TRUE; - gboolean link_autoneg; - NMPlatformLinkDuplexType duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN; - NMPlatformLinkDuplexType link_duplex; - guint32 speed = 0; - guint32 link_speed; - - s_wired = nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); - if (s_wired) { - autoneg = nm_setting_wired_get_auto_negotiate (s_wired); - speed = nm_setting_wired_get_speed (s_wired); - duplex = link_duplex_to_platform (nm_setting_wired_get_duplex (s_wired)); - if ( !autoneg - && !speed - && !duplex) { - _LOGD (LOGD_DEVICE, "set-link: ignore link negotiation"); - return; - } - } - - if (!nm_platform_ethtool_get_link_settings (nm_device_get_platform (device), - nm_device_get_ifindex (device), - &link_autoneg, - &link_speed, - &link_duplex)) { - _LOGW (LOGD_DEVICE, "set-link: unable to retrieve link negotiation"); - return; - } - - /* If link negotiation setting are already in place do nothing and return with success */ - if ( !!autoneg == !!link_autoneg - && speed == link_speed - && duplex == link_duplex) { - _LOGD (LOGD_DEVICE, "set-link: link negotiation is already configured"); - return; - } - - if ( autoneg - && !speed - && !duplex) - _LOGD (LOGD_DEVICE, "set-link: configure auto-negotiation"); - else { - _LOGD (LOGD_DEVICE, "set-link: configure %snegotiation (%u Mbit%s, %s duplex%s)", - autoneg ? "auto-" : "static ", - speed ?: link_speed, - speed ? "" : "*", - duplex - ? nm_platform_link_duplex_type_to_string (duplex) - : nm_platform_link_duplex_type_to_string (link_duplex), - duplex ? "" : "*"); - } - - if (!priv->ethtool_prev_set) { - /* remember the values we had before setting it. */ - priv->ethtool_prev_autoneg = link_autoneg; - priv->ethtool_prev_speed = link_speed; - priv->ethtool_prev_duplex = link_duplex; - priv->ethtool_prev_set = TRUE; - } - - if (!nm_platform_ethtool_set_link_settings (nm_device_get_platform (device), - nm_device_get_ifindex (device), - autoneg, - speed, - duplex)) { - _LOGW (LOGD_DEVICE, "set-link: failure to set link negotiation"); - return; - } + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSettingWired * s_wired; + gboolean autoneg = TRUE; + gboolean link_autoneg; + NMPlatformLinkDuplexType duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN; + NMPlatformLinkDuplexType link_duplex; + guint32 speed = 0; + guint32 link_speed; + + s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED); + if (s_wired) { + autoneg = nm_setting_wired_get_auto_negotiate(s_wired); + speed = nm_setting_wired_get_speed(s_wired); + duplex = link_duplex_to_platform(nm_setting_wired_get_duplex(s_wired)); + if (!autoneg && !speed && !duplex) { + _LOGD(LOGD_DEVICE, "set-link: ignore link negotiation"); + return; + } + } + + if (!nm_platform_ethtool_get_link_settings(nm_device_get_platform(device), + nm_device_get_ifindex(device), + &link_autoneg, + &link_speed, + &link_duplex)) { + _LOGW(LOGD_DEVICE, "set-link: unable to retrieve link negotiation"); + return; + } + + /* If link negotiation setting are already in place do nothing and return with success */ + if (!!autoneg == !!link_autoneg && speed == link_speed && duplex == link_duplex) { + _LOGD(LOGD_DEVICE, "set-link: link negotiation is already configured"); + return; + } + + if (autoneg && !speed && !duplex) + _LOGD(LOGD_DEVICE, "set-link: configure auto-negotiation"); + else { + _LOGD(LOGD_DEVICE, + "set-link: configure %snegotiation (%u Mbit%s, %s duplex%s)", + autoneg ? "auto-" : "static ", + speed ?: link_speed, + speed ? "" : "*", + duplex ? nm_platform_link_duplex_type_to_string(duplex) + : nm_platform_link_duplex_type_to_string(link_duplex), + duplex ? "" : "*"); + } + + if (!priv->ethtool_prev_set) { + /* remember the values we had before setting it. */ + priv->ethtool_prev_autoneg = link_autoneg; + priv->ethtool_prev_speed = link_speed; + priv->ethtool_prev_duplex = link_duplex; + priv->ethtool_prev_set = TRUE; + } + + if (!nm_platform_ethtool_set_link_settings(nm_device_get_platform(device), + nm_device_get_ifindex(device), + autoneg, + speed, + duplex)) { + _LOGW(LOGD_DEVICE, "set-link: failure to set link negotiation"); + return; + } } static gboolean -pppoe_reconnect_delay (gpointer user_data) +pppoe_reconnect_delay(gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - priv->pppoe_wait_id = 0; - priv->last_pppoe_time = 0; - _LOGI (LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection..."); - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); - return G_SOURCE_REMOVE; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + + priv->pppoe_wait_id = 0; + priv->last_pppoe_time = 0; + _LOGI(LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection..."); + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); + return G_SOURCE_REMOVE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - 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; - } - - link_negotiation_set (device); - - /* 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 - * remote side to handle the disconnection. Otherwise the peer may - * get confused and fail to negotiate the new connection. (rh #1023503) - * - * FIXME(shutdown): when exiting, we also need to wait before quiting, - * at least for additional NM_SHUTDOWN_TIMEOUT_MS seconds because - * otherwise after restart the device won't work for the first seconds. - */ - if (priv->last_pppoe_time != 0) { - gint32 delay = nm_utils_get_monotonic_timestamp_sec () - priv->last_pppoe_time; - - if ( delay < PPPOE_RECONNECT_DELAY - && nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE)) { - if (priv->pppoe_wait_id == 0) { - _LOGI (LOGD_DEVICE, "delaying PPPoE reconnect for %d seconds to ensure peer is ready...", - delay); - priv->pppoe_wait_id = g_timeout_add_seconds (delay, - pppoe_reconnect_delay, - self); - } - return NM_ACT_STAGE_RETURN_POSTPONE; - } - nm_clear_g_source (&priv->pppoe_wait_id); - priv->last_pppoe_time = 0; - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + + 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; + } + + link_negotiation_set(device); + + /* 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 + * remote side to handle the disconnection. Otherwise, the peer may + * get confused and fail to negotiate the new connection. (rh #1023503) + * + * FIXME(shutdown): when exiting, we also need to wait before quitting, + * at least for additional NM_SHUTDOWN_TIMEOUT_MS seconds because + * otherwise after restart the device won't work for the first seconds. + */ + if (priv->last_pppoe_time != 0) { + gint32 delay = nm_utils_get_monotonic_timestamp_sec() - priv->last_pppoe_time; + + if (delay < PPPOE_RECONNECT_DELAY + && nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE)) { + if (priv->pppoe_wait_id == 0) { + _LOGI(LOGD_DEVICE, + "delaying PPPoE reconnect for %d seconds to ensure peer is ready...", + delay); + priv->pppoe_wait_id = g_timeout_add_seconds(delay, pppoe_reconnect_delay, self); + } + return NM_ACT_STAGE_RETURN_POSTPONE; + } + nm_clear_g_source(&priv->pppoe_wait_id); + priv->last_pppoe_time = 0; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -supplicant_check_secrets_needed (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason) +supplicant_check_secrets_needed(NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMConnection *connection; - NMSetting8021x *security; - const char *setting_name; - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - security = nm_connection_get_setting_802_1x (connection); - if (!security) { - _LOGE (LOGD_DEVICE, "Invalid or missing 802.1X security"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (!priv->supplicant.mgr) - priv->supplicant.mgr = g_object_ref (nm_supplicant_manager_get ()); - - /* If we need secrets, get them */ - setting_name = nm_connection_need_secrets (connection, NULL); - if (setting_name) { - NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self)); - - _LOGI (LOGD_DEVICE | LOGD_ETHER, - "Activation: (ethernet) connection '%s' has security, but secrets are required.", - nm_connection_get_id (connection)); - - if (!handle_auth_or_fail (self, req, FALSE)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - return NM_ACT_STAGE_RETURN_FAILURE; - } - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - _LOGI (LOGD_DEVICE | LOGD_ETHER, - "Activation: (ethernet) connection '%s' requires no security. No secrets needed.", - nm_connection_get_id (connection)); - - supplicant_interface_release (self); - - 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; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMConnection * connection; + NMSetting8021x * security; + const char * setting_name; + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + security = nm_connection_get_setting_802_1x(connection); + if (!security) { + _LOGE(LOGD_DEVICE, "Invalid or missing 802.1X security"); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (!priv->supplicant.mgr) + priv->supplicant.mgr = g_object_ref(nm_supplicant_manager_get()); + + /* If we need secrets, get them */ + setting_name = nm_connection_need_secrets(connection, NULL); + if (setting_name) { + NMActRequest *req = nm_device_get_act_request(NM_DEVICE(self)); + + _LOGI(LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' has security, but secrets are required.", + nm_connection_get_id(connection)); + + if (!handle_auth_or_fail(self, req, FALSE)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + return NM_ACT_STAGE_RETURN_FAILURE; + } + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + _LOGI(LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id(connection)); + + supplicant_interface_release(self); + + 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; } static void -carrier_changed (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceEthernet *self) +carrier_changed(NMSupplicantInterface *iface, GParamSpec *pspec, NMDeviceEthernet *self) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDeviceStateReason reason; - NMActStageReturn ret; - - if (!nm_device_has_carrier (NM_DEVICE (self))) - return; - - _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); - } + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMDeviceStateReason reason; + NMActStageReturn ret; + + if (!nm_device_has_carrier(NM_DEVICE(self))) + return; + + _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); + } } /*****************************************************************************/ /* PPPoE */ static void -ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) +ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - - switch (status) { - case NM_PPP_STATUS_DISCONNECT: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); - break; - case NM_PPP_STATUS_DEAD: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); - break; - default: - break; - } + NMDevice *device = NM_DEVICE(user_data); + + switch (status) { + case NM_PPP_STATUS_DISCONNECT: + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT); + break; + case NM_PPP_STATUS_DEAD: + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); + break; + default: + break; + } } static void -ppp_ifindex_set (NMPPPManager *ppp_manager, - int ifindex, - const char *iface, - gpointer user_data) +ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - if (!nm_device_set_ip_ifindex (device, ifindex)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } + if (!nm_device_set_ip_ifindex(device, ifindex)) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } } static void -ppp_ip4_config (NMPPPManager *ppp_manager, - NMIP4Config *config, - gpointer user_data) +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - /* Ignore PPP IP4 events that come in after initial configuration */ - if (nm_device_activate_ip4_state_in_conf (device)) - nm_device_activate_schedule_ip_config_result (device, AF_INET, NM_IP_CONFIG_CAST (config)); + /* Ignore PPP IP4 events that come in after initial configuration */ + if (nm_device_activate_ip4_state_in_conf(device)) + nm_device_activate_schedule_ip_config_result(device, AF_INET, NM_IP_CONFIG_CAST(config)); } static NMActStageReturn -pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason) +pppoe_stage3_ip4_config_start(NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason) { - NMDevice *device = NM_DEVICE (self); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingPppoe *s_pppoe; - NMActRequest *req; - GError *err = NULL; - - req = nm_device_get_act_request (device); - - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - s_pppoe = nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE); - - g_return_val_if_fail (s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); - - priv->ppp_manager = nm_ppp_manager_create (nm_device_get_iface (device), - &err); - - if (priv->ppp_manager) { - nm_ppp_manager_set_route_parameters (priv->ppp_manager, - nm_device_get_route_table (device, AF_INET), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_table (device, AF_INET6), - nm_device_get_route_metric (device, AF_INET6)); - } - - if ( !priv->ppp_manager - || !nm_ppp_manager_start (priv->ppp_manager, req, - nm_setting_pppoe_get_username (s_pppoe), - 30, 0, &err)) { - _LOGW (LOGD_DEVICE, "PPPoE failed to start: %s", err->message); - g_error_free (err); - - g_clear_object (&priv->ppp_manager); - - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, - G_CALLBACK (ppp_state_changed), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, - G_CALLBACK (ppp_ifindex_set), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, - G_CALLBACK (ppp_ip4_config), - self); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDevice * device = NM_DEVICE(self); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSettingPppoe * s_pppoe; + NMActRequest * req; + GError * err = NULL; + + req = nm_device_get_act_request(device); + + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + s_pppoe = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE); + + g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); + + priv->ppp_manager = nm_ppp_manager_create(nm_device_get_iface(device), &err); + + if (priv->ppp_manager) { + nm_ppp_manager_set_route_parameters(priv->ppp_manager, + nm_device_get_route_table(device, AF_INET), + nm_device_get_route_metric(device, AF_INET), + nm_device_get_route_table(device, AF_INET6), + nm_device_get_route_metric(device, AF_INET6)); + } + + if (!priv->ppp_manager + || !nm_ppp_manager_start(priv->ppp_manager, + req, + nm_setting_pppoe_get_username(s_pppoe), + 30, + 0, + &err)) { + _LOGW(LOGD_DEVICE, "PPPoE failed to start: %s", err->message); + g_error_free(err); + + g_clear_object(&priv->ppp_manager); + + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, + G_CALLBACK(ppp_state_changed), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, + G_CALLBACK(ppp_ifindex_set), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, + G_CALLBACK(ppp_ip4_config), + self); + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ -static void dcb_state (NMDevice *device, gboolean timeout); +static void dcb_state(NMDevice *device, gboolean timeout); static gboolean -dcb_carrier_timeout (gpointer user_data) +dcb_carrier_timeout(gpointer user_data) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (user_data); - - g_return_val_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE); - - priv->dcb_timeout_id = 0; - if (priv->dcb_wait != DCB_WAIT_CARRIER_POSTCONFIG_DOWN) { - _LOGW (LOGD_DCB, "DCB: timed out waiting for carrier (step %d)", - priv->dcb_wait); - } - dcb_state (device, TRUE); - return G_SOURCE_REMOVE; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(user_data); + + g_return_val_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE); + + priv->dcb_timeout_id = 0; + if (priv->dcb_wait != DCB_WAIT_CARRIER_POSTCONFIG_DOWN) { + _LOGW(LOGD_DCB, "DCB: timed out waiting for carrier (step %d)", priv->dcb_wait); + } + dcb_state(device, TRUE); + return G_SOURCE_REMOVE; } static gboolean -dcb_configure (NMDevice *device) +dcb_configure(NMDevice *device) { - NMDeviceEthernet *self = (NMDeviceEthernet *) device; - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingDcb *s_dcb; - GError *error = NULL; - - nm_clear_g_source (&priv->dcb_timeout_id); - - s_dcb = nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); - - g_return_val_if_fail (s_dcb, FALSE); - - 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); - g_clear_error (&error); - return FALSE; - } - - /* Pause again just in case the device takes the carrier down when - * setting specific DCB attributes. - */ - _LOGD (LOGD_DCB, "waiting for carrier (postconfig down)"); - priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_DOWN; - priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); - return TRUE; + NMDeviceEthernet * self = (NMDeviceEthernet *) device; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSettingDcb * s_dcb; + GError * error = NULL; + + nm_clear_g_source(&priv->dcb_timeout_id); + + s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB); + + g_return_val_if_fail(s_dcb, FALSE); + + 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); + g_clear_error(&error); + return FALSE; + } + + /* Pause again just in case the device takes the carrier down when + * setting specific DCB attributes. + */ + _LOGD(LOGD_DCB, "waiting for carrier (postconfig down)"); + 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) +dcb_enable(NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - GError *error = NULL; - - nm_clear_g_source (&priv->dcb_timeout_id); - if (!nm_dcb_enable (nm_device_get_iface (device), TRUE, &error)) { - _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", - error->message); - g_clear_error (&error); - return FALSE; - } - - /* 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. - */ - _LOGD (LOGD_DCB, "waiting for carrier (preconfig down)"); - priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_DOWN; - priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); - return TRUE; + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + GError * error = NULL; + + nm_clear_g_source(&priv->dcb_timeout_id); + if (!nm_dcb_enable(nm_device_get_iface(device), TRUE, &error)) { + _LOGW(LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", error->message); + g_clear_error(&error); + return FALSE; + } + + /* 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. + */ + _LOGD(LOGD_DCB, "waiting for carrier (preconfig down)"); + 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) +dcb_state(NMDevice *device, gboolean timeout) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - gboolean carrier; - - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); - - carrier = nm_platform_link_is_connected (nm_device_get_platform (device), nm_device_get_ifindex (device)); - _LOGD (LOGD_DCB, "dcb_state() wait %d carrier %d timeout %d", priv->dcb_wait, carrier, timeout); - - switch (priv->dcb_wait) { - case DCB_WAIT_CARRIER_PREENABLE_UP: - if (timeout || carrier) { - _LOGD (LOGD_DCB, "dcb_state() enabling DCB"); - nm_clear_g_source (&priv->dcb_timeout_id); - if (!dcb_enable (device)) { - priv->dcb_handle_carrier_changes = FALSE; - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); - } - } - break; - case DCB_WAIT_CARRIER_PRECONFIG_DOWN: - nm_clear_g_source (&priv->dcb_timeout_id); - priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_UP; - - if (!carrier) { - /* Wait for the carrier to come back up */ - _LOGD (LOGD_DCB, "waiting for carrier (preconfig up)"); - priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); - break; - } - _LOGD (LOGD_DCB, "dcb_state() preconfig down falling through"); - /* fall-through */ - case DCB_WAIT_CARRIER_PRECONFIG_UP: - if (timeout || carrier) { - _LOGD (LOGD_DCB, "dcb_state() preconfig up configuring DCB"); - nm_clear_g_source (&priv->dcb_timeout_id); - if (!dcb_configure (device)) { - priv->dcb_handle_carrier_changes = FALSE; - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); - } - } - break; - case DCB_WAIT_CARRIER_POSTCONFIG_DOWN: - nm_clear_g_source (&priv->dcb_timeout_id); - priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_UP; - - if (!carrier) { - /* Wait for the carrier to come back up */ - _LOGD (LOGD_DCB, "waiting for carrier (postconfig up)"); - priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); - break; - } - _LOGD (LOGD_DCB, "dcb_state() postconfig down falling through"); - /* fall-through */ - case DCB_WAIT_CARRIER_POSTCONFIG_UP: - if (timeout || carrier) { - _LOGD (LOGD_DCB, "dcb_state() postconfig up starting IP"); - nm_clear_g_source (&priv->dcb_timeout_id); - priv->dcb_handle_carrier_changes = FALSE; - priv->dcb_wait = DCB_WAIT_UNKNOWN; - nm_device_activate_schedule_stage3_ip_config_start (device); - } - break; - default: - g_assert_not_reached (); - } + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + gboolean carrier; + + g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG); + + carrier = nm_platform_link_is_connected(nm_device_get_platform(device), + nm_device_get_ifindex(device)); + _LOGD(LOGD_DCB, "dcb_state() wait %d carrier %d timeout %d", priv->dcb_wait, carrier, timeout); + + switch (priv->dcb_wait) { + case DCB_WAIT_CARRIER_PREENABLE_UP: + if (timeout || carrier) { + _LOGD(LOGD_DCB, "dcb_state() enabling DCB"); + nm_clear_g_source(&priv->dcb_timeout_id); + if (!dcb_enable(device)) { + priv->dcb_handle_carrier_changes = FALSE; + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); + } + } + break; + case DCB_WAIT_CARRIER_PRECONFIG_DOWN: + nm_clear_g_source(&priv->dcb_timeout_id); + priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_UP; + + if (!carrier) { + /* Wait for the carrier to come back up */ + _LOGD(LOGD_DCB, "waiting for carrier (preconfig up)"); + priv->dcb_timeout_id = g_timeout_add_seconds(5, dcb_carrier_timeout, device); + break; + } + _LOGD(LOGD_DCB, "dcb_state() preconfig down falling through"); + /* fall-through */ + case DCB_WAIT_CARRIER_PRECONFIG_UP: + if (timeout || carrier) { + _LOGD(LOGD_DCB, "dcb_state() preconfig up configuring DCB"); + nm_clear_g_source(&priv->dcb_timeout_id); + if (!dcb_configure(device)) { + priv->dcb_handle_carrier_changes = FALSE; + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); + } + } + break; + case DCB_WAIT_CARRIER_POSTCONFIG_DOWN: + nm_clear_g_source(&priv->dcb_timeout_id); + priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_UP; + + if (!carrier) { + /* Wait for the carrier to come back up */ + _LOGD(LOGD_DCB, "waiting for carrier (postconfig up)"); + priv->dcb_timeout_id = g_timeout_add_seconds(5, dcb_carrier_timeout, device); + break; + } + _LOGD(LOGD_DCB, "dcb_state() postconfig down falling through"); + /* fall-through */ + case DCB_WAIT_CARRIER_POSTCONFIG_UP: + if (timeout || carrier) { + _LOGD(LOGD_DCB, "dcb_state() postconfig up starting IP"); + nm_clear_g_source(&priv->dcb_timeout_id); + priv->dcb_handle_carrier_changes = FALSE; + priv->dcb_wait = DCB_WAIT_UNKNOWN; + nm_device_activate_schedule_stage3_ip_config_start(device); + } + break; + default: + g_assert_not_reached(); + } } /*****************************************************************************/ static gboolean -wake_on_lan_enable (NMDevice *device) +wake_on_lan_enable(NMDevice *device) { - NMSettingWiredWakeOnLan wol; - NMSettingWired *s_wired; - const char *password = NULL; - - s_wired = nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); - - 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; - } - - wol = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ethernet.wake-on-lan"), - device, - NM_SETTING_WIRED_WAKE_ON_LAN_NONE, - G_MAXINT32, - NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); - - 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; - } - if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) - goto found; - wol = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + NMSettingWiredWakeOnLan wol; + NMSettingWired * s_wired; + const char * password = NULL; + + s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED); + + 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; + } + + wol = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ethernet.wake-on-lan"), + device, + NM_SETTING_WIRED_WAKE_ON_LAN_NONE, + G_MAXINT32, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); + + 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; + } + if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) + goto found; + wol = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; found: - return nm_platform_ethtool_set_wake_on_lan (nm_device_get_platform (device), - nm_device_get_ifindex (device), - wol, password); + return nm_platform_ethtool_set_wake_on_lan(nm_device_get_platform(device), + nm_device_get_ifindex(device), + wol, + password); } /*****************************************************************************/ static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceEthernet *self = (NMDeviceEthernet *) device; - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingConnection *s_con; - const char *connection_type; - gboolean do_postpone = FALSE; - NMSettingDcb *s_dcb; - - s_con = nm_device_get_applied_setting (device, NM_TYPE_SETTING_CONNECTION); - - g_return_val_if_fail (s_con, NM_ACT_STAGE_RETURN_FAILURE); - - nm_clear_g_source (&priv->dcb_timeout_id); - priv->dcb_handle_carrier_changes = FALSE; - - /* 802.1x has to run before any IP configuration since the 802.1x auth - * process opens the port up for normal traffic. - */ - connection_type = nm_setting_connection_get_connection_type (s_con); - if (nm_streq (connection_type, NM_SETTING_WIRED_SETTING_NAME)) { - NMSetting8021x *security; - - security = nm_device_get_applied_setting (device, NM_TYPE_SETTING_802_1X); - - if (security) { - /* FIXME: for now 802.1x is mutually exclusive with DCB */ - 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; - } - - return supplicant_check_secrets_needed (self, out_failure_reason); - } - } - - wake_on_lan_enable (device); - - /* DCB and FCoE setup */ - s_dcb = nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); - if (s_dcb) { - /* lldpad really really wants the carrier to be up */ - if (nm_platform_link_is_connected (nm_device_get_platform (device), nm_device_get_ifindex (device))) { - if (!dcb_enable (device)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } else { - _LOGD (LOGD_DCB, "waiting for carrier (preenable up)"); - priv->dcb_wait = DCB_WAIT_CARRIER_PREENABLE_UP; - priv->dcb_timeout_id = g_timeout_add_seconds (4, dcb_carrier_timeout, device); - } - - priv->dcb_handle_carrier_changes = TRUE; - do_postpone = TRUE; - } - - /* PPPoE setup */ - if (nm_connection_is_type (nm_device_get_applied_connection (device), - NM_SETTING_PPPOE_SETTING_NAME)) { - 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); - } - } - } - - return do_postpone - ? NM_ACT_STAGE_RETURN_POSTPONE - : NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceEthernet * self = (NMDeviceEthernet *) device; + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSettingConnection * s_con; + const char * connection_type; + gboolean do_postpone = FALSE; + NMSettingDcb * s_dcb; + + s_con = nm_device_get_applied_setting(device, NM_TYPE_SETTING_CONNECTION); + + g_return_val_if_fail(s_con, NM_ACT_STAGE_RETURN_FAILURE); + + nm_clear_g_source(&priv->dcb_timeout_id); + priv->dcb_handle_carrier_changes = FALSE; + + /* 802.1x has to run before any IP configuration since the 802.1x auth + * process opens the port up for normal traffic. + */ + connection_type = nm_setting_connection_get_connection_type(s_con); + if (nm_streq(connection_type, NM_SETTING_WIRED_SETTING_NAME)) { + NMSetting8021x *security; + + security = nm_device_get_applied_setting(device, NM_TYPE_SETTING_802_1X); + + if (security) { + /* FIXME: for now 802.1x is mutually exclusive with DCB */ + 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; + } + + return supplicant_check_secrets_needed(self, out_failure_reason); + } + } + + wake_on_lan_enable(device); + + /* DCB and FCoE setup */ + s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB); + if (s_dcb) { + /* lldpad really really wants the carrier to be up */ + if (nm_platform_link_is_connected(nm_device_get_platform(device), + nm_device_get_ifindex(device))) { + if (!dcb_enable(device)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } else { + _LOGD(LOGD_DCB, "waiting for carrier (preenable up)"); + priv->dcb_wait = DCB_WAIT_CARRIER_PREENABLE_UP; + priv->dcb_timeout_id = g_timeout_add_seconds(4, dcb_carrier_timeout, device); + } + + priv->dcb_handle_carrier_changes = TRUE; + do_postpone = TRUE; + } + + /* PPPoE setup */ + if (nm_connection_is_type(nm_device_get_applied_connection(device), + NM_SETTING_PPPOE_SETTING_NAME)) { + 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); + } + } + } + + return do_postpone ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - NMSettingConnection *s_con; - const char *connection_type; + NMSettingConnection *s_con; + const char * connection_type; - if (addr_family == AF_INET) { - s_con = nm_device_get_applied_setting (device, NM_TYPE_SETTING_CONNECTION); + if (addr_family == AF_INET) { + s_con = nm_device_get_applied_setting(device, NM_TYPE_SETTING_CONNECTION); - g_return_val_if_fail (s_con, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail(s_con, NM_ACT_STAGE_RETURN_FAILURE); - connection_type = nm_setting_connection_get_connection_type (s_con); - if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) - return pppoe_stage3_ip4_config_start (NM_DEVICE_ETHERNET (device), out_failure_reason); - } + connection_type = nm_setting_connection_get_connection_type(s_con); + if (!strcmp(connection_type, NM_SETTING_PPPOE_SETTING_NAME)) + return pppoe_stage3_ip4_config_start(NM_DEVICE_ETHERNET(device), out_failure_reason); + } - return NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_ethernet_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - /* MTU only set for plain ethernet */ - if (NM_DEVICE_ETHERNET_GET_PRIVATE (device)->ppp_manager) - return 0; + /* MTU only set for plain ethernet */ + if (NM_DEVICE_ETHERNET_GET_PRIVATE(device)->ppp_manager) + return 0; - return nm_device_get_configured_mtu_for_wired (device, out_source, out_force); + return nm_device_get_configured_mtu_for_wired(device, out_source, out_force); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - NMSettingDcb *s_dcb; - GError *error = NULL; - - nm_clear_g_source (&priv->pppoe_wait_id); - nm_clear_g_signal_handler (self, &priv->carrier_id); - - if (priv->ppp_manager) { - nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL); - g_clear_object (&priv->ppp_manager); - } - - supplicant_interface_release (self); - - priv->dcb_wait = DCB_WAIT_UNKNOWN; - nm_clear_g_source (&priv->dcb_timeout_id); - priv->dcb_handle_carrier_changes = FALSE; - - /* Tear down DCB/FCoE if it was enabled */ - s_dcb = nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); - if (s_dcb) { - if (!nm_dcb_cleanup (nm_device_get_iface (device), &error)) { - _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "failed to disable DCB/FCoE: %s", - error->message); - g_clear_error (&error); - } - } - - /* Set last PPPoE connection time */ - if (nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE)) - priv->last_pppoe_time = nm_utils_get_monotonic_timestamp_sec (); - - if (priv->ethtool_prev_set) { - priv->ethtool_prev_set = FALSE; - - _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), - nm_device_get_ifindex (device), - priv->ethtool_prev_autoneg, - priv->ethtool_prev_speed, - priv->ethtool_prev_duplex)) { - _LOGW (LOGD_DEVICE, "set-link: failure to reset link negotiation"); - return; - } - } + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + NMSettingDcb * s_dcb; + GError * error = NULL; + + nm_clear_g_source(&priv->pppoe_wait_id); + nm_clear_g_signal_handler(self, &priv->carrier_id); + + if (priv->ppp_manager) { + nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); + g_clear_object(&priv->ppp_manager); + } + + supplicant_interface_release(self); + + priv->dcb_wait = DCB_WAIT_UNKNOWN; + nm_clear_g_source(&priv->dcb_timeout_id); + priv->dcb_handle_carrier_changes = FALSE; + + /* Tear down DCB/FCoE if it was enabled */ + s_dcb = nm_device_get_applied_setting(device, NM_TYPE_SETTING_DCB); + if (s_dcb) { + if (!nm_dcb_cleanup(nm_device_get_iface(device), &error)) { + _LOGW(LOGD_DEVICE | LOGD_PLATFORM, "failed to disable DCB/FCoE: %s", error->message); + g_clear_error(&error); + } + } + + /* Set last PPPoE connection time */ + if (nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE)) + priv->last_pppoe_time = nm_utils_get_monotonic_timestamp_sec(); + + if (priv->ethtool_prev_set) { + priv->ethtool_prev_set = FALSE; + + _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), + nm_device_get_ifindex(device), + priv->ethtool_prev_autoneg, + priv->ethtool_prev_speed, + priv->ethtool_prev_duplex)) { + _LOGW(LOGD_DEVICE, "set-link: failure to reset link negotiation"); + return; + } + } } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingWired *s_wired; - NMSettingPppoe *s_pppoe; - - s_pppoe = nm_connection_get_setting_pppoe (connection); - - /* 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; - - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired) { - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - } - - /* Default to an ethernet-only connection, but if a PPPoE setting was given - * then PPPoE should be our connection type. - */ - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME, - existing_connections, - NULL, - s_pppoe ? _("PPPoE connection") : _("Wired connection"), - NULL, - nm_setting_wired_get_mac_address (s_wired) ? NULL : nm_device_get_iface (device), - s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ - - return TRUE; + NMSettingWired *s_wired; + NMSettingPppoe *s_pppoe; + + s_pppoe = nm_connection_get_setting_pppoe(connection); + + /* 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; + + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired) { + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); + } + + /* Default to an ethernet-only connection, but if a PPPoE setting was given + * then PPPoE should be our connection type. + */ + nm_utils_complete_generic( + nm_device_get_platform(device), + connection, + s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME, + existing_connections, + NULL, + s_pppoe ? _("PPPoE connection") : _("Wired connection"), + NULL, + nm_setting_wired_get_mac_address(s_wired) ? NULL : nm_device_get_iface(device), + s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ + + return TRUE; } static NMConnection * -new_default_connection (NMDevice *self) +new_default_connection(NMDevice *self) { - NMConnection *connection; - NMSettingsConnection *const*connections; - NMSetting *setting; - gs_unref_hashtable GHashTable *existing_ids = NULL; - struct udev_device *dev; - const char *perm_hw_addr; - const char *iface; - const char *uprop = "0"; - gs_free char *defname = NULL; - gs_free char *uuid = NULL; - guint i, n_connections; - - perm_hw_addr = nm_device_get_permanent_hw_address (self); - iface = nm_device_get_iface (self); - - connection = nm_simple_connection_new (); - setting = nm_setting_connection_new (); - nm_connection_add_setting (connection, setting); - - 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); - if (!defname) - return NULL; - - /* 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. */ - uuid = _nm_utils_uuid_generate_from_strings ("default-wired", - nm_utils_machine_id_str (), - defname, - perm_hw_addr ?: iface, - NULL); - - g_object_set (setting, - NM_SETTING_CONNECTION_ID, defname, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), - NM_SETTING_CONNECTION_INTERFACE_NAME, iface, - NULL); - - /* 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"); - - if (nm_udev_utils_property_as_boolean (uprop)) { - 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); - - 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); - } - - return connection; + NMConnection * connection; + NMSettingsConnection *const *connections; + NMSetting * setting; + gs_unref_hashtable GHashTable *existing_ids = NULL; + struct udev_device * dev; + const char * perm_hw_addr; + const char * iface; + const char * uprop = "0"; + gs_free char * defname = NULL; + gs_free char * uuid = NULL; + guint i, n_connections; + + perm_hw_addr = nm_device_get_permanent_hw_address(self); + iface = nm_device_get_iface(self); + + connection = nm_simple_connection_new(); + setting = nm_setting_connection_new(); + nm_connection_add_setting(connection, setting); + + 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); + if (!defname) + return NULL; + + /* 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. */ + uuid = _nm_utils_uuid_generate_from_strings("default-wired", + nm_utils_machine_id_str(), + defname, + perm_hw_addr ?: iface, + NULL); + + g_object_set(setting, + NM_SETTING_CONNECTION_ID, + defname, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, + TRUE, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_UUID, + uuid, + NM_SETTING_CONNECTION_TIMESTAMP, + (guint64) time(NULL), + NM_SETTING_CONNECTION_INTERFACE_NAME, + iface, + NULL); + + /* 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"); + + if (nm_udev_utils_property_as_boolean(uprop)) { + 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); + + 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); + } + + return connection; } static const char * -get_s390_subchannels (NMDevice *device) +get_s390_subchannels(NMDevice *device) { - nm_assert (NM_IS_DEVICE_ETHERNET (device)); + nm_assert(NM_IS_DEVICE_ETHERNET(device)); - return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->subchannels; + return NM_DEVICE_ETHERNET_GET_PRIVATE(device)->subchannels; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); - 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; - gpointer key, value; - - if (!s_wired) { - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, (NMSetting *) s_wired); - } - - 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); - - /* If the device reports a permanent address, use that for the MAC address - * and the current MAC, if different, is the cloned MAC. - */ - perm_hw_addr = nm_device_get_permanent_hw_address_full (device, TRUE, &perm_hw_addr_is_fake); - if (perm_hw_addr && !perm_hw_addr_is_fake) { - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL); - - mac_prop = NULL; - if (mac && !nm_utils_hwaddr_matches (perm_hw_addr, -1, mac, -1)) - mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS; - } - - if (mac_prop && mac && nm_utils_hwaddr_valid (mac, ETH_ALEN)) - g_object_set (s_wired, mac_prop, mac, NULL); - - /* We don't set the MTU as we don't know whether it was set explicitly */ - - /* s390 */ - if (priv->subchannels_dbus) - g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, priv->subchannels_dbus, NULL); - if (priv->s390_nettype) - g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL); - - _nm_setting_wired_clear_s390_options (s_wired); - g_hash_table_iter_init (&iter, priv->s390_options); - while (g_hash_table_iter_next (&iter, &key, &value)) - nm_setting_wired_add_s390_option (s_wired, (const char *) key, (const char *) value); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device); + NMSettingWired * s_wired = nm_connection_get_setting_wired(connection); + 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; + gpointer key, value; + + if (!s_wired) { + s_wired = (NMSettingWired *) nm_setting_wired_new(); + nm_connection_add_setting(connection, (NMSetting *) s_wired); + } + + 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); + + /* If the device reports a permanent address, use that for the MAC address + * and the current MAC, if different, is the cloned MAC. + */ + perm_hw_addr = nm_device_get_permanent_hw_address_full(device, TRUE, &perm_hw_addr_is_fake); + if (perm_hw_addr && !perm_hw_addr_is_fake) { + g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL); + + mac_prop = NULL; + if (mac && !nm_utils_hwaddr_matches(perm_hw_addr, -1, mac, -1)) + mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS; + } + + if (mac_prop && mac && nm_utils_hwaddr_valid(mac, ETH_ALEN)) + g_object_set(s_wired, mac_prop, mac, NULL); + + /* We don't set the MTU as we don't know whether it was set explicitly */ + + /* s390 */ + if (priv->subchannels_dbus) + g_object_set(s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, priv->subchannels_dbus, NULL); + if (priv->s390_nettype) + g_object_set(s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL); + + _nm_setting_wired_clear_s390_options(s_wired); + g_hash_table_iter_init(&iter, priv->s390_options); + while (g_hash_table_iter_next(&iter, &key, &value)) + nm_setting_wired_add_s390_option(s_wired, (const char *) key, (const char *) value); } static void -link_speed_update (NMDevice *device) +link_speed_update(NMDevice *device) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - guint32 speed; - - if (!nm_platform_ethtool_get_link_settings (nm_device_get_platform (device), nm_device_get_ifindex (device), NULL, &speed, NULL)) - return; - if (priv->speed == speed) - return; - - priv->speed = speed; - _LOGD (LOGD_PLATFORM | LOGD_ETHER, "speed is now %d Mb/s", speed); - _notify (self, PROP_SPEED); + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + guint32 speed; + + if (!nm_platform_ethtool_get_link_settings(nm_device_get_platform(device), + nm_device_get_ifindex(device), + NULL, + &speed, + NULL)) + return; + if (priv->speed == speed) + return; + + priv->speed = speed; + _LOGD(LOGD_PLATFORM | LOGD_ETHER, "speed is now %d Mb/s", speed); + _notify(self, PROP_SPEED); } static void -carrier_changed_notify (NMDevice *device, gboolean carrier) +carrier_changed_notify(NMDevice *device, gboolean carrier) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + 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_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); - } - } + if (priv->dcb_timeout_id) { + _LOGD(LOGD_DCB, "carrier_changed() calling dcb_state()"); + dcb_state(device, FALSE); + } + } - if (carrier) - link_speed_update (device); + if (carrier) + link_speed_update(device); - NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->carrier_changed_notify (device, carrier); + NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->carrier_changed_notify(device, carrier); } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->link_changed (device, pllink); - if (pllink->initialized) - _update_s390_subchannels ((NMDeviceEthernet *) device); + NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->link_changed(device, pllink); + if (pllink->initialized) + _update_s390_subchannels((NMDeviceEthernet *) device); } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->is_available (device, flags)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->is_available(device, flags)) + return FALSE; - return !!nm_device_get_initial_hw_address (device); + return !!nm_device_get_initial_hw_address(device); } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) { - NMDeviceClass *device_class; - - /* 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, - NM_SETTING_WIRED_MTU, /* reapplied with IP config */ - 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); - } - - 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); + NMDeviceClass *device_class; + + /* 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, + NM_SETTING_WIRED_MTU, /* reapplied with IP config */ + 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); + } + + 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) +reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); - NMDeviceState state = nm_device_get_state (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET(device); + NMDeviceState state = nm_device_get_state(device); - NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->reapply_connection (device, - con_old, - con_new); + NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->reapply_connection(device, con_old, con_new); - _LOGD (LOGD_DEVICE, "reapplying wired settings"); + _LOGD(LOGD_DEVICE, "reapplying wired settings"); - if (state >= NM_DEVICE_STATE_PREPARE) - link_negotiation_set (device); - if (state >= NM_DEVICE_STATE_CONFIG) - wake_on_lan_enable (device); + if (state >= NM_DEVICE_STATE_PREPARE) + link_negotiation_set(device); + if (state >= NM_DEVICE_STATE_CONFIG) + wake_on_lan_enable(device); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); - wired_secrets_cancel (self); + wired_secrets_cancel(self); - supplicant_interface_release (self); + supplicant_interface_release(self); - nm_clear_g_source (&priv->pppoe_wait_id); + nm_clear_g_source(&priv->pppoe_wait_id); - nm_clear_g_source (&priv->dcb_timeout_id); + nm_clear_g_source(&priv->dcb_timeout_id); - nm_clear_g_signal_handler (self, &priv->carrier_id); + nm_clear_g_signal_handler(self, &priv->carrier_id); - G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_ethernet_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - g_clear_object (&priv->supplicant.mgr); - g_free (priv->subchan1); - g_free (priv->subchan2); - g_free (priv->subchan3); - g_free (priv->subchannels); - g_strfreev (priv->subchannels_dbus); - g_free (priv->s390_nettype); - g_hash_table_destroy (priv->s390_options); - - G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object); + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + + g_clear_object(&priv->supplicant.mgr); + g_free(priv->subchan1); + g_free(priv->subchan2); + g_free(priv->subchan3); + g_free(priv->subchannels); + g_strfreev(priv->subchannels_dbus); + g_free(priv->s390_nettype); + g_hash_table_destroy(priv->s390_options); + + G_OBJECT_CLASS(nm_device_ethernet_parent_class)->finalize(object); } static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_SPEED: - g_value_set_uint (value, priv->speed); - break; - case PROP_S390_SUBCHANNELS: - g_value_set_boxed (value, priv->subchannels_dbus); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceEthernet * self = NM_DEVICE_ETHERNET(object); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_SPEED: + g_value_set_uint(value, priv->speed); + break; + case PROP_S390_SUBCHANNELS: + g_value_set_boxed(value, priv->subchannels_dbus); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +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; - } + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static const NMDBusInterfaceInfoExtended interface_info_device_wired = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WIRED, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PermHwAddress", "s", NM_DEVICE_PERM_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Speed", "u", NM_DEVICE_ETHERNET_SPEED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("S390Subchannels", "as", NM_DEVICE_ETHERNET_S390_SUBCHANNELS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_WIRED, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Speed", + "u", + NM_DEVICE_ETHERNET_SPEED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("S390Subchannels", + "as", + NM_DEVICE_ETHERNET_S390_SUBCHANNELS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", + "b", + NM_DEVICE_CARRIER), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) +nm_device_ethernet_class_init(NMDeviceEthernetClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMDeviceEthernetPrivate)); - - object_class->dispose = dispose; - object_class->finalize = finalize; - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wired); - - device_class->connection_type_supported = NM_SETTING_WIRED_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_ETHERNET); - - 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; - - device_class->act_stage1_prepare_also_for_external_or_assume = TRUE; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - 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; - - device_class->state_changed = device_state_changed; - - obj_properties[PROP_SPEED] = - g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_S390_SUBCHANNELS] = - g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + g_type_class_add_private(object_class, sizeof(NMDeviceEthernetPrivate)); + + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_wired); + + device_class->connection_type_supported = NM_SETTING_WIRED_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_ETHERNET); + + 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; + + device_class->act_stage1_prepare_also_for_external_or_assume = TRUE; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + 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; + + device_class->state_changed = device_state_changed; + + obj_properties[PROP_SPEED] = g_param_spec_uint(NM_DEVICE_ETHERNET_SPEED, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_S390_SUBCHANNELS] = + g_param_spec_boxed(NM_DEVICE_ETHERNET_S390_SUBCHANNELS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#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)) +#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)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) 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); + return (NMDevice *) 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); } static gboolean -match_connection (NMDeviceFactory *factory, NMConnection *connection) +match_connection(NMDeviceFactory *factory, NMConnection *connection) { - const char *type = nm_connection_get_connection_type (connection); - NMSettingPppoe *s_pppoe; + const char * type = nm_connection_get_connection_type(connection); + NMSettingPppoe *s_pppoe; - if (nm_streq (type, NM_SETTING_WIRED_SETTING_NAME)) - return TRUE; + 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); + 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); + return !nm_setting_pppoe_get_parent(s_pppoe); } -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), - factory_class->create_device = create_device; - factory_class->match_connection = match_connection; -); +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), + factory_class->create_device = create_device; + factory_class->match_connection = match_connection;); diff --git a/src/devices/nm-device-ethernet.h b/src/devices/nm-device-ethernet.h index 08962232..36b7bc57 100644 --- a/src/devices/nm-device-ethernet.h +++ b/src/devices/nm-device-ethernet.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2010 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -9,27 +9,31 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_ETHERNET (nm_device_ethernet_get_type ()) -#define NM_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernet)) -#define NM_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) -#define NM_IS_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_ETHERNET)) -#define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) -#define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) - -#define NM_DEVICE_ETHERNET_SPEED "speed" +#define NM_TYPE_DEVICE_ETHERNET (nm_device_ethernet_get_type()) +#define NM_DEVICE_ETHERNET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernet)) +#define NM_DEVICE_ETHERNET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) +#define NM_IS_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_ETHERNET)) +#define NM_IS_DEVICE_ETHERNET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_ETHERNET)) +#define NM_DEVICE_ETHERNET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) + +#define NM_DEVICE_ETHERNET_SPEED "speed" #define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels" struct _NMDeviceEthernetPrivate; typedef struct { - NMDevice parent; - struct _NMDeviceEthernetPrivate *_priv; + NMDevice parent; + struct _NMDeviceEthernetPrivate *_priv; } NMDeviceEthernet; typedef struct { - NMDeviceClass parent; + NMDeviceClass parent; } NMDeviceEthernetClass; -GType nm_device_ethernet_get_type (void); +GType nm_device_ethernet_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_ETHERNET_H__ */ diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index a7db2669..a238ce1b 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 - 2018 Red Hat, Inc. */ @@ -20,375 +20,394 @@ /*****************************************************************************/ -enum { - DEVICE_ADDED, - LAST_SIGNAL -}; +enum { DEVICE_ADDED, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; -G_DEFINE_ABSTRACT_TYPE (NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT) +G_DEFINE_ABSTRACT_TYPE(NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT) /*****************************************************************************/ static void -nm_device_factory_get_supported_types (NMDeviceFactory *factory, - const NMLinkType **out_link_types, - const char *const**out_setting_types) +nm_device_factory_get_supported_types(NMDeviceFactory * factory, + const NMLinkType ** out_link_types, + const char *const **out_setting_types) { - g_return_if_fail (NM_IS_DEVICE_FACTORY (factory)); + g_return_if_fail(NM_IS_DEVICE_FACTORY(factory)); - NM_DEVICE_FACTORY_GET_CLASS (factory)->get_supported_types (factory, - out_link_types, - out_setting_types); + NM_DEVICE_FACTORY_GET_CLASS(factory)->get_supported_types(factory, + out_link_types, + out_setting_types); } void -nm_device_factory_start (NMDeviceFactory *factory) +nm_device_factory_start(NMDeviceFactory *factory) { - g_return_if_fail (factory != NULL); + g_return_if_fail(factory != NULL); - if (NM_DEVICE_FACTORY_GET_CLASS (factory)->start) - NM_DEVICE_FACTORY_GET_CLASS (factory)->start (factory); + if (NM_DEVICE_FACTORY_GET_CLASS(factory)->start) + NM_DEVICE_FACTORY_GET_CLASS(factory)->start(factory); } NMDevice * -nm_device_factory_create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore, - GError **error) +nm_device_factory_create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore, + GError ** error) { - NMDeviceFactoryClass *klass; - NMDevice *device; - gboolean ignore = FALSE; - - g_return_val_if_fail (factory, NULL); - g_return_val_if_fail (iface && *iface, NULL); - if (plink) { - g_return_val_if_fail (!connection, NULL); - g_return_val_if_fail (strcmp (iface, plink->name) == 0, NULL); - nm_assert (factory == nm_device_factory_manager_find_factory_for_link_type (plink->type)); - } else if (connection) - nm_assert (factory == nm_device_factory_manager_find_factory_for_connection (connection)); - else - g_return_val_if_reached (NULL); - - klass = NM_DEVICE_FACTORY_GET_CLASS (factory); - if (!klass->create_device) { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, - "Device factory %s cannot manage new devices", - G_OBJECT_TYPE_NAME (factory)); - NM_SET_OUT (out_ignore, FALSE); - return NULL; - } - - device = klass->create_device (factory, iface, plink, connection, &ignore); - NM_SET_OUT (out_ignore, ignore); - if (!device) { - if (ignore) { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, - "Device factory %s ignores device %s", - G_OBJECT_TYPE_NAME (factory), iface); - } else { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, - "Device factory %s failed to create device %s", - G_OBJECT_TYPE_NAME (factory), iface); - } - } - return device; + NMDeviceFactoryClass *klass; + NMDevice * device; + gboolean ignore = FALSE; + + g_return_val_if_fail(factory, NULL); + g_return_val_if_fail(iface && *iface, NULL); + if (plink) { + g_return_val_if_fail(!connection, NULL); + g_return_val_if_fail(strcmp(iface, plink->name) == 0, NULL); + nm_assert(factory == nm_device_factory_manager_find_factory_for_link_type(plink->type)); + } else if (connection) + nm_assert(factory == nm_device_factory_manager_find_factory_for_connection(connection)); + else + g_return_val_if_reached(NULL); + + klass = NM_DEVICE_FACTORY_GET_CLASS(factory); + if (!klass->create_device) { + g_set_error(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Device factory %s cannot manage new devices", + G_OBJECT_TYPE_NAME(factory)); + NM_SET_OUT(out_ignore, FALSE); + return NULL; + } + + device = klass->create_device(factory, iface, plink, connection, &ignore); + NM_SET_OUT(out_ignore, ignore); + if (!device) { + if (ignore) { + g_set_error(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Device factory %s ignores device %s", + G_OBJECT_TYPE_NAME(factory), + iface); + } else { + g_set_error(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Device factory %s failed to create device %s", + G_OBJECT_TYPE_NAME(factory), + iface); + } + } + return device; } const char * -nm_device_factory_get_connection_parent (NMDeviceFactory *factory, - NMConnection *connection) +nm_device_factory_get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - g_return_val_if_fail (factory != NULL, NULL); - g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail(factory != NULL, NULL); + g_return_val_if_fail(connection != NULL, NULL); - if (!nm_connection_is_virtual (connection)) - return NULL; + if (!nm_connection_is_virtual(connection)) + return NULL; - if (NM_DEVICE_FACTORY_GET_CLASS (factory)->get_connection_parent) - return NM_DEVICE_FACTORY_GET_CLASS (factory)->get_connection_parent (factory, connection); - return NULL; + if (NM_DEVICE_FACTORY_GET_CLASS(factory)->get_connection_parent) + return NM_DEVICE_FACTORY_GET_CLASS(factory)->get_connection_parent(factory, connection); + return NULL; } char * -nm_device_factory_get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface, - GError **error) +nm_device_factory_get_connection_iface(NMDeviceFactory *factory, + NMConnection * connection, + const char * parent_iface, + GError ** error) { - NMDeviceFactoryClass *klass; - char *ifname; + NMDeviceFactoryClass *klass; + char * ifname; - g_return_val_if_fail (factory != NULL, NULL); - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (!error || !*error, NULL); + g_return_val_if_fail(factory != NULL, NULL); + g_return_val_if_fail(connection != NULL, NULL); + g_return_val_if_fail(!error || !*error, NULL); - klass = NM_DEVICE_FACTORY_GET_CLASS (factory); + klass = NM_DEVICE_FACTORY_GET_CLASS(factory); - ifname = g_strdup (nm_connection_get_interface_name (connection)); - if (!ifname && klass->get_connection_iface) - ifname = klass->get_connection_iface (factory, connection, parent_iface); + ifname = g_strdup(nm_connection_get_interface_name(connection)); + if (!ifname && klass->get_connection_iface) + ifname = klass->get_connection_iface(factory, connection, parent_iface); - if (!ifname) { - g_set_error (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_FAILED, - "failed to determine interface name: error determine name for %s", - nm_connection_get_connection_type (connection)); - return NULL; - } + if (!ifname) { + g_set_error(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "failed to determine interface name: error determine name for %s", + nm_connection_get_connection_type(connection)); + return NULL; + } - return ifname; + return ifname; } /*****************************************************************************/ static void -nm_device_factory_init (NMDeviceFactory *self) -{ -} +nm_device_factory_init(NMDeviceFactory *self) +{} static void -nm_device_factory_class_init (NMDeviceFactoryClass *klass) +nm_device_factory_class_init(NMDeviceFactoryClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - signals[DEVICE_ADDED] = g_signal_new (NM_DEVICE_FACTORY_DEVICE_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, NM_TYPE_DEVICE); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + signals[DEVICE_ADDED] = g_signal_new(NM_DEVICE_FACTORY_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_DEVICE); } /*****************************************************************************/ -static GHashTable *factories_by_link = NULL; +static GHashTable *factories_by_link = NULL; static GHashTable *factories_by_setting = NULL; -static void __attribute__((destructor)) -_cleanup (void) +static void __attribute__((destructor)) _cleanup(void) { - nm_clear_pointer (&factories_by_link, g_hash_table_unref); - nm_clear_pointer (&factories_by_setting, g_hash_table_unref); + nm_clear_pointer(&factories_by_link, g_hash_table_unref); + nm_clear_pointer(&factories_by_setting, g_hash_table_unref); } NMDeviceFactory * -nm_device_factory_manager_find_factory_for_link_type (NMLinkType link_type) +nm_device_factory_manager_find_factory_for_link_type(NMLinkType link_type) { - g_return_val_if_fail (factories_by_link, NULL); + g_return_val_if_fail(factories_by_link, NULL); - return g_hash_table_lookup (factories_by_link, GUINT_TO_POINTER (link_type)); + return g_hash_table_lookup(factories_by_link, GUINT_TO_POINTER(link_type)); } NMDeviceFactory * -nm_device_factory_manager_find_factory_for_connection (NMConnection *connection) +nm_device_factory_manager_find_factory_for_connection(NMConnection *connection) { - NMDeviceFactoryClass *klass; - NMDeviceFactory *factory; - const char *type; - GSList *list; + NMDeviceFactoryClass *klass; + NMDeviceFactory * factory; + const char * type; + GSList * list; - g_return_val_if_fail (factories_by_setting, NULL); + g_return_val_if_fail(factories_by_setting, NULL); - type = nm_connection_get_connection_type (connection); - list = g_hash_table_lookup (factories_by_setting, type); + type = nm_connection_get_connection_type(connection); + list = g_hash_table_lookup(factories_by_setting, type); - for (; list; list = g_slist_next (list)) { - factory = list->data; - klass = NM_DEVICE_FACTORY_GET_CLASS (factory); - if (!klass->match_connection || klass->match_connection (factory, connection)) - return factory; - } + for (; list; list = g_slist_next(list)) { + factory = list->data; + klass = NM_DEVICE_FACTORY_GET_CLASS(factory); + if (!klass->match_connection || klass->match_connection(factory, connection)) + return factory; + } - return NULL; + return NULL; } void -nm_device_factory_manager_for_each_factory (NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data) +nm_device_factory_manager_for_each_factory(NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data) { - GHashTableIter iter; - NMDeviceFactory *factory; - GSList *list_iter, *list = NULL; - - if (factories_by_link) { - g_hash_table_iter_init (&iter, factories_by_link); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &factory)) { - if (!g_slist_find (list, factory)) - list = g_slist_prepend (list, factory); - } - } - - if (factories_by_setting) { - g_hash_table_iter_init (&iter, factories_by_setting); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &list_iter)) { - for (; list_iter; list_iter = g_slist_next (list_iter)) { - if (!g_slist_find (list, list_iter->data)) - list = g_slist_prepend (list, list_iter->data); - } - } - } - - for (list_iter = list; list_iter; list_iter = list_iter->next) - callback (list_iter->data, user_data); - - g_slist_free (list); + GHashTableIter iter; + NMDeviceFactory *factory; + GSList * list_iter, *list = NULL; + + if (factories_by_link) { + g_hash_table_iter_init(&iter, factories_by_link); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &factory)) { + if (!g_slist_find(list, factory)) + list = g_slist_prepend(list, factory); + } + } + + if (factories_by_setting) { + g_hash_table_iter_init(&iter, factories_by_setting); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &list_iter)) { + for (; list_iter; list_iter = g_slist_next(list_iter)) { + if (!g_slist_find(list, list_iter->data)) + list = g_slist_prepend(list, list_iter->data); + } + } + } + + for (list_iter = list; list_iter; list_iter = list_iter->next) + callback(list_iter->data, user_data); + + g_slist_free(list); } static gboolean -_add_factory (NMDeviceFactory *factory, - const char *path, - NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data) +_add_factory(NMDeviceFactory * factory, + const char * path, + NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data) { - const NMLinkType *link_types = NULL; - const char *const*setting_types = NULL; - GSList *list, *list2; - int i; - - g_return_val_if_fail (factories_by_link, FALSE); - g_return_val_if_fail (factories_by_setting, FALSE); - - nm_device_factory_get_supported_types (factory, &link_types, &setting_types); - - g_return_val_if_fail ( (link_types && link_types[0] > NM_LINK_TYPE_UNKNOWN) - || (setting_types && setting_types[0]), - FALSE); - - for (i = 0; link_types && link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) - g_hash_table_insert (factories_by_link, GUINT_TO_POINTER (link_types[i]), g_object_ref (factory)); - for (i = 0; setting_types && setting_types[i]; i++) { - list = g_hash_table_lookup (factories_by_setting, (char *) setting_types[i]); - if (list) { - list2 = g_slist_append (list, g_object_ref (factory)); - nm_assert (list == list2); - } else { - list = g_slist_append (list, g_object_ref (factory)); - g_hash_table_insert (factories_by_setting, (char *) setting_types[i], list); - } - } - - callback (factory, user_data); - - nm_log (path ? LOGL_INFO : LOGL_DEBUG, - LOGD_PLATFORM, - NULL, NULL, - "Loaded device plugin: %s (%s)", - G_OBJECT_TYPE_NAME (factory), - path ?: "internal"); - return TRUE; + const NMLinkType * link_types = NULL; + const char *const *setting_types = NULL; + GSList * list, *list2; + int i; + + g_return_val_if_fail(factories_by_link, FALSE); + g_return_val_if_fail(factories_by_setting, FALSE); + + nm_device_factory_get_supported_types(factory, &link_types, &setting_types); + + g_return_val_if_fail((link_types && link_types[0] > NM_LINK_TYPE_UNKNOWN) + || (setting_types && setting_types[0]), + FALSE); + + for (i = 0; link_types && link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) + g_hash_table_insert(factories_by_link, + GUINT_TO_POINTER(link_types[i]), + g_object_ref(factory)); + for (i = 0; setting_types && setting_types[i]; i++) { + list = g_hash_table_lookup(factories_by_setting, (char *) setting_types[i]); + if (list) { + list2 = g_slist_append(list, g_object_ref(factory)); + nm_assert(list == list2); + } else { + list = g_slist_append(list, g_object_ref(factory)); + g_hash_table_insert(factories_by_setting, (char *) setting_types[i], list); + } + } + + callback(factory, user_data); + + nm_log(path ? LOGL_INFO : LOGL_DEBUG, + LOGD_PLATFORM, + NULL, + NULL, + "Loaded device plugin: %s (%s)", + G_OBJECT_TYPE_NAME(factory), + path ?: "internal"); + return TRUE; } static void -_load_internal_factory (GType factory_gtype, - NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data) +_load_internal_factory(GType factory_gtype, + NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data) { - gs_unref_object NMDeviceFactory *factory = NULL; + gs_unref_object NMDeviceFactory *factory = NULL; - factory = (NMDeviceFactory *) g_object_new (factory_gtype, NULL); - _add_factory (factory, NULL, callback, user_data); + factory = (NMDeviceFactory *) g_object_new(factory_gtype, NULL); + _add_factory(factory, NULL, callback, user_data); } static void -factories_list_unref (GSList *list) +factories_list_unref(GSList *list) { - g_slist_free_full (list, g_object_unref); + g_slist_free_full(list, g_object_unref); } static void -load_factories_from_dir (const char *dirname, - NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data) +load_factories_from_dir(const char * dirname, + NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data) { - NMDeviceFactory *factory; - GError *error = NULL; - char **path, **paths; - - paths = nm_utils_read_plugin_paths (dirname, PLUGIN_PREFIX); - if (!paths) - return; - - for (path = paths; *path; path++) { - GModule *plugin; - NMDeviceFactoryCreateFunc create_func; - const char *item; - - item = strrchr (*path, '/'); - g_assert (item); - - plugin = g_module_open (*path, G_MODULE_BIND_LOCAL); - - if (!plugin) { - nm_log_warn (LOGD_PLATFORM, "(%s): failed to load plugin: %s", item, g_module_error ()); - continue; - } - - if (!g_module_symbol (plugin, "nm_device_factory_create", (gpointer) &create_func)) { - nm_log_warn (LOGD_PLATFORM, "(%s): failed to find device factory creator: %s", item, g_module_error ()); - g_module_close (plugin); - continue; - } - - /* after loading glib types from the plugin, we cannot unload the library anymore. - * Make it resident. */ - g_module_make_resident (plugin); - - factory = create_func (&error); - if (!factory) { - nm_log_warn (LOGD_PLATFORM, "(%s): failed to initialize device factory: %s", - item, NM_G_ERROR_MSG (error)); - g_clear_error (&error); - continue; - } - g_clear_error (&error); - - _add_factory (factory, g_module_name (plugin), callback, user_data); - - g_object_unref (factory); - } - g_strfreev (paths); + NMDeviceFactory *factory; + GError * error = NULL; + char ** path, **paths; + + paths = nm_utils_read_plugin_paths(dirname, PLUGIN_PREFIX); + if (!paths) + return; + + for (path = paths; *path; path++) { + GModule * plugin; + NMDeviceFactoryCreateFunc create_func; + const char * item; + + item = strrchr(*path, '/'); + g_assert(item); + + plugin = g_module_open(*path, G_MODULE_BIND_LOCAL); + + if (!plugin) { + nm_log_warn(LOGD_PLATFORM, "(%s): failed to load plugin: %s", item, g_module_error()); + continue; + } + + if (!g_module_symbol(plugin, "nm_device_factory_create", (gpointer) &create_func)) { + nm_log_warn(LOGD_PLATFORM, + "(%s): failed to find device factory creator: %s", + item, + g_module_error()); + g_module_close(plugin); + continue; + } + + /* after loading glib types from the plugin, we cannot unload the library anymore. + * Make it resident. */ + g_module_make_resident(plugin); + + factory = create_func(&error); + if (!factory) { + nm_log_warn(LOGD_PLATFORM, + "(%s): failed to initialize device factory: %s", + item, + NM_G_ERROR_MSG(error)); + g_clear_error(&error); + continue; + } + g_clear_error(&error); + + _add_factory(factory, g_module_name(plugin), callback, user_data); + + g_object_unref(factory); + } + g_strfreev(paths); } void -nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data) +nm_device_factory_manager_load_factories(NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data) { - g_return_if_fail (factories_by_link == NULL); - g_return_if_fail (factories_by_setting == NULL); - - factories_by_link = g_hash_table_new_full (nm_direct_hash, NULL, NULL, g_object_unref); - factories_by_setting = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, (GDestroyNotify) factories_list_unref); - -#define _ADD_INTERNAL(get_type_fcn) \ - G_STMT_START { \ - GType get_type_fcn (void); \ - _load_internal_factory (get_type_fcn (), \ - callback, user_data); \ - } G_STMT_END - - _ADD_INTERNAL (nm_6lowpan_device_factory_get_type); - _ADD_INTERNAL (nm_bond_device_factory_get_type); - _ADD_INTERNAL (nm_bridge_device_factory_get_type); - _ADD_INTERNAL (nm_dummy_device_factory_get_type); - _ADD_INTERNAL (nm_ethernet_device_factory_get_type); - _ADD_INTERNAL (nm_infiniband_device_factory_get_type); - _ADD_INTERNAL (nm_ip_tunnel_device_factory_get_type); - _ADD_INTERNAL (nm_macsec_device_factory_get_type); - _ADD_INTERNAL (nm_macvlan_device_factory_get_type); - _ADD_INTERNAL (nm_ppp_device_factory_get_type); - _ADD_INTERNAL (nm_tun_device_factory_get_type); - _ADD_INTERNAL (nm_veth_device_factory_get_type); - _ADD_INTERNAL (nm_vlan_device_factory_get_type); - _ADD_INTERNAL (nm_vrf_device_factory_get_type); - _ADD_INTERNAL (nm_vxlan_device_factory_get_type); - _ADD_INTERNAL (nm_wireguard_device_factory_get_type); - _ADD_INTERNAL (nm_wpan_device_factory_get_type); - - load_factories_from_dir (NMPLUGINDIR, callback, user_data); + g_return_if_fail(factories_by_link == NULL); + g_return_if_fail(factories_by_setting == NULL); + + factories_by_link = g_hash_table_new_full(nm_direct_hash, NULL, NULL, g_object_unref); + factories_by_setting = g_hash_table_new_full(nm_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) factories_list_unref); + +#define _ADD_INTERNAL(get_type_fcn) \ + G_STMT_START \ + { \ + GType get_type_fcn(void); \ + _load_internal_factory(get_type_fcn(), callback, user_data); \ + } \ + G_STMT_END + + _ADD_INTERNAL(nm_6lowpan_device_factory_get_type); + _ADD_INTERNAL(nm_bond_device_factory_get_type); + _ADD_INTERNAL(nm_bridge_device_factory_get_type); + _ADD_INTERNAL(nm_dummy_device_factory_get_type); + _ADD_INTERNAL(nm_ethernet_device_factory_get_type); + _ADD_INTERNAL(nm_infiniband_device_factory_get_type); + _ADD_INTERNAL(nm_ip_tunnel_device_factory_get_type); + _ADD_INTERNAL(nm_macsec_device_factory_get_type); + _ADD_INTERNAL(nm_macvlan_device_factory_get_type); + _ADD_INTERNAL(nm_ppp_device_factory_get_type); + _ADD_INTERNAL(nm_tun_device_factory_get_type); + _ADD_INTERNAL(nm_veth_device_factory_get_type); + _ADD_INTERNAL(nm_vlan_device_factory_get_type); + _ADD_INTERNAL(nm_vrf_device_factory_get_type); + _ADD_INTERNAL(nm_vxlan_device_factory_get_type); + _ADD_INTERNAL(nm_wireguard_device_factory_get_type); + _ADD_INTERNAL(nm_wpan_device_factory_get_type); + + load_factories_from_dir(NMPLUGINDIR, callback, user_data); } diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index 7a323d49..5e7a8acd 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2007 - 2014 Red Hat, Inc. */ @@ -15,110 +15,112 @@ * not meant to enable third-party plugins. */ -#define NM_TYPE_DEVICE_FACTORY (nm_device_factory_get_type ()) -#define NM_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactory)) -#define NM_DEVICE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_FACTORY, NMDeviceFactoryClass)) -#define NM_IS_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_FACTORY)) -#define NM_IS_DEVICE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_FACTORY)) -#define NM_DEVICE_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactoryClass)) +#define NM_TYPE_DEVICE_FACTORY (nm_device_factory_get_type()) +#define NM_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactory)) +#define NM_DEVICE_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_FACTORY, NMDeviceFactoryClass)) +#define NM_IS_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_FACTORY)) +#define NM_IS_DEVICE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_FACTORY)) +#define NM_DEVICE_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactoryClass)) -#define NM_DEVICE_FACTORY_DEVICE_ADDED "device-added" +#define NM_DEVICE_FACTORY_DEVICE_ADDED "device-added" typedef struct { - GObject parent; + GObject parent; } NMDeviceFactory; typedef struct { - GObjectClass parent; - - /** - * get_supported_types: - * @factory: the #NMDeviceFactory - * @out_link_types: on return, a %NM_LINK_TYPE_NONE terminated - * list of #NMLinkType that the plugin supports - * @out_setting_types: on return, a %NULL terminated list of - * base-type #NMSetting names that the plugin can create devices for - * - * Returns the #NMLinkType and #NMSetting names that this plugin - * supports. This function MUST be implemented. - */ - void (*get_supported_types) (NMDeviceFactory *factory, - const NMLinkType **out_link_types, - const char *const**out_setting_types); - - /** - * start: - * @factory: the #NMDeviceFactory - * - * Start the factory and discover any existing devices that the factory - * can manage. - */ - void (*start) (NMDeviceFactory *factory); - - /** - * match_connection: - * @connection: the #NMConnection - * - * Check if the factory supports the given connection. - */ - gboolean (*match_connection) (NMDeviceFactory *factory, NMConnection *connection); - - /** - * get_connection_parent: - * @factory: the #NMDeviceFactory - * @connection: the #NMConnection to return the parent name for, if supported - * - * Given a connection, returns the parent interface name, parent connection - * UUID, or parent device permanent hardware address for @connection. - * - * Returns: the parent interface name, parent connection UUID, parent - * device permenent hardware address, or %NULL - */ - const char * (*get_connection_parent) (NMDeviceFactory *factory, - NMConnection *connection); - - /** - * get_connection_iface: - * @factory: the #NMDeviceFactory - * @connection: the #NMConnection to return the interface name for - * @parent_iface: optional parent interface name for virtual devices - * - * Given a connection, returns the interface name that a device activating - * that connection would have. - * - * Returns: the interface name, or %NULL - */ - char * (*get_connection_iface) (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface); - - /** - * create_device: - * @factory: the #NMDeviceFactory - * @iface: the interface name of the device - * @plink: the #NMPlatformLink if backed by a kernel device - * @connection: the #NMConnection if not backed by a kernel device - * @out_ignore: on return, %TRUE if the link should be ignored - * - * The plugin should create a new unrealized device using the details given - * by @iface and @plink or @connection. If both @iface and @plink are given, - * they are guaranteed to match. If both @iface and @connection are given, - * @iface is guaranteed to be the interface name that @connection specifies. - * - * If the plugin cannot create a #NMDevice for the link and wants the - * core to ignore it, set @out_ignore to %TRUE and return %NULL. - * - * Returns: the new unrealized #NMDevice, or %NULL - */ - NMDevice * (*create_device) (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore); + GObjectClass parent; + + /** + * get_supported_types: + * @factory: the #NMDeviceFactory + * @out_link_types: on return, a %NM_LINK_TYPE_NONE terminated + * list of #NMLinkType that the plugin supports + * @out_setting_types: on return, a %NULL terminated list of + * base-type #NMSetting names that the plugin can create devices for + * + * Returns the #NMLinkType and #NMSetting names that this plugin + * supports. This function MUST be implemented. + */ + void (*get_supported_types)(NMDeviceFactory * factory, + const NMLinkType ** out_link_types, + const char *const **out_setting_types); + + /** + * start: + * @factory: the #NMDeviceFactory + * + * Start the factory and discover any existing devices that the factory + * can manage. + */ + void (*start)(NMDeviceFactory *factory); + + /** + * match_connection: + * @connection: the #NMConnection + * + * Check if the factory supports the given connection. + */ + gboolean (*match_connection)(NMDeviceFactory *factory, NMConnection *connection); + + /** + * get_connection_parent: + * @factory: the #NMDeviceFactory + * @connection: the #NMConnection to return the parent name for, if supported + * + * Given a connection, returns the parent interface name, parent connection + * UUID, or parent device permanent hardware address for @connection. + * + * Returns: the parent interface name, parent connection UUID, parent + * device permanent hardware address, or %NULL + */ + const char *(*get_connection_parent)(NMDeviceFactory *factory, NMConnection *connection); + + /** + * get_connection_iface: + * @factory: the #NMDeviceFactory + * @connection: the #NMConnection to return the interface name for + * @parent_iface: optional parent interface name for virtual devices + * + * Given a connection, returns the interface name that a device activating + * that connection would have. + * + * Returns: the interface name, or %NULL + */ + char *(*get_connection_iface)(NMDeviceFactory *factory, + NMConnection * connection, + const char * parent_iface); + + /** + * create_device: + * @factory: the #NMDeviceFactory + * @iface: the interface name of the device + * @plink: the #NMPlatformLink if backed by a kernel device + * @connection: the #NMConnection if not backed by a kernel device + * @out_ignore: on return, %TRUE if the link should be ignored + * + * The plugin should create a new unrealized device using the details given + * by @iface and @plink or @connection. If both @iface and @plink are given, + * they are guaranteed to match. If both @iface and @connection are given, + * @iface is guaranteed to be the interface name that @connection specifies. + * + * If the plugin cannot create a #NMDevice for the link and wants the + * core to ignore it, set @out_ignore to %TRUE and return %NULL. + * + * Returns: the new unrealized #NMDevice, or %NULL + */ + NMDevice *(*create_device)(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore); } NMDeviceFactoryClass; -GType nm_device_factory_get_type (void); +GType nm_device_factory_get_type(void); /*****************************************************************************/ @@ -133,101 +135,103 @@ GType nm_device_factory_get_type (void); * * Returns: the #GObject implementing #NMDeviceFactory or %NULL */ -NMDeviceFactory *nm_device_factory_create (GError **error); +NMDeviceFactory *nm_device_factory_create(GError **error); /* Should match nm_device_factory_create() */ -typedef NMDeviceFactory * (*NMDeviceFactoryCreateFunc) (GError **error); +typedef NMDeviceFactory *(*NMDeviceFactoryCreateFunc)(GError **error); /*****************************************************************************/ -const char *nm_device_factory_get_connection_parent (NMDeviceFactory *factory, - NMConnection *connection); - -char * nm_device_factory_get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface, - GError **error); - -void nm_device_factory_start (NMDeviceFactory *factory); - -NMDevice * nm_device_factory_create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore, - GError **error); - -#define NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(...) \ - { static NMLinkType const _link_types_declared[] = { __VA_ARGS__, NM_LINK_TYPE_NONE }; _link_types = _link_types_declared; } -#define NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(...) \ - { static const char *const _setting_types_declared[] = { __VA_ARGS__, NULL }; _setting_types = _setting_types_declared; } - -#define NM_DEVICE_FACTORY_DECLARE_TYPES(...) \ - static void \ - get_supported_types (NMDeviceFactory *factory, \ - const NMLinkType **out_link_types, \ - const char *const**out_setting_types) \ - { \ - static NMLinkType const _link_types_null[1] = { NM_LINK_TYPE_NONE }; \ - static const char *const _setting_types_null[1] = { NULL }; \ - \ - const NMLinkType *_link_types = _link_types_null; \ - const char *const*_setting_types = _setting_types_null; \ - \ - { __VA_ARGS__; } \ - \ - NM_SET_OUT (out_link_types, _link_types); \ - NM_SET_OUT (out_setting_types, _setting_types); \ - } +const char *nm_device_factory_get_connection_parent(NMDeviceFactory *factory, + NMConnection * connection); + +char *nm_device_factory_get_connection_iface(NMDeviceFactory *factory, + NMConnection * connection, + const char * parent_iface, + GError ** error); + +void nm_device_factory_start(NMDeviceFactory *factory); + +NMDevice *nm_device_factory_create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore, + GError ** error); + +#define NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(...) \ + { \ + static NMLinkType const _link_types_declared[] = {__VA_ARGS__, NM_LINK_TYPE_NONE}; \ + _link_types = _link_types_declared; \ + } +#define NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(...) \ + { \ + static const char *const _setting_types_declared[] = {__VA_ARGS__, NULL}; \ + _setting_types = _setting_types_declared; \ + } + +#define NM_DEVICE_FACTORY_DECLARE_TYPES(...) \ + static void get_supported_types(NMDeviceFactory * factory, \ + const NMLinkType ** out_link_types, \ + const char *const **out_setting_types) \ + { \ + static NMLinkType const _link_types_null[1] = {NM_LINK_TYPE_NONE}; \ + static const char *const _setting_types_null[1] = {NULL}; \ + \ + const NMLinkType * _link_types = _link_types_null; \ + const char *const *_setting_types = _setting_types_null; \ + \ + { \ + __VA_ARGS__; \ + } \ + \ + NM_SET_OUT(out_link_types, _link_types); \ + NM_SET_OUT(out_setting_types, _setting_types); \ + } /************************************************************************** * INTERNAL DEVICE FACTORY FUNCTIONS - devices provided by plugins should * not use these functions. **************************************************************************/ -#define NM_DEVICE_FACTORY_DEFINE_INTERNAL(upper, mixed, lower, st_code, dfi_code) \ - typedef struct { \ - NMDeviceFactory parent; \ - } NM##mixed##DeviceFactory; \ - typedef struct { \ - NMDeviceFactoryClass parent; \ - } NM##mixed##DeviceFactoryClass; \ - \ - GType nm_##lower##_device_factory_get_type (void); \ - \ - G_DEFINE_TYPE (NM##mixed##DeviceFactory, nm_##lower##_device_factory, NM_TYPE_DEVICE_FACTORY) \ - \ - NM_DEVICE_FACTORY_DECLARE_TYPES(st_code) \ - \ - static void \ - nm_##lower##_device_factory_init (NM##mixed##DeviceFactory *self) \ - { \ - } \ - \ - static void \ - nm_##lower##_device_factory_class_init (NM##mixed##DeviceFactoryClass *klass) \ - { \ - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); \ - \ - factory_class->get_supported_types = get_supported_types; \ - dfi_code \ - } +#define NM_DEVICE_FACTORY_DEFINE_INTERNAL(upper, mixed, lower, st_code, dfi_code) \ + typedef struct { \ + NMDeviceFactory parent; \ + } NM##mixed##DeviceFactory; \ + typedef struct { \ + NMDeviceFactoryClass parent; \ + } NM##mixed##DeviceFactoryClass; \ + \ + GType nm_##lower##_device_factory_get_type(void); \ + \ + G_DEFINE_TYPE(NM##mixed##DeviceFactory, nm_##lower##_device_factory, NM_TYPE_DEVICE_FACTORY) \ + \ + NM_DEVICE_FACTORY_DECLARE_TYPES(st_code) \ + \ + static void nm_##lower##_device_factory_init(NM##mixed##DeviceFactory *self) {} \ + \ + static void nm_##lower##_device_factory_class_init(NM##mixed##DeviceFactoryClass *klass) \ + { \ + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); \ + \ + factory_class->get_supported_types = get_supported_types; \ + dfi_code \ + } /************************************************************************** * PRIVATE FACTORY FUNCTIONS - for factory consumers (eg, NMManager). **************************************************************************/ -typedef void (*NMDeviceFactoryManagerFactoryFunc) (NMDeviceFactory *factory, - gpointer user_data); +typedef void (*NMDeviceFactoryManagerFactoryFunc)(NMDeviceFactory *factory, gpointer user_data); -void nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data); +void nm_device_factory_manager_load_factories(NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data); -NMDeviceFactory * nm_device_factory_manager_find_factory_for_link_type (NMLinkType link_type); +NMDeviceFactory *nm_device_factory_manager_find_factory_for_link_type(NMLinkType link_type); -NMDeviceFactory * nm_device_factory_manager_find_factory_for_connection (NMConnection *connection); +NMDeviceFactory *nm_device_factory_manager_find_factory_for_connection(NMConnection *connection); -void nm_device_factory_manager_for_each_factory (NMDeviceFactoryManagerFactoryFunc callback, - gpointer user_data); +void nm_device_factory_manager_for_each_factory(NMDeviceFactoryManagerFactoryFunc callback, + gpointer user_data); #endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index 9883dc4e..ccd56366 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -13,222 +13,226 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_TYPE_DESCRIPTION, -); +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_TYPE_DESCRIPTION, ); typedef struct { - char *type_description; + char *type_description; } NMDeviceGenericPrivate; struct _NMDeviceGeneric { - NMDevice parent; - NMDeviceGenericPrivate _priv; + NMDevice parent; + NMDeviceGenericPrivate _priv; }; struct _NMDeviceGenericClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) -#define NM_DEVICE_GENERIC_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceGeneric, NM_IS_DEVICE_GENERIC, NMDevice) +#define NM_DEVICE_GENERIC_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceGeneric, NM_IS_DEVICE_GENERIC, NMDevice) /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - int ifindex = nm_device_get_ifindex (device); + int ifindex = nm_device_get_ifindex(device); - if (ifindex > 0 && nm_platform_link_supports_carrier_detect (nm_device_get_platform (device), ifindex)) - return NM_DEVICE_CAP_CARRIER_DETECT; - else - return NM_DEVICE_CAP_NONE; + if (ifindex > 0 + && nm_platform_link_supports_carrier_detect(nm_device_get_platform(device), ifindex)) + return NM_DEVICE_CAP_CARRIER_DETECT; + else + return NM_DEVICE_CAP_NONE; } static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - if (NM_DEVICE_GENERIC_GET_PRIVATE (device)->type_description) - return NM_DEVICE_GENERIC_GET_PRIVATE (device)->type_description; - return NM_DEVICE_CLASS (nm_device_generic_parent_class)->get_type_description (device); + if (NM_DEVICE_GENERIC_GET_PRIVATE(device)->type_description) + return NM_DEVICE_GENERIC_GET_PRIVATE(device)->type_description; + return NM_DEVICE_CLASS(nm_device_generic_parent_class)->get_type_description(device); } static void -realize_start_notify (NMDevice *device, const NMPlatformLink *plink) +realize_start_notify(NMDevice *device, const NMPlatformLink *plink) { - NMDeviceGeneric *self = NM_DEVICE_GENERIC (device); - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self); - int ifindex; + NMDeviceGeneric * self = NM_DEVICE_GENERIC(device); + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(self); + int ifindex; - NM_DEVICE_CLASS (nm_device_generic_parent_class)->realize_start_notify (device, plink); + NM_DEVICE_CLASS(nm_device_generic_parent_class)->realize_start_notify(device, plink); - nm_clear_g_free (&priv->type_description); - ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self)); - if (ifindex > 0) - priv->type_description = g_strdup (nm_platform_link_get_type_name (nm_device_get_platform (device), ifindex)); + nm_clear_g_free(&priv->type_description); + ifindex = nm_device_get_ip_ifindex(NM_DEVICE(self)); + if (ifindex > 0) + priv->type_description = + g_strdup(nm_platform_link_get_type_name(nm_device_get_platform(device), ifindex)); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingConnection *s_con; + NMSettingConnection *s_con; - if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_generic_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - s_con = nm_connection_get_setting_connection (connection); - if (!nm_setting_connection_get_interface_name (s_con)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "generic profiles need an interface name"); - return FALSE; - } + s_con = nm_connection_get_setting_connection(connection); + if (!nm_setting_connection_get_interface_name(s_con)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "generic profiles need an interface name"); + return FALSE; + } - return TRUE; + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSettingConnection *s_con; + NMSettingConnection *s_con; - if (!nm_connection_get_setting_generic (connection)) - nm_connection_add_setting (connection, nm_setting_generic_new ()); + if (!nm_connection_get_setting_generic(connection)) + nm_connection_add_setting(connection, nm_setting_generic_new()); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - g_object_set (G_OBJECT (s_con), - NM_SETTING_CONNECTION_INTERFACE_NAME, nm_device_get_iface (device), - NULL); + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + g_object_set(G_OBJECT(s_con), + NM_SETTING_CONNECTION_INTERFACE_NAME, + nm_device_get_iface(device), + NULL); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceGeneric *self = NM_DEVICE_GENERIC (object); - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_TYPE_DESCRIPTION: - g_value_set_string (value, priv->type_description); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceGeneric * self = NM_DEVICE_GENERIC(object); + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_TYPE_DESCRIPTION: + g_value_set_string(value, priv->type_description); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceGeneric *self = NM_DEVICE_GENERIC (object); - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_TYPE_DESCRIPTION: - priv->type_description = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceGeneric * self = NM_DEVICE_GENERIC(object); + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_TYPE_DESCRIPTION: + priv->type_description = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_generic_init (NMDeviceGeneric *self) -{ -} +nm_device_generic_init(NMDeviceGeneric *self) +{} static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) +constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params) { - GObject *object; + GObject *object; - object = G_OBJECT_CLASS (nm_device_generic_parent_class)->constructor (type, - n_construct_params, - construct_params); + object = G_OBJECT_CLASS(nm_device_generic_parent_class) + ->constructor(type, n_construct_params, construct_params); - nm_device_set_unmanaged_flags ((NMDevice *) object, NM_UNMANAGED_BY_DEFAULT, TRUE); + nm_device_set_unmanaged_flags((NMDevice *) object, NM_UNMANAGED_BY_DEFAULT, TRUE); - return object; + return object; } NMDevice * -nm_device_generic_new (const NMPlatformLink *plink, gboolean nm_plugin_missing) +nm_device_generic_new(const NMPlatformLink *plink, gboolean nm_plugin_missing) { - g_return_val_if_fail (plink != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GENERIC, - NM_DEVICE_IFACE, plink->name, - NM_DEVICE_TYPE_DESC, "Generic", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NM_DEVICE_NM_PLUGIN_MISSING, nm_plugin_missing, - NULL); + g_return_val_if_fail(plink != NULL, NULL); + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_GENERIC, + NM_DEVICE_IFACE, + plink->name, + NM_DEVICE_TYPE_DESC, + "Generic", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_GENERIC, + NM_DEVICE_NM_PLUGIN_MISSING, + nm_plugin_missing, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceGeneric *self = NM_DEVICE_GENERIC (object); - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self); + NMDeviceGeneric * self = NM_DEVICE_GENERIC(object); + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE(self); - nm_clear_g_free (&priv->type_description); + nm_clear_g_free(&priv->type_description); - G_OBJECT_CLASS (nm_device_generic_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_generic_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_generic = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_GENERIC, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("TypeDescription", "s", NM_DEVICE_GENERIC_TYPE_DESCRIPTION), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_GENERIC, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + "TypeDescription", + "s", + NM_DEVICE_GENERIC_TYPE_DESCRIPTION), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_generic_class_init (NMDeviceGenericClass *klass) +nm_device_generic_class_init(NMDeviceGenericClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructor = constructor; - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_generic); - - device_class->connection_type_supported = NM_SETTING_GENERIC_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_GENERIC_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_ANY); - - device_class->realize_start_notify = realize_start_notify; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_type_description = get_type_description; - device_class->check_connection_compatible = check_connection_compatible; - device_class->update_connection = update_connection; - - obj_properties[PROP_TYPE_DESCRIPTION] = - g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructor = constructor; + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_generic); + + device_class->connection_type_supported = NM_SETTING_GENERIC_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_GENERIC_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_ANY); + + device_class->realize_start_notify = realize_start_notify; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_type_description = get_type_description; + device_class->check_connection_compatible = check_connection_compatible; + device_class->update_connection = update_connection; + + obj_properties[PROP_TYPE_DESCRIPTION] = + g_param_spec_string(NM_DEVICE_GENERIC_TYPE_DESCRIPTION, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/nm-device-generic.h b/src/devices/nm-device-generic.h index 5dd90a3a..4acc4dc9 100644 --- a/src/devices/nm-device-generic.h +++ b/src/devices/nm-device-generic.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -8,21 +8,23 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) -#define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) -#define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) -#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GENERIC)) -#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) -#define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type()) +#define NM_DEVICE_GENERIC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) #define NM_DEVICE_GENERIC_TYPE_DESCRIPTION "type-description" -typedef struct _NMDeviceGeneric NMDeviceGeneric; +typedef struct _NMDeviceGeneric NMDeviceGeneric; typedef struct _NMDeviceGenericClass NMDeviceGenericClass; -GType nm_device_generic_get_type (void); +GType nm_device_generic_get_type(void); -NMDevice *nm_device_generic_new (const NMPlatformLink *plink, - gboolean nm_plugin_missing); +NMDevice *nm_device_generic_new(const NMPlatformLink *plink, gboolean nm_plugin_missing); #endif /* __NETWORKMANAGER_DEVICE_GENERIC_H__ */ diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 0ef74d25..bae5db64 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 - 2018 Red Hat, Inc. */ @@ -22,445 +22,483 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_IS_PARTITION, -); +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_IS_PARTITION, ); typedef struct { - gboolean is_partition; - int parent_ifindex; - int p_key; + gboolean is_partition; + int parent_ifindex; + int p_key; } NMDeviceInfinibandPrivate; struct _NMDeviceInfiniband { - NMDevice parent; - NMDeviceInfinibandPrivate _priv; + NMDevice parent; + NMDeviceInfinibandPrivate _priv; }; struct _NMDeviceInfinibandClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) -#define NM_DEVICE_INFINIBAND_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceInfiniband, NM_IS_DEVICE_INFINIBAND, NMDevice) +#define NM_DEVICE_INFINIBAND_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceInfiniband, NM_IS_DEVICE_INFINIBAND, NMDevice) /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - guint32 caps = NM_DEVICE_CAP_CARRIER_DETECT; + guint32 caps = NM_DEVICE_CAP_CARRIER_DETECT; - if (NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->is_partition) - caps |= NM_DEVICE_CAP_IS_SOFTWARE; + if (NM_DEVICE_INFINIBAND_GET_PRIVATE(device)->is_partition) + caps |= NM_DEVICE_CAP_IS_SOFTWARE; - return caps; + return caps; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - nm_auto_close int dirfd = -1; - NMSettingInfiniband *s_infiniband; - char ifname_verified[IFNAMSIZ]; - const char *transport_mode; - gboolean ok; - - s_infiniband = nm_device_get_applied_setting (device, NM_TYPE_SETTING_INFINIBAND); - - g_return_val_if_fail (s_infiniband, NM_ACT_STAGE_RETURN_FAILURE); - - transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband); - - dirfd = nm_platform_sysctl_open_netdir (nm_device_get_platform (device), nm_device_get_ifindex (device), ifname_verified); - if (dirfd < 0) { - if (nm_streq (transport_mode, "datagram")) - return NM_ACT_STAGE_RETURN_SUCCESS; - else { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_INFINIBAND_MODE); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - - /* With some drivers the interface must be down to set transport mode */ - nm_device_take_down (device, TRUE); - ok = nm_platform_sysctl_set (nm_device_get_platform (device), NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname_verified, "mode"), transport_mode); - nm_device_bring_up (device, TRUE, NULL); - - if (!ok) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + nm_auto_close int dirfd = -1; + NMSettingInfiniband *s_infiniband; + char ifname_verified[IFNAMSIZ]; + const char * transport_mode; + gboolean ok; + + s_infiniband = nm_device_get_applied_setting(device, NM_TYPE_SETTING_INFINIBAND); + + g_return_val_if_fail(s_infiniband, NM_ACT_STAGE_RETURN_FAILURE); + + transport_mode = nm_setting_infiniband_get_transport_mode(s_infiniband); + + dirfd = nm_platform_sysctl_open_netdir(nm_device_get_platform(device), + nm_device_get_ifindex(device), + ifname_verified); + if (dirfd < 0) { + if (nm_streq(transport_mode, "datagram")) + return NM_ACT_STAGE_RETURN_SUCCESS; + else { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_INFINIBAND_MODE); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + /* With some drivers the interface must be down to set transport mode */ + nm_device_take_down(device, TRUE); + ok = nm_platform_sysctl_set(nm_device_get_platform(device), + NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname_verified, "mode"), + transport_mode); + nm_device_bring_up(device, TRUE, NULL); + + if (!ok) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - return nm_device_get_configured_mtu_from_connection (device, - NM_TYPE_SETTING_INFINIBAND, - out_source); + return nm_device_get_configured_mtu_from_connection(device, + NM_TYPE_SETTING_INFINIBAND, + out_source); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingInfiniband *s_infiniband; - - if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (nm_device_is_real (device)) { - const char *mac; - const char *hw_addr; - - s_infiniband = nm_connection_get_setting_infiniband (connection); - - mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac) { - hw_addr = nm_device_get_permanent_hw_address (device); - if ( !hw_addr - || !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address mismatches"); - return FALSE; - } - } - } - - return TRUE; + NMSettingInfiniband *s_infiniband; + + if (!NM_DEVICE_CLASS(nm_device_infiniband_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_device_is_real(device)) { + const char *mac; + const char *hw_addr; + + s_infiniband = nm_connection_get_setting_infiniband(connection); + + mac = nm_setting_infiniband_get_mac_address(s_infiniband); + if (mac) { + hw_addr = nm_device_get_permanent_hw_address(device); + if (!hw_addr || !nm_utils_hwaddr_matches(mac, -1, hw_addr, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "MAC address mismatches"); + return FALSE; + } + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingInfiniband *s_infiniband; - - s_infiniband = nm_connection_get_setting_infiniband (connection); - if (!s_infiniband) { - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - } - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_INFINIBAND_SETTING_NAME, - existing_connections, - NULL, - _("InfiniBand connection"), - NULL, - nm_setting_infiniband_get_mac_address (s_infiniband) ? NULL : nm_device_get_iface (device), - TRUE); - - if (!nm_setting_infiniband_get_transport_mode (s_infiniband)) - g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); - - return TRUE; + NMSettingInfiniband *s_infiniband; + + s_infiniband = nm_connection_get_setting_infiniband(connection); + if (!s_infiniband) { + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); + nm_connection_add_setting(connection, NM_SETTING(s_infiniband)); + } + + nm_utils_complete_generic( + nm_device_get_platform(device), + connection, + NM_SETTING_INFINIBAND_SETTING_NAME, + existing_connections, + NULL, + _("InfiniBand connection"), + NULL, + nm_setting_infiniband_get_mac_address(s_infiniband) ? NULL : nm_device_get_iface(device), + TRUE); + + if (!nm_setting_infiniband_get_transport_mode(s_infiniband)) + g_object_set(G_OBJECT(s_infiniband), + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + "datagram", + NULL); + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); - const char *mac = nm_device_get_permanent_hw_address (device); - const char *transport_mode = "datagram"; - int ifindex; - - if (!s_infiniband) { - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, (NMSetting *) s_infiniband); - } - - if (mac && !nm_utils_hwaddr_matches (mac, -1, NULL, INFINIBAND_ALEN)) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); - - ifindex = nm_device_get_ifindex (device); - if (ifindex > 0) { - if (!nm_platform_link_infiniband_get_properties (nm_device_get_platform (device), ifindex, NULL, NULL, &transport_mode)) - transport_mode = "datagram"; - } - g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL); + NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband(connection); + const char * mac = nm_device_get_permanent_hw_address(device); + const char * transport_mode = "datagram"; + int ifindex; + + if (!s_infiniband) { + s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); + nm_connection_add_setting(connection, (NMSetting *) s_infiniband); + } + + if (mac && !nm_utils_hwaddr_matches(mac, -1, NULL, INFINIBAND_ALEN)) + g_object_set(s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); + + ifindex = nm_device_get_ifindex(device); + if (ifindex > 0) { + if (!nm_platform_link_infiniband_get_properties(nm_device_get_platform(device), + ifindex, + NULL, + NULL, + &transport_mode)) + transport_mode = "datagram"; + } + g_object_set(G_OBJECT(s_infiniband), + NM_SETTING_INFINIBAND_TRANSPORT_MODE, + transport_mode, + NULL); } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) { - NMDeviceClass *device_class; - - if (nm_streq (setting_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_INFINIBAND_SETTING_NAME, - error, - NM_SETTING_INFINIBAND_MTU); /* reapplied with IP config */ - } - - device_class = NM_DEVICE_CLASS (nm_device_infiniband_parent_class); - return device_class->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); + NMDeviceClass *device_class; + + if (nm_streq(setting_name, NM_SETTING_INFINIBAND_SETTING_NAME)) { + return nm_device_hash_check_invalid_keys( + diffs, + NM_SETTING_INFINIBAND_SETTING_NAME, + error, + NM_SETTING_INFINIBAND_MTU); /* reapplied with IP config */ + } + + device_class = NM_DEVICE_CLASS(nm_device_infiniband_parent_class); + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); - NMSettingInfiniband *s_infiniband; - int r; - - s_infiniband = nm_connection_get_setting_infiniband (connection); - g_assert (s_infiniband); - - /* Can only create partitions at this time */ - priv->p_key = nm_setting_infiniband_get_p_key (s_infiniband); - if (priv->p_key < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "only InfiniBand partitions can be created"); - return FALSE; - } - - if (!parent) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "InfiniBand partitions can not be created without a parent interface"); - return FALSE; - } - - if (!NM_IS_DEVICE_INFINIBAND (parent)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "Parent interface %s must be an InfiniBand interface", - nm_device_get_iface (parent)); - return FALSE; - } - - priv->parent_ifindex = nm_device_get_ifindex (parent); - if (priv->parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "failed to get InfiniBand parent %s ifindex", - nm_device_get_iface (parent)); - return FALSE; - } - - r = nm_platform_link_infiniband_add (nm_device_get_platform (device), priv->parent_ifindex, priv->p_key, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create InfiniBand P_Key interface '%s' for '%s': %s", - nm_device_get_iface (device), - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - priv->is_partition = TRUE; - return TRUE; + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE(device); + NMSettingInfiniband * s_infiniband; + int r; + + s_infiniband = nm_connection_get_setting_infiniband(connection); + g_assert(s_infiniband); + + /* Can only create partitions at this time */ + priv->p_key = nm_setting_infiniband_get_p_key(s_infiniband); + if (priv->p_key < 0) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "only InfiniBand partitions can be created"); + return FALSE; + } + + if (!parent) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "InfiniBand partitions can not be created without a parent interface"); + return FALSE; + } + + if (!NM_IS_DEVICE_INFINIBAND(parent)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "Parent interface %s must be an InfiniBand interface", + nm_device_get_iface(parent)); + return FALSE; + } + + priv->parent_ifindex = nm_device_get_ifindex(parent); + if (priv->parent_ifindex <= 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "failed to get InfiniBand parent %s ifindex", + nm_device_get_iface(parent)); + return FALSE; + } + + r = nm_platform_link_infiniband_add(nm_device_get_platform(device), + priv->parent_ifindex, + priv->p_key, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create InfiniBand P_Key interface '%s' for '%s': %s", + nm_device_get_iface(device), + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + priv->is_partition = TRUE; + return TRUE; } static gboolean -unrealize (NMDevice *device, GError **error) +unrealize(NMDevice *device, GError **error) { - NMDeviceInfinibandPrivate *priv; - int r; - - g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE); - - priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (device); - - if (priv->p_key < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Only InfiniBand partitions can be removed"); - return FALSE; - } - - r = nm_platform_link_infiniband_delete (nm_device_get_platform (device), priv->parent_ifindex, priv->p_key); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to remove InfiniBand P_Key interface '%s': %s", - nm_device_get_iface (device), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + NMDeviceInfinibandPrivate *priv; + int r; + + g_return_val_if_fail(NM_IS_DEVICE_INFINIBAND(device), FALSE); + + priv = NM_DEVICE_INFINIBAND_GET_PRIVATE(device); + + if (priv->p_key < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Only InfiniBand partitions can be removed"); + return FALSE; + } + + r = nm_platform_link_infiniband_delete(nm_device_get_platform(device), + priv->parent_ifindex, + priv->p_key); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to remove InfiniBand P_Key interface '%s': %s", + nm_device_get_iface(device), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - switch (prop_id) { - case PROP_IS_PARTITION: - g_value_set_boolean (value, NM_DEVICE_INFINIBAND_GET_PRIVATE (object)->is_partition); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_IS_PARTITION: + g_value_set_boolean(value, NM_DEVICE_INFINIBAND_GET_PRIVATE(object)->is_partition); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - switch (prop_id) { - case PROP_IS_PARTITION: - NM_DEVICE_INFINIBAND_GET_PRIVATE (object)->is_partition = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_IS_PARTITION: + NM_DEVICE_INFINIBAND_GET_PRIVATE(object)->is_partition = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_infiniband_init (NMDeviceInfiniband * self) -{ -} +nm_device_infiniband_init(NMDeviceInfiniband *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_infiniband = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_INFINIBAND, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", + "b", + NM_DEVICE_CARRIER), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) +nm_device_infiniband_class_init(NMDeviceInfinibandClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_infiniband); - - device_class->connection_type_supported = NM_SETTING_INFINIBAND_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_INFINIBAND_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_INFINIBAND); - - device_class->can_reapply_change = can_reapply_change; - device_class->create_and_realize = create_and_realize; - device_class->unrealize = unrealize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = get_configured_mtu; - - obj_properties[PROP_IS_PARTITION] = - g_param_spec_boolean (NM_DEVICE_INFINIBAND_IS_PARTITION, "", "", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_infiniband); + + device_class->connection_type_supported = NM_SETTING_INFINIBAND_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_INFINIBAND_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_INFINIBAND); + + device_class->can_reapply_change = can_reapply_change; + device_class->create_and_realize = create_and_realize; + device_class->unrealize = unrealize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; + device_class->update_connection = update_connection; + + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->get_configured_mtu = get_configured_mtu; + + obj_properties[PROP_IS_PARTITION] = + g_param_spec_boolean(NM_DEVICE_INFINIBAND_IS_PARTITION, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_INFINIBAND_DEVICE_FACTORY (nm_infiniband_device_factory_get_type ()) -#define NM_INFINIBAND_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INFINIBAND_DEVICE_FACTORY, NMInfinibandDeviceFactory)) +#define NM_TYPE_INFINIBAND_DEVICE_FACTORY (nm_infiniband_device_factory_get_type()) +#define NM_INFINIBAND_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + NM_TYPE_INFINIBAND_DEVICE_FACTORY, \ + NMInfinibandDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - gboolean is_partition = FALSE; - - if (plink) - is_partition = (plink->parent > 0 || plink->parent == NM_PLATFORM_LINK_OTHER_NETNS); - else if (connection) { - NMSettingInfiniband *s_infiniband; - - s_infiniband = nm_connection_get_setting_infiniband (connection); - g_return_val_if_fail (s_infiniband, NULL); - is_partition = !!nm_setting_infiniband_get_parent (s_infiniband) - || ( nm_setting_infiniband_get_p_key (s_infiniband) >= 0 - && nm_setting_infiniband_get_mac_address (s_infiniband)); - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "InfiniBand", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_INFINIBAND, - /* NOTE: Partition should probably be a different link type! */ - NM_DEVICE_INFINIBAND_IS_PARTITION, is_partition, - NULL); + gboolean is_partition = FALSE; + + if (plink) + is_partition = (plink->parent > 0 || plink->parent == NM_PLATFORM_LINK_OTHER_NETNS); + else if (connection) { + NMSettingInfiniband *s_infiniband; + + s_infiniband = nm_connection_get_setting_infiniband(connection); + g_return_val_if_fail(s_infiniband, NULL); + is_partition = !!nm_setting_infiniband_get_parent(s_infiniband) + || (nm_setting_infiniband_get_p_key(s_infiniband) >= 0 + && nm_setting_infiniband_get_mac_address(s_infiniband)); + } + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_INFINIBAND, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "InfiniBand", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_INFINIBAND, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_INFINIBAND, + /* NOTE: Partition should probably be a different link type! */ + NM_DEVICE_INFINIBAND_IS_PARTITION, + is_partition, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingInfiniband *s_infiniband; + NMSettingInfiniband *s_infiniband; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_INFINIBAND_SETTING_NAME), + NULL); - s_infiniband = nm_connection_get_setting_infiniband (connection); - g_assert (s_infiniband); + s_infiniband = nm_connection_get_setting_infiniband(connection); + g_assert(s_infiniband); - return nm_setting_infiniband_get_parent (s_infiniband); + return nm_setting_infiniband_get_parent(s_infiniband); } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - NMSettingInfiniband *s_infiniband; + NMSettingInfiniband *s_infiniband; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_INFINIBAND_SETTING_NAME), + NULL); - s_infiniband = nm_connection_get_setting_infiniband (connection); - g_assert (s_infiniband); + s_infiniband = nm_connection_get_setting_infiniband(connection); + g_assert(s_infiniband); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - g_return_val_if_fail (g_strcmp0 (parent_iface, nm_setting_infiniband_get_parent (s_infiniband)) == 0, NULL); + g_return_val_if_fail(g_strcmp0(parent_iface, nm_setting_infiniband_get_parent(s_infiniband)) + == 0, + NULL); - return g_strdup (nm_setting_infiniband_get_virtual_interface_name (s_infiniband)); + return g_strdup(nm_setting_infiniband_get_virtual_interface_name(s_infiniband)); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (INFINIBAND, Infiniband, infiniband, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_INFINIBAND) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_INFINIBAND_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + INFINIBAND, + Infiniband, + infiniband, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_INFINIBAND) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_INFINIBAND_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-infiniband.h b/src/devices/nm-device-infiniband.h index 6f46ef50..d8be8f21 100644 --- a/src/devices/nm-device-infiniband.h +++ b/src/devices/nm-device-infiniband.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -8,16 +8,20 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type ()) -#define NM_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) -#define NM_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) -#define NM_IS_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INFINIBAND)) -#define NM_IS_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_INFINIBAND)) -#define NM_DEVICE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) +#define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type()) +#define NM_DEVICE_INFINIBAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) +#define NM_DEVICE_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) +#define NM_IS_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_IS_DEVICE_INFINIBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_DEVICE_INFINIBAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) -typedef struct _NMDeviceInfiniband NMDeviceInfiniband; +typedef struct _NMDeviceInfiniband NMDeviceInfiniband; typedef struct _NMDeviceInfinibandClass NMDeviceInfinibandClass; -GType nm_device_infiniband_get_type (void); +GType nm_device_infiniband_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_INFINIBAND_H__ */ diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 2c9a6050..e01cc7ff 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -27,1234 +27,1272 @@ _LOG_DECLARE_SELF(NMDeviceIPTunnel); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceIPTunnel, - PROP_MODE, - PROP_LOCAL, - PROP_REMOTE, - PROP_TTL, - PROP_TOS, - PROP_PATH_MTU_DISCOVERY, - PROP_INPUT_KEY, - PROP_OUTPUT_KEY, - PROP_ENCAPSULATION_LIMIT, - PROP_FLOW_LABEL, - PROP_FLAGS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceIPTunnel, + PROP_MODE, + PROP_LOCAL, + PROP_REMOTE, + PROP_TTL, + PROP_TOS, + PROP_PATH_MTU_DISCOVERY, + PROP_INPUT_KEY, + PROP_OUTPUT_KEY, + PROP_ENCAPSULATION_LIMIT, + PROP_FLOW_LABEL, + PROP_FLAGS, ); typedef struct { - NMIPTunnelMode mode; - char *local; - char *remote; - guint8 ttl; - guint8 tos; - gboolean path_mtu_discovery; - int addr_family; - char *input_key; - char *output_key; - guint8 encap_limit; - guint32 flow_label; - NMIPTunnelFlags flags; + NMIPTunnelMode mode; + char * local; + char * remote; + guint8 ttl; + guint8 tos; + gboolean path_mtu_discovery; + int addr_family; + char * input_key; + char * output_key; + guint8 encap_limit; + guint32 flow_label; + NMIPTunnelFlags flags; } NMDeviceIPTunnelPrivate; struct _NMDeviceIPTunnel { - NMDevice parent; - NMDeviceIPTunnelPrivate _priv; + NMDevice parent; + NMDeviceIPTunnelPrivate _priv; }; struct _NMDeviceIPTunnelClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE) -#define NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceIPTunnel, NM_IS_DEVICE_IP_TUNNEL, NMDevice) +#define NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceIPTunnel, NM_IS_DEVICE_IP_TUNNEL, NMDevice) /*****************************************************************************/ static guint32 -ip6tnl_flags_setting_to_plat (NMIPTunnelFlags flags) +ip6tnl_flags_setting_to_plat(NMIPTunnelFlags flags) { - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT == IP6_TNL_F_IGN_ENCAP_LIMIT); - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS == IP6_TNL_F_USE_ORIG_TCLASS); - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL == IP6_TNL_F_USE_ORIG_FLOWLABEL); - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV == IP6_TNL_F_MIP6_DEV); - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY == IP6_TNL_F_RCV_DSCP_COPY); - G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK == IP6_TNL_F_USE_ORIG_FWMARK); - - /* NOTE: "accidentally", the numeric values correspond. - * For flags added in the future, that might no longer - * be the case. */ - return flags & _NM_IP_TUNNEL_FLAG_ALL_IP6TNL; + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT == IP6_TNL_F_IGN_ENCAP_LIMIT); + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS == IP6_TNL_F_USE_ORIG_TCLASS); + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL == IP6_TNL_F_USE_ORIG_FLOWLABEL); + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV == IP6_TNL_F_MIP6_DEV); + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY == IP6_TNL_F_RCV_DSCP_COPY); + G_STATIC_ASSERT(NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK == IP6_TNL_F_USE_ORIG_FWMARK); + + /* NOTE: "accidentally", the numeric values correspond. + * For flags added in the future, that might no longer + * be the case. */ + return flags & _NM_IP_TUNNEL_FLAG_ALL_IP6TNL; } static NMIPTunnelFlags -ip6tnl_flags_plat_to_setting (guint32 flags) +ip6tnl_flags_plat_to_setting(guint32 flags) { - return flags & ((guint32) _NM_IP_TUNNEL_FLAG_ALL_IP6TNL); + return flags & ((guint32) _NM_IP_TUNNEL_FLAG_ALL_IP6TNL); } /*****************************************************************************/ static gboolean -address_equal_pp (int addr_family, const char *a, const char *b) +address_equal_pp(int addr_family, const char *a, const char *b) { - const NMIPAddr *addr_a = &nm_ip_addr_zero; - const NMIPAddr *addr_b = &nm_ip_addr_zero; - NMIPAddr addr_a_val; - NMIPAddr addr_b_val; - - nm_assert_addr_family (addr_family); - - if (a) { - if (!nm_utils_parse_inaddr_bin (addr_family, a, NULL, &addr_a_val)) - nm_assert_not_reached (); - addr_a = &addr_a_val; - } - if (b) { - if (!nm_utils_parse_inaddr_bin (addr_family, b, NULL, &addr_b_val)) - nm_assert_not_reached (); - addr_b = &addr_b_val; - } - - return nm_ip_addr_equal (addr_family, addr_a, addr_b); + const NMIPAddr *addr_a = &nm_ip_addr_zero; + const NMIPAddr *addr_b = &nm_ip_addr_zero; + NMIPAddr addr_a_val; + NMIPAddr addr_b_val; + + nm_assert_addr_family(addr_family); + + if (a) { + if (!nm_utils_parse_inaddr_bin(addr_family, a, NULL, &addr_a_val)) + nm_assert_not_reached(); + addr_a = &addr_a_val; + } + if (b) { + if (!nm_utils_parse_inaddr_bin(addr_family, b, NULL, &addr_b_val)) + nm_assert_not_reached(); + addr_b = &addr_b_val; + } + + return nm_ip_addr_equal(addr_family, addr_a, addr_b); } static gboolean -address_set (int addr_family, - char **p_addr, - const NMIPAddr *addr_new) +address_set(int addr_family, char **p_addr, const NMIPAddr *addr_new) { - nm_assert_addr_family (addr_family); - nm_assert (p_addr); - nm_assert ( !*p_addr - || nm_utils_ipaddr_is_normalized (addr_family, *p_addr)); - - if ( !addr_new - || nm_ip_addr_is_null (addr_family, addr_new)) { - if (nm_clear_g_free (p_addr)) - return TRUE; - return FALSE; - } - - if (*p_addr) { - NMIPAddr addr_val; - - if (!nm_utils_parse_inaddr_bin (addr_family, - *p_addr, - NULL, - &addr_val)) - nm_assert_not_reached (); - - if (nm_ip_addr_equal (addr_family, &addr_val, addr_new)) - return FALSE; - - g_free (*p_addr); - } - - *p_addr = nm_utils_inet_ntop_dup (addr_family, addr_new); - return TRUE; + nm_assert_addr_family(addr_family); + nm_assert(p_addr); + nm_assert(!*p_addr || nm_utils_ipaddr_is_normalized(addr_family, *p_addr)); + + if (!addr_new || nm_ip_addr_is_null(addr_family, addr_new)) { + if (nm_clear_g_free(p_addr)) + return TRUE; + return FALSE; + } + + if (*p_addr) { + NMIPAddr addr_val; + + if (!nm_utils_parse_inaddr_bin(addr_family, *p_addr, NULL, &addr_val)) + nm_assert_not_reached(); + + if (nm_ip_addr_equal(addr_family, &addr_val, addr_new)) + return FALSE; + + g_free(*p_addr); + } + + *p_addr = nm_utils_inet_ntop_dup(addr_family, addr_new); + return TRUE; } static void -update_properties_from_ifindex (NMDevice *device, int ifindex) +update_properties_from_ifindex(NMDevice *device, int ifindex) { - NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); - int parent_ifindex = 0; - NMIPAddr local = NM_IP_ADDR_INIT; - NMIPAddr remote = NM_IP_ADDR_INIT; - guint8 ttl = 0; - guint8 tos = 0; - guint8 encap_limit = 0; - gboolean pmtud = FALSE; - guint32 flow_label = 0; - NMIPTunnelFlags flags = NM_IP_TUNNEL_FLAG_NONE; - char *key; - - if (ifindex <= 0) { + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); + int parent_ifindex = 0; + NMIPAddr local = NM_IP_ADDR_INIT; + NMIPAddr remote = NM_IP_ADDR_INIT; + guint8 ttl = 0; + guint8 tos = 0; + guint8 encap_limit = 0; + gboolean pmtud = FALSE; + guint32 flow_label = 0; + NMIPTunnelFlags flags = NM_IP_TUNNEL_FLAG_NONE; + char * key; + + if (ifindex <= 0) { clear: - nm_device_parent_set_ifindex (device, 0); - if (priv->local) { - nm_clear_g_free (&priv->local); - _notify (self, PROP_LOCAL); - } - if (priv->remote) { - nm_clear_g_free (&priv->remote); - _notify (self, PROP_REMOTE); - } - if (priv->input_key) { - nm_clear_g_free (&priv->input_key); - _notify (self, PROP_INPUT_KEY); - } - if (priv->output_key) { - nm_clear_g_free (&priv->output_key); - _notify (self, PROP_OUTPUT_KEY); - } - - goto out; - } - - if (NM_IN_SET (priv->mode, NM_IP_TUNNEL_MODE_GRE, NM_IP_TUNNEL_MODE_GRETAP)) { - const NMPlatformLnkGre *lnk; - - if (priv->mode == NM_IP_TUNNEL_MODE_GRE) - lnk = nm_platform_link_get_lnk_gre (nm_device_get_platform (device), ifindex, NULL); - else - lnk = nm_platform_link_get_lnk_gretap (nm_device_get_platform (device), ifindex, NULL); - if (!lnk) { - _LOGW (LOGD_PLATFORM, "could not read %s properties", "gre"); - goto clear; - } - - parent_ifindex = lnk->parent_ifindex; - local.addr4 = lnk->local; - remote.addr4 = lnk->remote; - ttl = lnk->ttl; - tos = lnk->tos; - pmtud = lnk->path_mtu_discovery; - - if (NM_FLAGS_HAS (lnk->input_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->input_key); - if (g_strcmp0 (priv->input_key, key)) { - g_free (priv->input_key); - priv->input_key = key; - _notify (self, PROP_INPUT_KEY); - } else - g_free (key); - } else { - if (priv->input_key) { - nm_clear_g_free (&priv->input_key); - _notify (self, PROP_INPUT_KEY); - } - } - - if (NM_FLAGS_HAS (lnk->output_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->output_key); - if (g_strcmp0 (priv->output_key, key)) { - g_free (priv->output_key); - priv->output_key = key; - _notify (self, PROP_OUTPUT_KEY); - } else - g_free (key); - } else { - if (priv->output_key) { - nm_clear_g_free (&priv->output_key); - _notify (self, PROP_OUTPUT_KEY); - } - } - } else if (priv->mode == NM_IP_TUNNEL_MODE_SIT) { - const NMPlatformLnkSit *lnk; - - lnk = nm_platform_link_get_lnk_sit (nm_device_get_platform (device), ifindex, NULL); - if (!lnk) { - _LOGW (LOGD_PLATFORM, "could not read %s properties", "sit"); - goto clear; - } - - parent_ifindex = lnk->parent_ifindex; - local.addr4 = lnk->local; - remote.addr4 = lnk->remote; - ttl = lnk->ttl; - tos = lnk->tos; - pmtud = lnk->path_mtu_discovery; - } else if (priv->mode == NM_IP_TUNNEL_MODE_IPIP) { - const NMPlatformLnkIpIp *lnk; - - lnk = nm_platform_link_get_lnk_ipip (nm_device_get_platform (device), ifindex, NULL); - if (!lnk) { - _LOGW (LOGD_PLATFORM, "could not read %s properties", "ipip"); - goto clear; - } - - parent_ifindex = lnk->parent_ifindex; - local.addr4 = lnk->local; - remote.addr4 = lnk->remote; - ttl = lnk->ttl; - tos = lnk->tos; - pmtud = lnk->path_mtu_discovery; - } else if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IPIP6, - NM_IP_TUNNEL_MODE_IP6IP6, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { - const NMPlatformLnkIp6Tnl *lnk; - NMPlatform *plat = nm_device_get_platform (device); - - if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) - lnk = nm_platform_link_get_lnk_ip6gre (plat, ifindex, NULL); - else if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRETAP) - lnk = nm_platform_link_get_lnk_ip6gretap (plat, ifindex, NULL); - else - lnk = nm_platform_link_get_lnk_ip6tnl (plat, ifindex, NULL); - - if (!lnk) { - _LOGW (LOGD_PLATFORM, "could not read %s properties", "ip6tnl"); - goto clear; - } - - parent_ifindex = lnk->parent_ifindex; - local.addr6 = lnk->local; - remote.addr6 = lnk->remote; - ttl = lnk->ttl; - tos = lnk->tclass; - encap_limit = lnk->encap_limit; - flow_label = lnk->flow_label; - flags = ip6tnl_flags_plat_to_setting (lnk->flags); - - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { - if (NM_FLAGS_HAS (lnk->input_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->input_key); - if (g_strcmp0 (priv->input_key, key)) { - g_free (priv->input_key); - priv->input_key = key; - _notify (self, PROP_INPUT_KEY); - } else - g_free (key); - } else { - if (priv->input_key) { - nm_clear_g_free (&priv->input_key); - _notify (self, PROP_INPUT_KEY); - } - } - - if (NM_FLAGS_HAS (lnk->output_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->output_key); - if (g_strcmp0 (priv->output_key, key)) { - g_free (priv->output_key); - priv->output_key = key; - _notify (self, PROP_OUTPUT_KEY); - } else - g_free (key); - } else { - if (priv->output_key) { - nm_clear_g_free (&priv->output_key); - _notify (self, PROP_OUTPUT_KEY); - } - } - } - } else - g_return_if_reached (); - - nm_device_parent_set_ifindex (device, parent_ifindex); - - if (address_set (priv->addr_family, &priv->local, &local)) - _notify (self, PROP_LOCAL); - if (address_set (priv->addr_family, &priv->remote, &remote)) - _notify (self, PROP_REMOTE); + nm_device_parent_set_ifindex(device, 0); + if (priv->local) { + nm_clear_g_free(&priv->local); + _notify(self, PROP_LOCAL); + } + if (priv->remote) { + nm_clear_g_free(&priv->remote); + _notify(self, PROP_REMOTE); + } + if (priv->input_key) { + nm_clear_g_free(&priv->input_key); + _notify(self, PROP_INPUT_KEY); + } + if (priv->output_key) { + nm_clear_g_free(&priv->output_key); + _notify(self, PROP_OUTPUT_KEY); + } + + goto out; + } + + if (NM_IN_SET(priv->mode, NM_IP_TUNNEL_MODE_GRE, NM_IP_TUNNEL_MODE_GRETAP)) { + const NMPlatformLnkGre *lnk; + + if (priv->mode == NM_IP_TUNNEL_MODE_GRE) + lnk = nm_platform_link_get_lnk_gre(nm_device_get_platform(device), ifindex, NULL); + else + lnk = nm_platform_link_get_lnk_gretap(nm_device_get_platform(device), ifindex, NULL); + if (!lnk) { + _LOGW(LOGD_PLATFORM, "could not read %s properties", "gre"); + goto clear; + } + + parent_ifindex = lnk->parent_ifindex; + local.addr4 = lnk->local; + remote.addr4 = lnk->remote; + ttl = lnk->ttl; + tos = lnk->tos; + pmtud = lnk->path_mtu_discovery; + + if (NM_FLAGS_HAS(lnk->input_flags, NM_GRE_KEY)) { + key = g_strdup_printf("%u", lnk->input_key); + if (g_strcmp0(priv->input_key, key)) { + g_free(priv->input_key); + priv->input_key = key; + _notify(self, PROP_INPUT_KEY); + } else + g_free(key); + } else { + if (priv->input_key) { + nm_clear_g_free(&priv->input_key); + _notify(self, PROP_INPUT_KEY); + } + } + + if (NM_FLAGS_HAS(lnk->output_flags, NM_GRE_KEY)) { + key = g_strdup_printf("%u", lnk->output_key); + if (g_strcmp0(priv->output_key, key)) { + g_free(priv->output_key); + priv->output_key = key; + _notify(self, PROP_OUTPUT_KEY); + } else + g_free(key); + } else { + if (priv->output_key) { + nm_clear_g_free(&priv->output_key); + _notify(self, PROP_OUTPUT_KEY); + } + } + } else if (priv->mode == NM_IP_TUNNEL_MODE_SIT) { + const NMPlatformLnkSit *lnk; + + lnk = nm_platform_link_get_lnk_sit(nm_device_get_platform(device), ifindex, NULL); + if (!lnk) { + _LOGW(LOGD_PLATFORM, "could not read %s properties", "sit"); + goto clear; + } + + parent_ifindex = lnk->parent_ifindex; + local.addr4 = lnk->local; + remote.addr4 = lnk->remote; + ttl = lnk->ttl; + tos = lnk->tos; + pmtud = lnk->path_mtu_discovery; + } else if (priv->mode == NM_IP_TUNNEL_MODE_IPIP) { + const NMPlatformLnkIpIp *lnk; + + lnk = nm_platform_link_get_lnk_ipip(nm_device_get_platform(device), ifindex, NULL); + if (!lnk) { + _LOGW(LOGD_PLATFORM, "could not read %s properties", "ipip"); + goto clear; + } + + parent_ifindex = lnk->parent_ifindex; + local.addr4 = lnk->local; + remote.addr4 = lnk->remote; + ttl = lnk->ttl; + tos = lnk->tos; + pmtud = lnk->path_mtu_discovery; + } else if (NM_IN_SET(priv->mode, + NM_IP_TUNNEL_MODE_IPIP6, + NM_IP_TUNNEL_MODE_IP6IP6, + NM_IP_TUNNEL_MODE_IP6GRE, + NM_IP_TUNNEL_MODE_IP6GRETAP)) { + const NMPlatformLnkIp6Tnl *lnk; + NMPlatform * plat = nm_device_get_platform(device); + + if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) + lnk = nm_platform_link_get_lnk_ip6gre(plat, ifindex, NULL); + else if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRETAP) + lnk = nm_platform_link_get_lnk_ip6gretap(plat, ifindex, NULL); + else + lnk = nm_platform_link_get_lnk_ip6tnl(plat, ifindex, NULL); + + if (!lnk) { + _LOGW(LOGD_PLATFORM, "could not read %s properties", "ip6tnl"); + goto clear; + } + + parent_ifindex = lnk->parent_ifindex; + local.addr6 = lnk->local; + remote.addr6 = lnk->remote; + ttl = lnk->ttl; + tos = lnk->tclass; + encap_limit = lnk->encap_limit; + flow_label = lnk->flow_label; + flags = ip6tnl_flags_plat_to_setting(lnk->flags); + + if (NM_IN_SET(priv->mode, NM_IP_TUNNEL_MODE_IP6GRE, NM_IP_TUNNEL_MODE_IP6GRETAP)) { + if (NM_FLAGS_HAS(lnk->input_flags, NM_GRE_KEY)) { + key = g_strdup_printf("%u", lnk->input_key); + if (g_strcmp0(priv->input_key, key)) { + g_free(priv->input_key); + priv->input_key = key; + _notify(self, PROP_INPUT_KEY); + } else + g_free(key); + } else { + if (priv->input_key) { + nm_clear_g_free(&priv->input_key); + _notify(self, PROP_INPUT_KEY); + } + } + + if (NM_FLAGS_HAS(lnk->output_flags, NM_GRE_KEY)) { + key = g_strdup_printf("%u", lnk->output_key); + if (g_strcmp0(priv->output_key, key)) { + g_free(priv->output_key); + priv->output_key = key; + _notify(self, PROP_OUTPUT_KEY); + } else + g_free(key); + } else { + if (priv->output_key) { + nm_clear_g_free(&priv->output_key); + _notify(self, PROP_OUTPUT_KEY); + } + } + } + } else + g_return_if_reached(); + + nm_device_parent_set_ifindex(device, parent_ifindex); + + if (address_set(priv->addr_family, &priv->local, &local)) + _notify(self, PROP_LOCAL); + if (address_set(priv->addr_family, &priv->remote, &remote)) + _notify(self, PROP_REMOTE); out: - if (priv->ttl != ttl) { - priv->ttl = ttl; - _notify (self, PROP_TTL); - } - - if (priv->tos != tos) { - priv->tos = tos; - _notify (self, PROP_TOS); - } - - if (priv->path_mtu_discovery != pmtud) { - priv->path_mtu_discovery = pmtud; - _notify (self, PROP_PATH_MTU_DISCOVERY); - } - - if (priv->encap_limit != encap_limit) { - priv->encap_limit = encap_limit; - _notify (self, PROP_ENCAPSULATION_LIMIT); - } - - if (priv->flow_label != flow_label) { - priv->flow_label = flow_label; - _notify (self, PROP_FLOW_LABEL); - } - - if (priv->flags != flags) { - priv->flags = flags; - _notify (self, PROP_FLAGS); - } + if (priv->ttl != ttl) { + priv->ttl = ttl; + _notify(self, PROP_TTL); + } + + if (priv->tos != tos) { + priv->tos = tos; + _notify(self, PROP_TOS); + } + + if (priv->path_mtu_discovery != pmtud) { + priv->path_mtu_discovery = pmtud; + _notify(self, PROP_PATH_MTU_DISCOVERY); + } + + if (priv->encap_limit != encap_limit) { + priv->encap_limit = encap_limit; + _notify(self, PROP_ENCAPSULATION_LIMIT); + } + + if (priv->flow_label != flow_label) { + priv->flow_label = flow_label; + _notify(self, PROP_FLOW_LABEL); + } + + if (priv->flags != flags) { + priv->flags = flags; + _notify(self, PROP_FLAGS); + } } static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - update_properties_from_ifindex (device, nm_device_get_ifindex (device)); + update_properties_from_ifindex(device, nm_device_get_ifindex(device)); } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_ip_tunnel_parent_class)->link_changed(device, pllink); + update_properties(device); } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingIPTunnel *s_ip_tunnel; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_IP_TUNNEL_SETTING_NAME, - existing_connections, - NULL, - _("IP tunnel connection"), - NULL, - NULL, - TRUE); - - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - if (!s_ip_tunnel) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'tunnel' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingIPTunnel *s_ip_tunnel; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_IP_TUNNEL_SETTING_NAME, + existing_connections, + NULL, + _("IP tunnel connection"), + NULL, + NULL, + TRUE); + + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + if (!s_ip_tunnel) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'tunnel' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); - NMSettingIPTunnel *s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - - if (!s_ip_tunnel) { - s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new (); - nm_connection_add_setting (connection, (NMSetting *) s_ip_tunnel); - } - - if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode) - g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_MODE, priv->mode, NULL); - - g_object_set (s_ip_tunnel, - NM_SETTING_IP_TUNNEL_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_ip_tunnel_get_parent (s_ip_tunnel)), - NULL); - - if (!address_equal_pp (priv->addr_family, - nm_setting_ip_tunnel_get_local (s_ip_tunnel), - priv->local)) - g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_LOCAL, priv->local, NULL); - - if (!address_equal_pp (priv->addr_family, - nm_setting_ip_tunnel_get_remote (s_ip_tunnel), - priv->remote)) - g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_REMOTE, priv->remote, NULL); - - if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl) - g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TTL, priv->ttl, NULL); - - if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos) - g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TOS, priv->tos, NULL); - - if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) { - g_object_set (G_OBJECT (s_ip_tunnel), - NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY, - priv->path_mtu_discovery, - NULL); - } - - if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) { - g_object_set (G_OBJECT (s_ip_tunnel), - NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, - priv->encap_limit, - NULL); - } - - if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) { - g_object_set (G_OBJECT (s_ip_tunnel), - NM_SETTING_IP_TUNNEL_FLOW_LABEL, - priv->flow_label, - NULL); - } - - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_GRE, - NM_IP_TUNNEL_MODE_GRETAP, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { - if (g_strcmp0 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), priv->input_key)) { - g_object_set (G_OBJECT (s_ip_tunnel), - NM_SETTING_IP_TUNNEL_INPUT_KEY, - priv->input_key, - NULL); - } - if (g_strcmp0 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), priv->output_key)) { - g_object_set (G_OBJECT (s_ip_tunnel), - NM_SETTING_IP_TUNNEL_OUTPUT_KEY, - priv->output_key, - NULL); - } - } + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); + NMSettingIPTunnel * s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + + if (!s_ip_tunnel) { + s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new(); + nm_connection_add_setting(connection, (NMSetting *) s_ip_tunnel); + } + + if (nm_setting_ip_tunnel_get_mode(s_ip_tunnel) != priv->mode) + g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_MODE, priv->mode, NULL); + + g_object_set( + s_ip_tunnel, + NM_SETTING_IP_TUNNEL_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_ip_tunnel_get_parent(s_ip_tunnel)), + NULL); + + if (!address_equal_pp(priv->addr_family, + nm_setting_ip_tunnel_get_local(s_ip_tunnel), + priv->local)) + g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_LOCAL, priv->local, NULL); + + if (!address_equal_pp(priv->addr_family, + nm_setting_ip_tunnel_get_remote(s_ip_tunnel), + priv->remote)) + g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_REMOTE, priv->remote, NULL); + + if (nm_setting_ip_tunnel_get_ttl(s_ip_tunnel) != priv->ttl) + g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_TTL, priv->ttl, NULL); + + if (nm_setting_ip_tunnel_get_tos(s_ip_tunnel) != priv->tos) + g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_TOS, priv->tos, NULL); + + if (nm_setting_ip_tunnel_get_path_mtu_discovery(s_ip_tunnel) != priv->path_mtu_discovery) { + g_object_set(G_OBJECT(s_ip_tunnel), + NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY, + priv->path_mtu_discovery, + NULL); + } + + if (nm_setting_ip_tunnel_get_encapsulation_limit(s_ip_tunnel) != priv->encap_limit) { + g_object_set(G_OBJECT(s_ip_tunnel), + NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, + priv->encap_limit, + NULL); + } + + if (nm_setting_ip_tunnel_get_flow_label(s_ip_tunnel) != priv->flow_label) { + g_object_set(G_OBJECT(s_ip_tunnel), + NM_SETTING_IP_TUNNEL_FLOW_LABEL, + priv->flow_label, + NULL); + } + + if (NM_IN_SET(priv->mode, + NM_IP_TUNNEL_MODE_GRE, + NM_IP_TUNNEL_MODE_GRETAP, + NM_IP_TUNNEL_MODE_IP6GRE, + NM_IP_TUNNEL_MODE_IP6GRETAP)) { + if (g_strcmp0(nm_setting_ip_tunnel_get_input_key(s_ip_tunnel), priv->input_key)) { + g_object_set(G_OBJECT(s_ip_tunnel), + NM_SETTING_IP_TUNNEL_INPUT_KEY, + priv->input_key, + NULL); + } + if (g_strcmp0(nm_setting_ip_tunnel_get_output_key(s_ip_tunnel), priv->output_key)) { + g_object_set(G_OBJECT(s_ip_tunnel), + NM_SETTING_IP_TUNNEL_OUTPUT_KEY, + priv->output_key, + NULL); + } + } } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); - NMSettingIPTunnel *s_ip_tunnel; - const char *parent; - - if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - - if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "incompatible IP tunnel mode"); - return FALSE; - } - - if (nm_device_is_real (device)) { - /* Check parent interface; could be an interface name or a UUID */ - parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel); - if (parent && !nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IP tunnel parent mismatches"); - return FALSE; - } - - if (!address_equal_pp (priv->addr_family, - nm_setting_ip_tunnel_get_local (s_ip_tunnel), - priv->local)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "local IP tunnel address mismatches"); - return FALSE; - } - - if (!address_equal_pp (priv->addr_family, - nm_setting_ip_tunnel_get_remote (s_ip_tunnel), - priv->remote)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "remote IP tunnel address mismatches"); - return FALSE; - } - - if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "TTL of IP tunnel mismatches"); - return FALSE; - } - - if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "TOS of IP tunnel mismatches"); - return FALSE; - } - - if (priv->addr_family == AF_INET) { - if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MTU discovery setting of IP tunnel mismatches"); - return FALSE; - } - } else { - if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "encapsulation limit of IP tunnel mismatches"); - return FALSE; - } - - if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "flow-label of IP tunnel mismatches"); - return FALSE; - } - } - } - - return TRUE; + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); + NMSettingIPTunnel * s_ip_tunnel; + const char * parent; + + if (!NM_DEVICE_CLASS(nm_device_ip_tunnel_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + + if (nm_setting_ip_tunnel_get_mode(s_ip_tunnel) != priv->mode) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "incompatible IP tunnel mode"); + return FALSE; + } + + if (nm_device_is_real(device)) { + /* Check parent interface; could be an interface name or a UUID */ + parent = nm_setting_ip_tunnel_get_parent(s_ip_tunnel); + if (parent && !nm_device_match_parent(device, parent)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IP tunnel parent mismatches"); + return FALSE; + } + + if (!address_equal_pp(priv->addr_family, + nm_setting_ip_tunnel_get_local(s_ip_tunnel), + priv->local)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "local IP tunnel address mismatches"); + return FALSE; + } + + if (!address_equal_pp(priv->addr_family, + nm_setting_ip_tunnel_get_remote(s_ip_tunnel), + priv->remote)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "remote IP tunnel address mismatches"); + return FALSE; + } + + if (nm_setting_ip_tunnel_get_ttl(s_ip_tunnel) != priv->ttl) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "TTL of IP tunnel mismatches"); + return FALSE; + } + + if (nm_setting_ip_tunnel_get_tos(s_ip_tunnel) != priv->tos) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "TOS of IP tunnel mismatches"); + return FALSE; + } + + if (priv->addr_family == AF_INET) { + if (nm_setting_ip_tunnel_get_path_mtu_discovery(s_ip_tunnel) + != priv->path_mtu_discovery) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "MTU discovery setting of IP tunnel mismatches"); + return FALSE; + } + } else { + if (nm_setting_ip_tunnel_get_encapsulation_limit(s_ip_tunnel) != priv->encap_limit) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "encapsulation limit of IP tunnel mismatches"); + return FALSE; + } + + if (nm_setting_ip_tunnel_get_flow_label(s_ip_tunnel) != priv->flow_label) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "flow-label of IP tunnel mismatches"); + return FALSE; + } + } + } + + return TRUE; } static NMIPTunnelMode -platform_link_to_tunnel_mode (const NMPlatformLink *link) +platform_link_to_tunnel_mode(const NMPlatformLink *link) { - const NMPlatformLnkIp6Tnl *lnk; - - switch (link->type) { - case NM_LINK_TYPE_GRE: - return NM_IP_TUNNEL_MODE_GRE; - case NM_LINK_TYPE_GRETAP: - return NM_IP_TUNNEL_MODE_GRETAP; - case NM_LINK_TYPE_IP6TNL: - lnk = nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, link->ifindex, NULL); - if (lnk) { - if (lnk->proto == IPPROTO_IPIP) - return NM_IP_TUNNEL_MODE_IPIP6; - if (lnk->proto == IPPROTO_IPV6) - return NM_IP_TUNNEL_MODE_IP6IP6; - } - return NM_IP_TUNNEL_MODE_UNKNOWN; - case NM_LINK_TYPE_IP6GRE: - return NM_IP_TUNNEL_MODE_IP6GRE; - case NM_LINK_TYPE_IP6GRETAP: - return NM_IP_TUNNEL_MODE_IP6GRETAP; - case NM_LINK_TYPE_IPIP: - return NM_IP_TUNNEL_MODE_IPIP; - case NM_LINK_TYPE_SIT: - return NM_IP_TUNNEL_MODE_SIT; - default: - g_return_val_if_reached (NM_IP_TUNNEL_MODE_UNKNOWN); - } + const NMPlatformLnkIp6Tnl *lnk; + + switch (link->type) { + case NM_LINK_TYPE_GRE: + return NM_IP_TUNNEL_MODE_GRE; + case NM_LINK_TYPE_GRETAP: + return NM_IP_TUNNEL_MODE_GRETAP; + case NM_LINK_TYPE_IP6TNL: + lnk = nm_platform_link_get_lnk_ip6tnl(NM_PLATFORM_GET, link->ifindex, NULL); + if (lnk) { + if (lnk->proto == IPPROTO_IPIP) + return NM_IP_TUNNEL_MODE_IPIP6; + if (lnk->proto == IPPROTO_IPV6) + return NM_IP_TUNNEL_MODE_IP6IP6; + } + return NM_IP_TUNNEL_MODE_UNKNOWN; + case NM_LINK_TYPE_IP6GRE: + return NM_IP_TUNNEL_MODE_IP6GRE; + case NM_LINK_TYPE_IP6GRETAP: + return NM_IP_TUNNEL_MODE_IP6GRETAP; + case NM_LINK_TYPE_IPIP: + return NM_IP_TUNNEL_MODE_IPIP; + case NM_LINK_TYPE_SIT: + return NM_IP_TUNNEL_MODE_SIT; + default: + g_return_val_if_reached(NM_IP_TUNNEL_MODE_UNKNOWN); + } } static NMLinkType -tunnel_mode_to_link_type (NMIPTunnelMode tunnel_mode) +tunnel_mode_to_link_type(NMIPTunnelMode tunnel_mode) { - switch (tunnel_mode) { - case NM_IP_TUNNEL_MODE_GRE: - return NM_LINK_TYPE_GRE; - case NM_IP_TUNNEL_MODE_GRETAP: - return NM_LINK_TYPE_GRETAP; - case NM_IP_TUNNEL_MODE_IPIP6: - case NM_IP_TUNNEL_MODE_IP6IP6: - return NM_LINK_TYPE_IP6TNL; - case NM_IP_TUNNEL_MODE_IP6GRE: - return NM_LINK_TYPE_IP6GRE; - case NM_IP_TUNNEL_MODE_IP6GRETAP: - return NM_LINK_TYPE_IP6GRETAP; - case NM_IP_TUNNEL_MODE_IPIP: - return NM_LINK_TYPE_IPIP; - case NM_IP_TUNNEL_MODE_SIT: - return NM_LINK_TYPE_SIT; - case NM_IP_TUNNEL_MODE_VTI: - case NM_IP_TUNNEL_MODE_VTI6: - case NM_IP_TUNNEL_MODE_ISATAP: - return NM_LINK_TYPE_UNKNOWN; - case NM_IP_TUNNEL_MODE_UNKNOWN: - break; - } - g_return_val_if_reached (NM_LINK_TYPE_UNKNOWN); + switch (tunnel_mode) { + case NM_IP_TUNNEL_MODE_GRE: + return NM_LINK_TYPE_GRE; + case NM_IP_TUNNEL_MODE_GRETAP: + return NM_LINK_TYPE_GRETAP; + case NM_IP_TUNNEL_MODE_IPIP6: + case NM_IP_TUNNEL_MODE_IP6IP6: + return NM_LINK_TYPE_IP6TNL; + case NM_IP_TUNNEL_MODE_IP6GRE: + return NM_LINK_TYPE_IP6GRE; + case NM_IP_TUNNEL_MODE_IP6GRETAP: + return NM_LINK_TYPE_IP6GRETAP; + case NM_IP_TUNNEL_MODE_IPIP: + return NM_LINK_TYPE_IPIP; + case NM_IP_TUNNEL_MODE_SIT: + return NM_LINK_TYPE_SIT; + case NM_IP_TUNNEL_MODE_VTI: + case NM_IP_TUNNEL_MODE_VTI6: + case NM_IP_TUNNEL_MODE_ISATAP: + return NM_LINK_TYPE_UNKNOWN; + case NM_IP_TUNNEL_MODE_UNKNOWN: + break; + } + g_return_val_if_reached(NM_LINK_TYPE_UNKNOWN); } /*****************************************************************************/ static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMSettingIPTunnel *s_ip_tunnel; - NMPlatformLnkGre lnk_gre = { }; - NMPlatformLnkSit lnk_sit = { }; - NMPlatformLnkIpIp lnk_ipip = { }; - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - const char *str; - gint64 val; - NMIPTunnelMode mode; - int r; - gs_free char *hwaddr = NULL; - guint8 mac_address[ETH_ALEN]; - gboolean mac_address_valid = FALSE; - - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - nm_assert (NM_IS_SETTING_IP_TUNNEL (s_ip_tunnel)); - - mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); - - if ( _nm_ip_tunnel_mode_is_layer2 (mode) - && nm_device_hw_addr_get_cloned (device, - connection, - FALSE, - &hwaddr, - NULL, - NULL) - && hwaddr) { - /* FIXME: we set the MAC address when creating the interface, while the - * NMDevice is still unrealized. As we afterwards realize the device, it - * forgets the parameters for the cloned MAC address, and in stage 1 - * it might create a different MAC address. That should be fixed by - * better handling device realization. */ - if (!nm_utils_hwaddr_aton (hwaddr, mac_address, ETH_ALEN)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Invalid hardware address '%s'", - hwaddr); - g_return_val_if_reached (FALSE); - } - - mac_address_valid = TRUE; - } - - switch (mode) { - case NM_IP_TUNNEL_MODE_GRETAP: - lnk_gre.is_tap = TRUE; - /* fall-through */ - case NM_IP_TUNNEL_MODE_GRE: - if (parent) - lnk_gre.parent_ifindex = nm_device_get_ifindex (parent); - - str = nm_setting_ip_tunnel_get_local (s_ip_tunnel); - if (str) - inet_pton (AF_INET, str, &lnk_gre.local); - - str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel); - g_assert (str); - inet_pton (AF_INET, str, &lnk_gre.remote); - - lnk_gre.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel); - lnk_gre.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel); - lnk_gre.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel); - - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_gre.input_key = val; - lnk_gre.input_flags = NM_GRE_KEY; - } - - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_gre.output_key = val; - lnk_gre.output_flags = NM_GRE_KEY; - } - - r = nm_platform_link_gre_add (nm_device_get_platform (device), - iface, - mac_address_valid ? mac_address : NULL, - mac_address_valid ? ETH_ALEN : 0, - &lnk_gre, - out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create GRE interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - break; - case NM_IP_TUNNEL_MODE_SIT: - if (parent) - lnk_sit.parent_ifindex = nm_device_get_ifindex (parent); - - str = nm_setting_ip_tunnel_get_local (s_ip_tunnel); - if (str) - inet_pton (AF_INET, str, &lnk_sit.local); - - str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel); - g_assert (str); - inet_pton (AF_INET, str, &lnk_sit.remote); - - lnk_sit.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel); - lnk_sit.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel); - lnk_sit.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel); - - r = nm_platform_link_sit_add (nm_device_get_platform (device), iface, &lnk_sit, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create SIT interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - break; - case NM_IP_TUNNEL_MODE_IPIP: - if (parent) - lnk_ipip.parent_ifindex = nm_device_get_ifindex (parent); - - str = nm_setting_ip_tunnel_get_local (s_ip_tunnel); - if (str) - inet_pton (AF_INET, str, &lnk_ipip.local); - - str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel); - g_assert (str); - inet_pton (AF_INET, str, &lnk_ipip.remote); - - lnk_ipip.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel); - lnk_ipip.tos = nm_setting_ip_tunnel_get_tos (s_ip_tunnel); - lnk_ipip.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel); - - r = nm_platform_link_ipip_add (nm_device_get_platform (device), iface, &lnk_ipip, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create IPIP interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - break; - case NM_IP_TUNNEL_MODE_IPIP6: - case NM_IP_TUNNEL_MODE_IP6IP6: - case NM_IP_TUNNEL_MODE_IP6GRE: - case NM_IP_TUNNEL_MODE_IP6GRETAP: - if (parent) - lnk_ip6tnl.parent_ifindex = nm_device_get_ifindex (parent); - - str = nm_setting_ip_tunnel_get_local (s_ip_tunnel); - if (str) - inet_pton (AF_INET6, str, &lnk_ip6tnl.local); - - str = nm_setting_ip_tunnel_get_remote (s_ip_tunnel); - g_assert (str); - inet_pton (AF_INET6, str, &lnk_ip6tnl.remote); - - lnk_ip6tnl.ttl = nm_setting_ip_tunnel_get_ttl (s_ip_tunnel); - lnk_ip6tnl.tclass = nm_setting_ip_tunnel_get_tos (s_ip_tunnel); - lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel); - lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel); - lnk_ip6tnl.flags = ip6tnl_flags_setting_to_plat (nm_setting_ip_tunnel_get_flags (s_ip_tunnel)); - - if (NM_IN_SET (mode, NM_IP_TUNNEL_MODE_IP6GRE, NM_IP_TUNNEL_MODE_IP6GRETAP)) { - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_ip6tnl.input_key = val; - lnk_ip6tnl.input_flags = NM_GRE_KEY; - } - - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_ip6tnl.output_key = val; - lnk_ip6tnl.output_flags = NM_GRE_KEY; - } - - lnk_ip6tnl.is_gre = TRUE; - lnk_ip6tnl.is_tap = (mode == NM_IP_TUNNEL_MODE_IP6GRETAP); - - r = nm_platform_link_ip6gre_add (nm_device_get_platform (device), - iface, - mac_address_valid ? mac_address : NULL, - mac_address_valid ? ETH_ALEN : 0, - &lnk_ip6tnl, out_plink); - } else { - lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 - ? IPPROTO_IPIP - : IPPROTO_IPV6; - r = nm_platform_link_ip6tnl_add (nm_device_get_platform (device), - iface, &lnk_ip6tnl, out_plink); - } - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create IPv6 tunnel interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - break; - default: - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create IP tunnel interface '%s' for '%s': mode %d not supported", - iface, - nm_connection_get_id (connection), - (int) nm_setting_ip_tunnel_get_mode (s_ip_tunnel)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMSettingIPTunnel * s_ip_tunnel; + NMPlatformLnkGre lnk_gre = {}; + NMPlatformLnkSit lnk_sit = {}; + NMPlatformLnkIpIp lnk_ipip = {}; + NMPlatformLnkIp6Tnl lnk_ip6tnl = {}; + const char * str; + gint64 val; + NMIPTunnelMode mode; + int r; + gs_free char * hwaddr = NULL; + guint8 mac_address[ETH_ALEN]; + gboolean mac_address_valid = FALSE; + + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + nm_assert(NM_IS_SETTING_IP_TUNNEL(s_ip_tunnel)); + + mode = nm_setting_ip_tunnel_get_mode(s_ip_tunnel); + + if (_nm_ip_tunnel_mode_is_layer2(mode) + && nm_device_hw_addr_get_cloned(device, connection, FALSE, &hwaddr, NULL, NULL) && hwaddr) { + /* FIXME: we set the MAC address when creating the interface, while the + * NMDevice is still unrealized. As we afterwards realize the device, it + * forgets the parameters for the cloned MAC address, and in stage 1 + * it might create a different MAC address. That should be fixed by + * better handling device realization. */ + if (!nm_utils_hwaddr_aton(hwaddr, mac_address, ETH_ALEN)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Invalid hardware address '%s'", + hwaddr); + g_return_val_if_reached(FALSE); + } + + mac_address_valid = TRUE; + } + + switch (mode) { + case NM_IP_TUNNEL_MODE_GRETAP: + lnk_gre.is_tap = TRUE; + /* fall-through */ + case NM_IP_TUNNEL_MODE_GRE: + if (parent) + lnk_gre.parent_ifindex = nm_device_get_ifindex(parent); + + str = nm_setting_ip_tunnel_get_local(s_ip_tunnel); + if (str) + inet_pton(AF_INET, str, &lnk_gre.local); + + str = nm_setting_ip_tunnel_get_remote(s_ip_tunnel); + g_assert(str); + inet_pton(AF_INET, str, &lnk_gre.remote); + + lnk_gre.ttl = nm_setting_ip_tunnel_get_ttl(s_ip_tunnel); + lnk_gre.tos = nm_setting_ip_tunnel_get_tos(s_ip_tunnel); + lnk_gre.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery(s_ip_tunnel); + + val = _nm_utils_ascii_str_to_int64(nm_setting_ip_tunnel_get_input_key(s_ip_tunnel), + 10, + 0, + G_MAXUINT32, + -1); + if (val != -1) { + lnk_gre.input_key = val; + lnk_gre.input_flags = NM_GRE_KEY; + } + + val = _nm_utils_ascii_str_to_int64(nm_setting_ip_tunnel_get_output_key(s_ip_tunnel), + 10, + 0, + G_MAXUINT32, + -1); + if (val != -1) { + lnk_gre.output_key = val; + lnk_gre.output_flags = NM_GRE_KEY; + } + + r = nm_platform_link_gre_add(nm_device_get_platform(device), + iface, + mac_address_valid ? mac_address : NULL, + mac_address_valid ? ETH_ALEN : 0, + &lnk_gre, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create GRE interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + break; + case NM_IP_TUNNEL_MODE_SIT: + if (parent) + lnk_sit.parent_ifindex = nm_device_get_ifindex(parent); + + str = nm_setting_ip_tunnel_get_local(s_ip_tunnel); + if (str) + inet_pton(AF_INET, str, &lnk_sit.local); + + str = nm_setting_ip_tunnel_get_remote(s_ip_tunnel); + g_assert(str); + inet_pton(AF_INET, str, &lnk_sit.remote); + + lnk_sit.ttl = nm_setting_ip_tunnel_get_ttl(s_ip_tunnel); + lnk_sit.tos = nm_setting_ip_tunnel_get_tos(s_ip_tunnel); + lnk_sit.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery(s_ip_tunnel); + + r = nm_platform_link_sit_add(nm_device_get_platform(device), iface, &lnk_sit, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create SIT interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + break; + case NM_IP_TUNNEL_MODE_IPIP: + if (parent) + lnk_ipip.parent_ifindex = nm_device_get_ifindex(parent); + + str = nm_setting_ip_tunnel_get_local(s_ip_tunnel); + if (str) + inet_pton(AF_INET, str, &lnk_ipip.local); + + str = nm_setting_ip_tunnel_get_remote(s_ip_tunnel); + g_assert(str); + inet_pton(AF_INET, str, &lnk_ipip.remote); + + lnk_ipip.ttl = nm_setting_ip_tunnel_get_ttl(s_ip_tunnel); + lnk_ipip.tos = nm_setting_ip_tunnel_get_tos(s_ip_tunnel); + lnk_ipip.path_mtu_discovery = nm_setting_ip_tunnel_get_path_mtu_discovery(s_ip_tunnel); + + r = nm_platform_link_ipip_add(nm_device_get_platform(device), iface, &lnk_ipip, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create IPIP interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + break; + case NM_IP_TUNNEL_MODE_IPIP6: + case NM_IP_TUNNEL_MODE_IP6IP6: + case NM_IP_TUNNEL_MODE_IP6GRE: + case NM_IP_TUNNEL_MODE_IP6GRETAP: + if (parent) + lnk_ip6tnl.parent_ifindex = nm_device_get_ifindex(parent); + + str = nm_setting_ip_tunnel_get_local(s_ip_tunnel); + if (str) + inet_pton(AF_INET6, str, &lnk_ip6tnl.local); + + str = nm_setting_ip_tunnel_get_remote(s_ip_tunnel); + g_assert(str); + inet_pton(AF_INET6, str, &lnk_ip6tnl.remote); + + lnk_ip6tnl.ttl = nm_setting_ip_tunnel_get_ttl(s_ip_tunnel); + lnk_ip6tnl.tclass = nm_setting_ip_tunnel_get_tos(s_ip_tunnel); + lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit(s_ip_tunnel); + lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label(s_ip_tunnel); + lnk_ip6tnl.flags = + ip6tnl_flags_setting_to_plat(nm_setting_ip_tunnel_get_flags(s_ip_tunnel)); + + if (NM_IN_SET(mode, NM_IP_TUNNEL_MODE_IP6GRE, NM_IP_TUNNEL_MODE_IP6GRETAP)) { + val = _nm_utils_ascii_str_to_int64(nm_setting_ip_tunnel_get_input_key(s_ip_tunnel), + 10, + 0, + G_MAXUINT32, + -1); + if (val != -1) { + lnk_ip6tnl.input_key = val; + lnk_ip6tnl.input_flags = NM_GRE_KEY; + } + + val = _nm_utils_ascii_str_to_int64(nm_setting_ip_tunnel_get_output_key(s_ip_tunnel), + 10, + 0, + G_MAXUINT32, + -1); + if (val != -1) { + lnk_ip6tnl.output_key = val; + lnk_ip6tnl.output_flags = NM_GRE_KEY; + } + + lnk_ip6tnl.is_gre = TRUE; + lnk_ip6tnl.is_tap = (mode == NM_IP_TUNNEL_MODE_IP6GRETAP); + + r = nm_platform_link_ip6gre_add(nm_device_get_platform(device), + iface, + mac_address_valid ? mac_address : NULL, + mac_address_valid ? ETH_ALEN : 0, + &lnk_ip6tnl, + out_plink); + } else { + lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode(s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 + ? IPPROTO_IPIP + : IPPROTO_IPV6; + r = nm_platform_link_ip6tnl_add(nm_device_get_platform(device), + iface, + &lnk_ip6tnl, + out_plink); + } + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create IPv6 tunnel interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + break; + default: + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create IP tunnel interface '%s' for '%s': mode %d not supported", + iface, + nm_connection_get_id(connection), + (int) nm_setting_ip_tunnel_get_mode(s_ip_tunnel)); + return FALSE; + } + + return TRUE; } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - return nm_device_get_configured_mtu_from_connection (device, - NM_TYPE_SETTING_IP_TUNNEL, - out_source); + return nm_device_get_configured_mtu_from_connection(device, + NM_TYPE_SETTING_IP_TUNNEL, + out_source); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static void -unrealize_notify (NMDevice *device) +unrealize_notify(NMDevice *device) { - NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->unrealize_notify (device); + NM_DEVICE_CLASS(nm_device_ip_tunnel_parent_class)->unrealize_notify(device); - update_properties_from_ifindex (device, 0); + update_properties_from_ifindex(device, 0); } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) { - NMDeviceClass *device_class; - - /* Only handle ip-tunnel setting here, delegate other settings to parent class */ - if (nm_streq (setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_IP_TUNNEL_SETTING_NAME, - error, - NM_SETTING_IP_TUNNEL_MTU); /* reapplied with IP config */ - } - - device_class = NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class); - return device_class->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); + NMDeviceClass *device_class; + + /* Only handle ip-tunnel setting here, delegate other settings to parent class */ + if (nm_streq(setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME)) { + return nm_device_hash_check_invalid_keys( + diffs, + NM_SETTING_IP_TUNNEL_SETTING_NAME, + error, + NM_SETTING_IP_TUNNEL_MTU); /* reapplied with IP config */ + } + + device_class = NM_DEVICE_CLASS(nm_device_ip_tunnel_parent_class); + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); - - if ( _nm_ip_tunnel_mode_is_layer2 (priv->mode) - && !nm_device_hw_addr_set_cloned (device, - nm_device_get_applied_connection (device), - FALSE)) { - *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); + + if (_nm_ip_tunnel_mode_is_layer2(priv->mode) + && !nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE)) { + *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MODE: - g_value_set_uint (value, priv->mode); - break; - case PROP_LOCAL: - g_value_set_string (value, priv->local); - break; - case PROP_REMOTE: - g_value_set_string (value, priv->remote); - break; - case PROP_TTL: - g_value_set_uchar (value, priv->ttl); - break; - case PROP_TOS: - g_value_set_uchar (value, priv->tos); - break; - case PROP_PATH_MTU_DISCOVERY: - g_value_set_boolean (value, priv->path_mtu_discovery); - break; - case PROP_INPUT_KEY: - g_value_set_string (value, priv->input_key); - break; - case PROP_OUTPUT_KEY: - g_value_set_string (value, priv->output_key); - break; - case PROP_ENCAPSULATION_LIMIT: - g_value_set_uchar (value, priv->encap_limit); - break; - case PROP_FLOW_LABEL: - g_value_set_uint (value, priv->flow_label); - break; - case PROP_FLAGS: - g_value_set_uint (value, priv->flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_LOCAL: + g_value_set_string(value, priv->local); + break; + case PROP_REMOTE: + g_value_set_string(value, priv->remote); + break; + case PROP_TTL: + g_value_set_uchar(value, priv->ttl); + break; + case PROP_TOS: + g_value_set_uchar(value, priv->tos); + break; + case PROP_PATH_MTU_DISCOVERY: + g_value_set_boolean(value, priv->path_mtu_discovery); + break; + case PROP_INPUT_KEY: + g_value_set_string(value, priv->input_key); + break; + case PROP_OUTPUT_KEY: + g_value_set_string(value, priv->output_key); + break; + case PROP_ENCAPSULATION_LIMIT: + g_value_set_uchar(value, priv->encap_limit); + break; + case PROP_FLOW_LABEL: + g_value_set_uint(value, priv->flow_label); + break; + case PROP_FLAGS: + g_value_set_uint(value, priv->flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MODE: - priv->mode = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODE: + priv->mode = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } } /*****************************************************************************/ static void -nm_device_ip_tunnel_init (NMDeviceIPTunnel *self) -{ -} +nm_device_ip_tunnel_init(NMDeviceIPTunnel *self) +{} static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object); - - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IPIP6, - NM_IP_TUNNEL_MODE_IP6IP6, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) - priv->addr_family = AF_INET6; - else - priv->addr_family = AF_INET; - - G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->constructed (object); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(object); + + if (NM_IN_SET(priv->mode, + NM_IP_TUNNEL_MODE_IPIP6, + NM_IP_TUNNEL_MODE_IP6IP6, + NM_IP_TUNNEL_MODE_IP6GRE, + NM_IP_TUNNEL_MODE_IP6GRETAP)) + priv->addr_family = AF_INET6; + else + priv->addr_family = AF_INET; + + G_OBJECT_CLASS(nm_device_ip_tunnel_parent_class)->constructed(object); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (object); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(object); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); - nm_clear_g_free (&priv->local); - nm_clear_g_free (&priv->remote); - nm_clear_g_free (&priv->input_key); - nm_clear_g_free (&priv->output_key); + nm_clear_g_free(&priv->local); + nm_clear_g_free(&priv->remote); + nm_clear_g_free(&priv->input_key); + nm_clear_g_free(&priv->output_key); - G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_ip_tunnel_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_ip_tunnel = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Local", "s", NM_DEVICE_IP_TUNNEL_LOCAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Remote", "s", NM_DEVICE_IP_TUNNEL_REMOTE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PathMtuDiscovery", "b", NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("InputKey", "s", NM_DEVICE_IP_TUNNEL_INPUT_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("OutputKey", "s", NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("EncapsulationLimit", "y", NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FlowLabel", "u", NM_DEVICE_IP_TUNNEL_FLOW_LABEL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Flags", "u", NM_DEVICE_IP_TUNNEL_FLAGS), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Local", + "s", + NM_DEVICE_IP_TUNNEL_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Remote", + "s", + NM_DEVICE_IP_TUNNEL_REMOTE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + "PathMtuDiscovery", + "b", + NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("InputKey", + "s", + NM_DEVICE_IP_TUNNEL_INPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("OutputKey", + "s", + NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + "EncapsulationLimit", + "y", + NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FlowLabel", + "u", + NM_DEVICE_IP_TUNNEL_FLOW_LABEL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Flags", + "u", + NM_DEVICE_IP_TUNNEL_FLAGS), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) +nm_device_ip_tunnel_class_init(NMDeviceIPTunnelClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructed = constructed; - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ip_tunnel); - - device_class->connection_type_supported = NM_SETTING_IP_TUNNEL_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_IP_TUNNEL_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, - NM_LINK_TYPE_IPIP, - NM_LINK_TYPE_SIT); - - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->link_changed = link_changed; - device_class->can_reapply_change = can_reapply_change; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - device_class->check_connection_compatible = check_connection_compatible; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_configured_mtu = get_configured_mtu; - device_class->unrealize_notify = unrealize_notify; - - obj_properties[PROP_MODE] = - g_param_spec_uint (NM_DEVICE_IP_TUNNEL_MODE, "", "", - 0, G_MAXUINT, 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LOCAL] = - g_param_spec_string (NM_DEVICE_IP_TUNNEL_LOCAL, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_REMOTE] = - g_param_spec_string (NM_DEVICE_IP_TUNNEL_REMOTE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_TTL] = - g_param_spec_uchar (NM_DEVICE_IP_TUNNEL_TTL, "", "", - 0, 255, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_TOS] = - g_param_spec_uchar (NM_DEVICE_IP_TUNNEL_TOS, "", "", - 0, 255, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_PATH_MTU_DISCOVERY] = - g_param_spec_boolean (NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_INPUT_KEY] = - g_param_spec_string (NM_DEVICE_IP_TUNNEL_INPUT_KEY, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_OUTPUT_KEY] = - g_param_spec_string (NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ENCAPSULATION_LIMIT] = - g_param_spec_uchar (NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, "", "", - 0, 255, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FLOW_LABEL] = - g_param_spec_uint (NM_DEVICE_IP_TUNNEL_FLOW_LABEL, "", "", - 0, (1 << 20) - 1, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FLAGS] = - g_param_spec_uint (NM_DEVICE_IP_TUNNEL_FLAGS, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_ip_tunnel); + + device_class->connection_type_supported = NM_SETTING_IP_TUNNEL_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_IP_TUNNEL_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_GRE, + NM_LINK_TYPE_GRETAP, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IP6GRE, + NM_LINK_TYPE_IP6GRETAP, + NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_SIT); + + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->link_changed = link_changed; + device_class->can_reapply_change = can_reapply_change; + device_class->complete_connection = complete_connection; + device_class->update_connection = update_connection; + device_class->check_connection_compatible = check_connection_compatible; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_configured_mtu = get_configured_mtu; + device_class->unrealize_notify = unrealize_notify; + + obj_properties[PROP_MODE] = + g_param_spec_uint(NM_DEVICE_IP_TUNNEL_MODE, + "", + "", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_LOCAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_REMOTE] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_REMOTE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_TTL] = g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_PATH_MTU_DISCOVERY] = + g_param_spec_boolean(NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_INPUT_KEY] = g_param_spec_string(NM_DEVICE_IP_TUNNEL_INPUT_KEY, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_OUTPUT_KEY] = + g_param_spec_string(NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ENCAPSULATION_LIMIT] = + g_param_spec_uchar(NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FLOW_LABEL] = g_param_spec_uint(NM_DEVICE_IP_TUNNEL_FLOW_LABEL, + "", + "", + 0, + (1 << 20) - 1, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_DEVICE_IP_TUNNEL_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_IP_TUNNEL_DEVICE_FACTORY (nm_ip_tunnel_device_factory_get_type ()) -#define NM_IP_TUNNEL_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP_TUNNEL_DEVICE_FACTORY, NMIPTunnelDeviceFactory)) +#define NM_TYPE_IP_TUNNEL_DEVICE_FACTORY (nm_ip_tunnel_device_factory_get_type()) +#define NM_IP_TUNNEL_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IP_TUNNEL_DEVICE_FACTORY, NMIPTunnelDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - NMSettingIPTunnel *s_ip_tunnel; - NMIPTunnelMode mode; - NMLinkType link_type; - - if (connection) { - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); - link_type = tunnel_mode_to_link_type (mode); - } else { - link_type = plink->type; - mode = platform_link_to_tunnel_mode (plink); - } - - if (mode == NM_IP_TUNNEL_MODE_UNKNOWN || link_type == NM_LINK_TYPE_UNKNOWN) - return NULL; - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_IP_TUNNEL, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "IPTunnel", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_IP_TUNNEL, - NM_DEVICE_LINK_TYPE, link_type, - NM_DEVICE_IP_TUNNEL_MODE, mode, - NULL); + NMSettingIPTunnel *s_ip_tunnel; + NMIPTunnelMode mode; + NMLinkType link_type; + + if (connection) { + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + mode = nm_setting_ip_tunnel_get_mode(s_ip_tunnel); + link_type = tunnel_mode_to_link_type(mode); + } else { + link_type = plink->type; + mode = platform_link_to_tunnel_mode(plink); + } + + if (mode == NM_IP_TUNNEL_MODE_UNKNOWN || link_type == NM_LINK_TYPE_UNKNOWN) + return NULL; + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_IP_TUNNEL, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "IPTunnel", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_IP_TUNNEL, + NM_DEVICE_LINK_TYPE, + link_type, + NM_DEVICE_IP_TUNNEL_MODE, + mode, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingIPTunnel *s_ip_tunnel; + NMSettingIPTunnel *s_ip_tunnel; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_IP_TUNNEL_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_IP_TUNNEL_SETTING_NAME), + NULL); - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - g_assert (s_ip_tunnel); + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + g_assert(s_ip_tunnel); - return nm_setting_ip_tunnel_get_parent (s_ip_tunnel); + return nm_setting_ip_tunnel_get_parent(s_ip_tunnel); } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - const char *ifname; - NMSettingIPTunnel *s_ip_tunnel; + const char * ifname; + NMSettingIPTunnel *s_ip_tunnel; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_IP_TUNNEL_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_IP_TUNNEL_SETTING_NAME), + NULL); - s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); - g_assert (s_ip_tunnel); + s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); + g_assert(s_ip_tunnel); - if (nm_setting_ip_tunnel_get_parent (s_ip_tunnel) && !parent_iface) - return NULL; + if (nm_setting_ip_tunnel_get_parent(s_ip_tunnel) && !parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); + ifname = nm_connection_get_interface_name(connection); - return g_strdup (ifname); + return g_strdup(ifname); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (IP_TUNNEL, IPTunnel, ip_tunnel, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_SIT, - NM_LINK_TYPE_IPIP, - NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_IP_TUNNEL_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + IP_TUNNEL, + IPTunnel, + ip_tunnel, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_GRE, + NM_LINK_TYPE_GRETAP, + NM_LINK_TYPE_SIT, + NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IP6GRE, + NM_LINK_TYPE_IP6GRETAP) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_IP_TUNNEL_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-ip-tunnel.h b/src/devices/nm-device-ip-tunnel.h index a8f30711..0d9211ec 100644 --- a/src/devices/nm-device-ip-tunnel.h +++ b/src/devices/nm-device-ip-tunnel.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -9,12 +9,16 @@ #include "nm-core-types.h" #include "nm-device.h" -#define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type ()) -#define NM_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) -#define NM_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) -#define NM_IS_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_IP_TUNNEL)) -#define NM_IS_DEVICE_IP_TUNNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_IP_TUNNEL)) -#define NM_DEVICE_IP_TUNNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) +#define NM_TYPE_DEVICE_IP_TUNNEL (nm_device_ip_tunnel_get_type()) +#define NM_DEVICE_IP_TUNNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnel)) +#define NM_DEVICE_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) +#define NM_IS_DEVICE_IP_TUNNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_IS_DEVICE_IP_TUNNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IP_TUNNEL)) +#define NM_DEVICE_IP_TUNNEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelClass)) #define NM_DEVICE_IP_TUNNEL_MODE "mode" #define NM_DEVICE_IP_TUNNEL_LOCAL "local" @@ -28,9 +32,9 @@ #define NM_DEVICE_IP_TUNNEL_FLOW_LABEL "flow-label" #define NM_DEVICE_IP_TUNNEL_FLAGS "flags" -typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel; +typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel; typedef struct _NMDeviceIPTunnelClass NMDeviceIPTunnelClass; -GType nm_device_ip_tunnel_get_type (void); +GType nm_device_ip_tunnel_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_IP_TUNNEL_H__ */ diff --git a/src/devices/nm-device-logging.h b/src/devices/nm-device-logging.h index 2c56e526..d1291020 100644 --- a/src/devices/nm-device-logging.h +++ b/src/devices/nm-device-logging.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -8,32 +8,36 @@ #include "nm-device.h" -#define _LOG_DECLARE_SELF(t) \ -_nm_unused \ -static inline NMDevice * \ -_nm_device_log_self_to_device (t *self) \ -{ \ - return (NMDevice *) self; \ -} +#define _LOG_DECLARE_SELF(t) \ + _nm_unused static inline NMDevice *_nm_device_log_self_to_device(t *self) \ + { \ + return (NMDevice *) self; \ + } -#undef _NMLOG_ENABLED -#define _NMLOG_ENABLED(level, domain) ( nm_logging_enabled ((level), (domain)) ) -#define _NMLOG(level, domain, ...) \ - G_STMT_START { \ - const NMLogLevel _level = (level); \ - const NMLogDomain _domain = (domain); \ - \ - if (nm_logging_enabled (_level, _domain)) { \ - typeof (*self) *const _self = (self); \ - const char *const _ifname = _nm_device_get_iface (_nm_device_log_self_to_device (_self)); \ - \ - nm_log_obj (_level, _domain, \ - _ifname, NULL, \ - _self, "device", \ - "%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - NM_PRINT_FMT_QUOTED (_ifname, "(", _ifname, ")", "[null]") \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#undef _NMLOG_ENABLED +#define _NMLOG_ENABLED(level, domain) (nm_logging_enabled((level), (domain))) +#define _NMLOG(level, domain, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + const NMLogDomain _domain = (domain); \ + \ + if (nm_logging_enabled(_level, _domain)) { \ + typeof(*self) *const _self = (self); \ + const char *const _ifname = \ + _nm_device_get_iface(_nm_device_log_self_to_device(_self)); \ + \ + nm_log_obj(_level, \ + _domain, \ + _ifname, \ + NULL, \ + _self, \ + "device", \ + "%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_PRINT_FMT_QUOTED(_ifname, "(", _ifname, ")", "[null]") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END #endif /* __NETWORKMANAGER_DEVICE_LOGGING_H__ */ diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index 94edc947..7d738b42 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -27,1024 +27,1062 @@ _LOG_DECLARE_SELF(NMDeviceMacsec); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceMacsec, - PROP_SCI, - PROP_CIPHER_SUITE, - PROP_ICV_LENGTH, - PROP_WINDOW, - PROP_ENCODING_SA, - PROP_ENCRYPT, - PROP_PROTECT, - PROP_INCLUDE_SCI, - PROP_ES, - PROP_SCB, - PROP_REPLAY_PROTECT, - PROP_VALIDATION, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceMacsec, + PROP_SCI, + PROP_CIPHER_SUITE, + PROP_ICV_LENGTH, + PROP_WINDOW, + PROP_ENCODING_SA, + PROP_ENCRYPT, + PROP_PROTECT, + PROP_INCLUDE_SCI, + PROP_ES, + PROP_SCB, + PROP_REPLAY_PROTECT, + PROP_VALIDATION, ); typedef struct { - NMPlatformLnkMacsec props; - gulong parent_state_id; - gulong parent_mtu_id; + NMPlatformLnkMacsec props; + gulong parent_state_id; + gulong parent_mtu_id; - struct { - NMSupplicantManager *mgr; - NMSupplMgrCreateIfaceHandle *create_handle; - NMSupplicantInterface *iface; + struct { + NMSupplicantManager * mgr; + NMSupplMgrCreateIfaceHandle *create_handle; + NMSupplicantInterface * iface; - gulong iface_state_id; + gulong iface_state_id; - guint con_timeout_id; - guint lnk_timeout_id; + guint con_timeout_id; + guint lnk_timeout_id; - bool is_associated:1; - } supplicant; + bool is_associated : 1; + } supplicant; - NMActRequestGetSecretsCallId *macsec_secrets_id; + NMActRequestGetSecretsCallId *macsec_secrets_id; } NMDeviceMacsecPrivate; struct _NMDeviceMacsec { - NMDevice parent; - NMDeviceMacsecPrivate _priv; + NMDevice parent; + NMDeviceMacsecPrivate _priv; }; struct _NMDeviceMacsecClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceMacsec, nm_device_macsec, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceMacsec, nm_device_macsec, NM_TYPE_DEVICE) -#define NM_DEVICE_MACSEC_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceMacsec, NM_IS_DEVICE_MACSEC, NMDevice) +#define NM_DEVICE_MACSEC_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceMacsec, NM_IS_DEVICE_MACSEC, NMDevice) /******************************************************************/ -static void macsec_secrets_cancel (NMDeviceMacsec *self); +static void macsec_secrets_cancel(NMDeviceMacsec *self); /******************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (validation_mode_to_string, guint8, - NM_UTILS_LOOKUP_DEFAULT_WARN (""), - NM_UTILS_LOOKUP_STR_ITEM (0, "disable"), - NM_UTILS_LOOKUP_STR_ITEM (1, "check"), - NM_UTILS_LOOKUP_STR_ITEM (2, "strict"), -); +static NM_UTILS_LOOKUP_STR_DEFINE(validation_mode_to_string, + guint8, + NM_UTILS_LOOKUP_DEFAULT_WARN(""), + NM_UTILS_LOOKUP_STR_ITEM(0, "disable"), + NM_UTILS_LOOKUP_STR_ITEM(1, "check"), + NM_UTILS_LOOKUP_STR_ITEM(2, "strict"), ); static void -parent_state_changed (NMDevice *parent, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) +parent_state_changed(NMDevice * parent, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); + NMDeviceMacsec *self = NM_DEVICE_MACSEC(user_data); - /* We'll react to our own carrier state notifications. Ignore the parent's. */ - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CARRIER) - return; + /* We'll react to our own carrier state notifications. Ignore the parent's. */ + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_CARRIER) + return; - nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); + nm_device_set_unmanaged_by_flags(NM_DEVICE(self), + NM_UNMANAGED_PARENT, + !nm_device_get_managed(parent, FALSE), + reason); } static void -parent_mtu_maybe_changed (NMDevice *parent, - GParamSpec *pspec, - gpointer user_data) +parent_mtu_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_data) { - /* the MTU of a MACsec device is limited by the parent's MTU. - * - * When the parent's MTU changes, try to re-set the MTU. */ - nm_device_commit_mtu (user_data); + /* the MTU of a MACsec device is limited by the parent's MTU. + * + * When the parent's MTU changes, try to re-set the MTU. */ + nm_device_commit_mtu(user_data); } static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *device, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (device); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - - NM_DEVICE_CLASS (nm_device_macsec_parent_class)->parent_changed_notify (device, - old_ifindex, - old_parent, - new_ifindex, - new_parent); - - /* note that @self doesn't have to clear @parent_state_id on dispose, - * because NMDevice's dispose() will unset the parent, which in turn calls - * parent_changed_notify(). */ - nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); - nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id); - - if (new_parent) { - priv->parent_state_id = g_signal_connect (new_parent, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (parent_state_changed), - device); - priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU, - G_CALLBACK (parent_mtu_maybe_changed), device); - - - /* Set parent-dependent unmanaged flag */ - nm_device_set_unmanaged_by_flags (device, - NM_UNMANAGED_PARENT, - !nm_device_get_managed (new_parent, FALSE), - NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); - } - - /* Recheck availability now that the parent has changed */ - if (new_ifindex > 0) { - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_PARENT_CHANGED, - NM_DEVICE_STATE_REASON_PARENT_CHANGED); - } + NMDeviceMacsec * self = NM_DEVICE_MACSEC(device); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + + NM_DEVICE_CLASS(nm_device_macsec_parent_class) + ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent); + + /* note that @self doesn't have to clear @parent_state_id on dispose, + * because NMDevice's dispose() will unset the parent, which in turn calls + * parent_changed_notify(). */ + nm_clear_g_signal_handler(old_parent, &priv->parent_state_id); + nm_clear_g_signal_handler(old_parent, &priv->parent_mtu_id); + + if (new_parent) { + priv->parent_state_id = g_signal_connect(new_parent, + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(parent_state_changed), + device); + priv->parent_mtu_id = g_signal_connect(new_parent, + "notify::" NM_DEVICE_MTU, + G_CALLBACK(parent_mtu_maybe_changed), + device); + + /* Set parent-dependent unmanaged flag */ + nm_device_set_unmanaged_by_flags(device, + NM_UNMANAGED_PARENT, + !nm_device_get_managed(new_parent, FALSE), + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); + } + + /* Recheck availability now that the parent has changed */ + if (new_ifindex > 0) { + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_PARENT_CHANGED, + NM_DEVICE_STATE_REASON_PARENT_CHANGED); + } } static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceMacsec *self; - NMDeviceMacsecPrivate *priv; - const NMPlatformLink *plink = NULL; - const NMPlatformLnkMacsec *props = NULL; - int ifindex; - - g_return_if_fail (NM_IS_DEVICE_MACSEC (device)); - self = NM_DEVICE_MACSEC (device); - priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - - ifindex = nm_device_get_ifindex (device); - g_return_if_fail (ifindex > 0); - props = nm_platform_link_get_lnk_macsec (nm_device_get_platform (device), ifindex, &plink); - - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get macsec properties"); - return; - } - - g_object_freeze_notify ((GObject *) device); - - if (priv->props.parent_ifindex != props->parent_ifindex) - nm_device_parent_set_ifindex (device, props->parent_ifindex); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->props.field != props->field) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED (sci, PROP_SCI); - CHECK_PROPERTY_CHANGED (cipher_suite, PROP_CIPHER_SUITE); - CHECK_PROPERTY_CHANGED (window, PROP_WINDOW); - CHECK_PROPERTY_CHANGED (icv_length, PROP_ICV_LENGTH); - CHECK_PROPERTY_CHANGED (encoding_sa, PROP_ENCODING_SA); - CHECK_PROPERTY_CHANGED (validation, PROP_VALIDATION); - CHECK_PROPERTY_CHANGED (encrypt, PROP_ENCRYPT); - CHECK_PROPERTY_CHANGED (protect, PROP_PROTECT); - CHECK_PROPERTY_CHANGED (include_sci, PROP_INCLUDE_SCI); - CHECK_PROPERTY_CHANGED (es, PROP_ES); - CHECK_PROPERTY_CHANGED (scb, PROP_SCB); - CHECK_PROPERTY_CHANGED (replay_protect, PROP_REPLAY_PROTECT); - - g_object_thaw_notify ((GObject *) device); + NMDeviceMacsec * self; + NMDeviceMacsecPrivate * priv; + const NMPlatformLink * plink = NULL; + const NMPlatformLnkMacsec *props = NULL; + int ifindex; + + g_return_if_fail(NM_IS_DEVICE_MACSEC(device)); + self = NM_DEVICE_MACSEC(device); + priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + + ifindex = nm_device_get_ifindex(device); + g_return_if_fail(ifindex > 0); + props = nm_platform_link_get_lnk_macsec(nm_device_get_platform(device), ifindex, &plink); + + if (!props) { + _LOGW(LOGD_PLATFORM, "could not get macsec properties"); + return; + } + + g_object_freeze_notify((GObject *) device); + + if (priv->props.parent_ifindex != props->parent_ifindex) + nm_device_parent_set_ifindex(device, props->parent_ifindex); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED(sci, PROP_SCI); + CHECK_PROPERTY_CHANGED(cipher_suite, PROP_CIPHER_SUITE); + CHECK_PROPERTY_CHANGED(window, PROP_WINDOW); + CHECK_PROPERTY_CHANGED(icv_length, PROP_ICV_LENGTH); + CHECK_PROPERTY_CHANGED(encoding_sa, PROP_ENCODING_SA); + CHECK_PROPERTY_CHANGED(validation, PROP_VALIDATION); + CHECK_PROPERTY_CHANGED(encrypt, PROP_ENCRYPT); + CHECK_PROPERTY_CHANGED(protect, PROP_PROTECT); + CHECK_PROPERTY_CHANGED(include_sci, PROP_INCLUDE_SCI); + CHECK_PROPERTY_CHANGED(es, PROP_ES); + CHECK_PROPERTY_CHANGED(scb, PROP_SCB); + CHECK_PROPERTY_CHANGED(replay_protect, PROP_REPLAY_PROTECT); + + g_object_thaw_notify((GObject *) device); } static NMSupplicantConfig * -build_supplicant_config (NMDeviceMacsec *self, GError **error) +build_supplicant_config(NMDeviceMacsec *self, GError **error) { - gs_unref_object NMSupplicantConfig *config = NULL; - NMSettingMacsec *s_macsec; - NMSetting8021x *s_8021x; - NMConnection *connection; - const char *con_uuid; - guint32 mtu; + gs_unref_object NMSupplicantConfig *config = NULL; + NMSettingMacsec * s_macsec; + NMSetting8021x * s_8021x; + NMConnection * connection; + const char * con_uuid; + guint32 mtu; - connection = nm_device_get_applied_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection(NM_DEVICE(self)); - g_return_val_if_fail (connection, NULL); + g_return_val_if_fail(connection, NULL); - con_uuid = nm_connection_get_uuid (connection); - mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); + con_uuid = nm_connection_get_uuid(connection); + mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)), + nm_device_get_ifindex(NM_DEVICE(self))); - config = nm_supplicant_config_new (NM_SUPPL_CAP_MASK_NONE); + config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE); - s_macsec = nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_MACSEC); + s_macsec = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_MACSEC); - g_return_val_if_fail (s_macsec, NULL); + g_return_val_if_fail(s_macsec, NULL); - if (!nm_supplicant_config_add_setting_macsec (config, s_macsec, error)) { - g_prefix_error (error, "macsec-setting: "); - return NULL; - } + if (!nm_supplicant_config_add_setting_macsec(config, s_macsec, error)) { + g_prefix_error(error, "macsec-setting: "); + return NULL; + } - if (nm_setting_macsec_get_mode (s_macsec) == NM_SETTING_MACSEC_MODE_EAP) { - s_8021x = nm_connection_get_setting_802_1x (connection); - if (!nm_supplicant_config_add_setting_8021x (config, s_8021x, con_uuid, mtu, TRUE, error)) { - g_prefix_error (error, "802-1x-setting: "); - return NULL; - } - } + if (nm_setting_macsec_get_mode(s_macsec) == NM_SETTING_MACSEC_MODE_EAP) { + s_8021x = nm_connection_get_setting_802_1x(connection); + if (!nm_supplicant_config_add_setting_8021x(config, s_8021x, con_uuid, mtu, TRUE, error)) { + g_prefix_error(error, "802-1x-setting: "); + return NULL; + } + } - return g_steal_pointer (&config); + return g_steal_pointer(&config); } static void -supplicant_interface_release (NMDeviceMacsec *self) +supplicant_interface_release(NMDeviceMacsec *self) { - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); - nm_clear_pointer (&priv->supplicant.create_handle, nm_supplicant_manager_create_interface_cancel); + nm_clear_pointer(&priv->supplicant.create_handle, + nm_supplicant_manager_create_interface_cancel); - nm_clear_g_source (&priv->supplicant.lnk_timeout_id); - nm_clear_g_source (&priv->supplicant.con_timeout_id); - nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_state_id); + nm_clear_g_source(&priv->supplicant.lnk_timeout_id); + nm_clear_g_source(&priv->supplicant.con_timeout_id); + nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id); - if (priv->supplicant.iface) { - nm_supplicant_interface_disconnect (priv->supplicant.iface); - g_clear_object (&priv->supplicant.iface); - } + if (priv->supplicant.iface) { + nm_supplicant_interface_disconnect(priv->supplicant.iface); + g_clear_object(&priv->supplicant.iface); + } } static void -macsec_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *connection, - GError *error, - gpointer user_data) +macsec_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * connection, + GError * error, + gpointer user_data) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); - NMDevice *device = NM_DEVICE (self); - NMDeviceMacsecPrivate *priv; + NMDeviceMacsec * self = NM_DEVICE_MACSEC(user_data); + NMDevice * device = NM_DEVICE(self); + NMDeviceMacsecPrivate *priv; - g_return_if_fail (NM_IS_DEVICE_MACSEC (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + g_return_if_fail(NM_IS_DEVICE_MACSEC(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); - priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); + priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); - g_return_if_fail (priv->macsec_secrets_id == call_id); + g_return_if_fail(priv->macsec_secrets_id == call_id); - priv->macsec_secrets_id = NULL; + priv->macsec_secrets_id = NULL; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - 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); - g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); + 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); + g_return_if_fail(nm_act_request_get_settings_connection(req) == connection); - if (error) { - _LOGW (LOGD_ETHER, "%s", error->message); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } + if (error) { + _LOGW(LOGD_ETHER, "%s", error->message); + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -macsec_secrets_cancel (NMDeviceMacsec *self) +macsec_secrets_cancel(NMDeviceMacsec *self) { - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); - if (priv->macsec_secrets_id) - nm_act_request_cancel_secrets (NULL, priv->macsec_secrets_id); - nm_assert (!priv->macsec_secrets_id); + if (priv->macsec_secrets_id) + nm_act_request_cancel_secrets(NULL, priv->macsec_secrets_id); + nm_assert(!priv->macsec_secrets_id); } static void -macsec_secrets_get_secrets (NMDeviceMacsec *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags) +macsec_secrets_get_secrets(NMDeviceMacsec * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags) { - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - NMActRequest *req; - - macsec_secrets_cancel (self); - - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv->macsec_secrets_id = nm_act_request_get_secrets (req, - TRUE, - setting_name, - flags, - NULL, - macsec_secrets_cb, - self); - g_return_if_fail (priv->macsec_secrets_id); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + NMActRequest * req; + + macsec_secrets_cancel(self); + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + + priv->macsec_secrets_id = + nm_act_request_get_secrets(req, TRUE, setting_name, flags, NULL, macsec_secrets_cb, self); + g_return_if_fail(priv->macsec_secrets_id); } static gboolean -supplicant_lnk_timeout_cb (gpointer user_data) +supplicant_lnk_timeout_cb(gpointer user_data) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - NMDevice *dev = NM_DEVICE (self); - NMActRequest *req; - NMConnection *applied_connection; - const char *setting_name; + NMDeviceMacsec * self = NM_DEVICE_MACSEC(user_data); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + NMDevice * dev = NM_DEVICE(self); + NMActRequest * req; + NMConnection * applied_connection; + const char * setting_name; - priv->supplicant.lnk_timeout_id = 0; + priv->supplicant.lnk_timeout_id = 0; - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request(dev); - if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { - nm_device_state_changed (dev, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); - return G_SOURCE_REMOVE; - } + if (nm_device_get_state(dev) == NM_DEVICE_STATE_ACTIVATED) { + nm_device_state_changed(dev, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); + return G_SOURCE_REMOVE; + } - /* Disconnect event during initial authentication and credentials - * ARE checked - we are likely to have wrong key. Ask the user for - * another one. - */ - if (nm_device_get_state (dev) != NM_DEVICE_STATE_CONFIG) - goto time_out; + /* Disconnect event during initial authentication and credentials + * ARE checked - we are likely to have wrong key. Ask the user for + * another one. + */ + if (nm_device_get_state(dev) != NM_DEVICE_STATE_CONFIG) + goto time_out; - nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); + 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); - if (!setting_name) - goto time_out; + applied_connection = nm_act_request_get_applied_connection(req); + setting_name = nm_connection_need_secrets(applied_connection, NULL); + if (!setting_name) + goto time_out; - _LOGI (LOGD_DEVICE | LOGD_ETHER, - "Activation: disconnected during authentication, asking for new key."); - supplicant_interface_release (self); + _LOGI(LOGD_DEVICE | LOGD_ETHER, + "Activation: disconnected during authentication, asking for new key."); + supplicant_interface_release(self); - nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - macsec_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + nm_device_state_changed(dev, + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + macsec_secrets_get_secrets(self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; time_out: - _LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out."); - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + _LOGW(LOGD_DEVICE | LOGD_ETHER, "link timed out."); + nm_device_state_changed(dev, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -supplicant_iface_state_is_completed (NMDeviceMacsec *self, - NMSupplicantInterfaceState state) +supplicant_iface_state_is_completed(NMDeviceMacsec *self, NMSupplicantInterfaceState state) { - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_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); - - nm_device_bring_up (NM_DEVICE (self), TRUE, NULL); - - /* If this is the initial association during device activation, - * schedule the next activation stage. - */ - if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_CONFIG) { - _LOGI (LOGD_DEVICE, - "Activation: Stage 2 of 5 (Device Configure) successful."); - nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self)); - } - return; - } - - 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); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_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); + + nm_device_bring_up(NM_DEVICE(self), TRUE, NULL); + + /* If this is the initial association during device activation, + * schedule the next activation stage. + */ + if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_CONFIG) { + _LOGI(LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) successful."); + nm_device_activate_schedule_stage3_ip_config_start(NM_DEVICE(self)); + } + return; + } + + 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); } static void -supplicant_iface_assoc_cb (NMSupplicantInterface *iface, - GError *error, - gpointer user_data) +supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data) { - NMDeviceMacsec *self; - NMDeviceMacsecPrivate *priv; + NMDeviceMacsec * self; + NMDeviceMacsecPrivate *priv; - if (nm_utils_error_is_cancelled_or_disposing (error)) - return; + if (nm_utils_error_is_cancelled_or_disposing(error)) + return; - self = user_data; - priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); + self = user_data; + priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); - if (error) { - supplicant_interface_release (self); - nm_device_queue_state (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); - return; - } + if (error) { + supplicant_interface_release(self); + nm_device_queue_state(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); + return; + } - nm_assert (!priv->supplicant.lnk_timeout_id); - nm_assert (!priv->supplicant.is_associated); + 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)); + priv->supplicant.is_associated = TRUE; + supplicant_iface_state_is_completed(self, + nm_supplicant_interface_get_state(priv->supplicant.iface)); } static gboolean -supplicant_iface_start (NMDeviceMacsec *self) +supplicant_iface_start(NMDeviceMacsec *self) { - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - gs_unref_object NMSupplicantConfig *config = NULL; - gs_free_error GError *error = NULL; - - config = build_supplicant_config (self, &error); - if (!config) { - _LOGE (LOGD_DEVICE, - "Activation: 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; - } - - nm_supplicant_interface_disconnect (priv->supplicant.iface); - nm_supplicant_interface_assoc (priv->supplicant.iface, - config, - supplicant_iface_assoc_cb, - self); - return TRUE; + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + gs_unref_object NMSupplicantConfig *config = NULL; + gs_free_error GError *error = NULL; + + config = build_supplicant_config(self, &error); + if (!config) { + _LOGE(LOGD_DEVICE, "Activation: 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; + } + + nm_supplicant_interface_disconnect(priv->supplicant.iface); + nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self); + return TRUE; } static void -supplicant_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data) +supplicant_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - NMSupplicantInterfaceState new_state = new_state_i; - NMSupplicantInterfaceState old_state = old_state_i; - - _LOGI (LOGD_DEVICE, "supplicant interface state: %s -> %s", - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); - - if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { - supplicant_interface_release (self); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return; - } - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - if (!supplicant_iface_start (self)) - return; - } - - if (priv->supplicant.is_associated) - supplicant_iface_state_is_completed (self, new_state); + NMDeviceMacsec * self = NM_DEVICE_MACSEC(user_data); + NMDeviceMacsecPrivate * priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + NMSupplicantInterfaceState new_state = new_state_i; + NMSupplicantInterfaceState old_state = old_state_i; + + _LOGI(LOGD_DEVICE, + "supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string(old_state), + nm_supplicant_interface_state_to_string(new_state)); + + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + supplicant_interface_release(self); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return; + } + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + if (!supplicant_iface_start(self)) + return; + } + + if (priv->supplicant.is_associated) + supplicant_iface_state_is_completed(self, new_state); } static gboolean -handle_auth_or_fail (NMDeviceMacsec *self, - NMActRequest *req, - gboolean new_secrets) +handle_auth_or_fail(NMDeviceMacsec *self, NMActRequest *req, gboolean new_secrets) { - const char *setting_name; - NMConnection *applied_connection; - - if (!nm_device_auth_retries_try_next (NM_DEVICE (self))) - return FALSE; - - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - - 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); - if (!setting_name) { - _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - return FALSE; - } - - macsec_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)); - return TRUE; + const char * setting_name; + NMConnection *applied_connection; + + if (!nm_device_auth_retries_try_next(NM_DEVICE(self))) + return FALSE; + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); + + 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); + if (!setting_name) { + _LOGI(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + return FALSE; + } + + macsec_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)); + return TRUE; } static gboolean -supplicant_connection_timeout_cb (gpointer user_data) +supplicant_connection_timeout_cb(gpointer user_data) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (user_data); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMActRequest *req; - NMSettingsConnection *connection; - guint64 timestamp = 0; - gboolean new_secrets = TRUE; - - priv->supplicant.con_timeout_id = 0; - - /* 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. */ - _LOGW (LOGD_DEVICE, - "Activation: (macsec) association took too long."); - - supplicant_interface_release (self); - - req = nm_device_get_act_request (device); - connection = nm_act_request_get_settings_connection (req); - g_return_val_if_fail (connection, G_SOURCE_REMOVE); - - /* 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. */ - if (nm_settings_connection_get_timestamp (connection, ×tamp)) - new_secrets = !timestamp; - - if (!handle_auth_or_fail (self, req, new_secrets)) { - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - return G_SOURCE_REMOVE; - } - - _LOGW (LOGD_DEVICE, "Activation: (macsec) asking for new secrets"); - - if ( !priv->supplicant.lnk_timeout_id - && priv->supplicant.iface) { - NMSupplicantInterfaceState state; - - state = nm_supplicant_interface_get_state (priv->supplicant.iface); - if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED - && nm_supplicant_interface_state_is_operational (state)) - priv->supplicant.lnk_timeout_id = g_timeout_add_seconds (SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self); - } - - return G_SOURCE_REMOVE; + NMDeviceMacsec * self = NM_DEVICE_MACSEC(user_data); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMActRequest * req; + NMSettingsConnection * connection; + guint64 timestamp = 0; + gboolean new_secrets = TRUE; + + priv->supplicant.con_timeout_id = 0; + + /* 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. */ + _LOGW(LOGD_DEVICE, "Activation: (macsec) association took too long."); + + supplicant_interface_release(self); + + req = nm_device_get_act_request(device); + connection = nm_act_request_get_settings_connection(req); + g_return_val_if_fail(connection, G_SOURCE_REMOVE); + + /* 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. */ + if (nm_settings_connection_get_timestamp(connection, ×tamp)) + new_secrets = !timestamp; + + if (!handle_auth_or_fail(self, req, new_secrets)) { + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return G_SOURCE_REMOVE; + } + + _LOGW(LOGD_DEVICE, "Activation: (macsec) asking for new secrets"); + + if (!priv->supplicant.lnk_timeout_id && priv->supplicant.iface) { + NMSupplicantInterfaceState state; + + state = nm_supplicant_interface_get_state(priv->supplicant.iface); + if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED + && nm_supplicant_interface_state_is_operational(state)) + priv->supplicant.lnk_timeout_id = + g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self); + } + + return G_SOURCE_REMOVE; } static void -supplicant_interface_create_cb (NMSupplicantManager *supplicant_manager, - NMSupplMgrCreateIfaceHandle *handle, - NMSupplicantInterface *iface, - GError *error, - gpointer user_data) +supplicant_interface_create_cb(NMSupplicantManager * supplicant_manager, + NMSupplMgrCreateIfaceHandle *handle, + NMSupplicantInterface * iface, + GError * error, + gpointer user_data) { - NMDeviceMacsec *self; - NMDeviceMacsecPrivate *priv; - guint timeout; - - if (nm_utils_error_is_cancelled (error)) - return; - - self = user_data; - priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - - nm_assert (priv->supplicant.create_handle == handle); - - priv->supplicant.create_handle = NULL; - - if (error) { - _LOGE (LOGD_DEVICE, - "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; - } - - priv->supplicant.iface = g_object_ref (iface); - priv->supplicant.is_associated = FALSE; - - priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface, - NM_SUPPLICANT_INTERFACE_STATE, - G_CALLBACK (supplicant_iface_state_cb), - self); - - timeout = nm_device_get_supplicant_timeout (NM_DEVICE (self)); - priv->supplicant.con_timeout_id = g_timeout_add_seconds (timeout, - supplicant_connection_timeout_cb, - self); - - if (nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (iface))) - supplicant_iface_start (self); + NMDeviceMacsec * self; + NMDeviceMacsecPrivate *priv; + guint timeout; + + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + + nm_assert(priv->supplicant.create_handle == handle); + + priv->supplicant.create_handle = NULL; + + if (error) { + _LOGE(LOGD_DEVICE, "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; + } + + priv->supplicant.iface = g_object_ref(iface); + priv->supplicant.is_associated = FALSE; + + priv->supplicant.iface_state_id = g_signal_connect(priv->supplicant.iface, + NM_SUPPLICANT_INTERFACE_STATE, + G_CALLBACK(supplicant_iface_state_cb), + self); + + timeout = nm_device_get_supplicant_timeout(NM_DEVICE(self)); + priv->supplicant.con_timeout_id = + g_timeout_add_seconds(timeout, supplicant_connection_timeout_cb, self); + + if (nm_supplicant_interface_state_is_operational(nm_supplicant_interface_get_state(iface))) + supplicant_iface_start(self); } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (device); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - NMConnection *connection; - NMDevice *parent; - const char *setting_name; - int ifindex; - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - if (!priv->supplicant.mgr) - priv->supplicant.mgr = g_object_ref (nm_supplicant_manager_get ()); - - /* If we need secrets, get them */ - setting_name = nm_connection_need_secrets (connection, NULL); - if (setting_name) { - NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self)); - - _LOGI (LOGD_DEVICE, - "Activation: connection '%s' has security, but secrets are required.", - nm_connection_get_id (connection)); - - if (!handle_auth_or_fail (self, req, FALSE)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - _LOGI (LOGD_DEVICE | LOGD_ETHER, - "Activation: connection '%s' requires no security. No secrets needed.", - nm_connection_get_id (connection)); - - supplicant_interface_release (self); - - parent = nm_device_parent_get_device (NM_DEVICE (self)); - g_return_val_if_fail (parent, NM_ACT_STAGE_RETURN_FAILURE); - ifindex = nm_device_get_ifindex (parent); - g_return_val_if_fail (ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE); - - priv->supplicant.create_handle = nm_supplicant_manager_create_interface (priv->supplicant.mgr, - ifindex, - NM_SUPPLICANT_DRIVER_MACSEC, - supplicant_interface_create_cb, - self); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDeviceMacsec * self = NM_DEVICE_MACSEC(device); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + NMConnection * connection; + NMDevice * parent; + const char * setting_name; + int ifindex; + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + if (!priv->supplicant.mgr) + priv->supplicant.mgr = g_object_ref(nm_supplicant_manager_get()); + + /* If we need secrets, get them */ + setting_name = nm_connection_need_secrets(connection, NULL); + if (setting_name) { + NMActRequest *req = nm_device_get_act_request(NM_DEVICE(self)); + + _LOGI(LOGD_DEVICE, + "Activation: connection '%s' has security, but secrets are required.", + nm_connection_get_id(connection)); + + if (!handle_auth_or_fail(self, req, FALSE)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + _LOGI(LOGD_DEVICE | LOGD_ETHER, + "Activation: connection '%s' requires no security. No secrets needed.", + nm_connection_get_id(connection)); + + supplicant_interface_release(self); + + parent = nm_device_parent_get_device(NM_DEVICE(self)); + g_return_val_if_fail(parent, NM_ACT_STAGE_RETURN_FAILURE); + ifindex = nm_device_get_ifindex(parent); + g_return_val_if_fail(ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE); + + priv->supplicant.create_handle = + nm_supplicant_manager_create_interface(priv->supplicant.mgr, + ifindex, + NM_SUPPLICANT_DRIVER_MACSEC, + supplicant_interface_create_cb, + self); + return NM_ACT_STAGE_RETURN_POSTPONE; } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (device); + NMDeviceMacsec *self = NM_DEVICE_MACSEC(device); - supplicant_interface_release (self); + supplicant_interface_release(self); } /******************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - /* We assume MACsec interfaces always support carrier detect */ - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + /* We assume MACsec interfaces always support carrier detect */ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } /******************************************************************/ static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - if (!nm_device_parent_get_device (device)) - return FALSE; - return NM_DEVICE_CLASS (nm_device_macsec_parent_class)->is_available (device, flags); + if (!nm_device_parent_get_device(device)) + return FALSE; + return NM_DEVICE_CLASS(nm_device_macsec_parent_class)->is_available(device, flags); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMSettingMacsec *s_macsec; - NMPlatformLnkMacsec lnk = { }; - int parent_ifindex; - const char *hw_addr; - union { - struct { - guint8 mac[6]; - guint16 port; - } s; - guint64 u; - } sci; - int r; - - s_macsec = nm_connection_get_setting_macsec (connection); - g_assert (s_macsec); - - if (!parent) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "MACsec devices can not be created without a parent interface"); - return FALSE; - } - - lnk.encrypt = nm_setting_macsec_get_encrypt (s_macsec); - - hw_addr = nm_device_get_hw_address (parent); - if (!hw_addr) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "can't read parent MAC"); - return FALSE; - } - - nm_utils_hwaddr_aton (hw_addr, sci.s.mac, ETH_ALEN); - sci.s.port = htons (nm_setting_macsec_get_port (s_macsec)); - lnk.sci = be64toh (sci.u); - lnk.validation = nm_setting_macsec_get_validation (s_macsec); - lnk.include_sci = nm_setting_macsec_get_send_sci (s_macsec); - - parent_ifindex = nm_device_get_ifindex (parent); - g_warn_if_fail (parent_ifindex > 0); - - r = nm_platform_link_macsec_add (nm_device_get_platform (device), iface, parent_ifindex, &lnk, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create macsec interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - nm_device_parent_set_ifindex (device, parent_ifindex); - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMSettingMacsec * s_macsec; + NMPlatformLnkMacsec lnk = {}; + int parent_ifindex; + const char * hw_addr; + union { + struct { + guint8 mac[6]; + guint16 port; + } s; + guint64 u; + } sci; + int r; + + s_macsec = nm_connection_get_setting_macsec(connection); + g_assert(s_macsec); + + if (!parent) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "MACsec devices can not be created without a parent interface"); + return FALSE; + } + + lnk.encrypt = nm_setting_macsec_get_encrypt(s_macsec); + + hw_addr = nm_device_get_hw_address(parent); + if (!hw_addr) { + g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "can't read parent MAC"); + return FALSE; + } + + nm_utils_hwaddr_aton(hw_addr, sci.s.mac, ETH_ALEN); + sci.s.port = htons(nm_setting_macsec_get_port(s_macsec)); + lnk.sci = be64toh(sci.u); + lnk.validation = nm_setting_macsec_get_validation(s_macsec); + lnk.include_sci = nm_setting_macsec_get_send_sci(s_macsec); + + parent_ifindex = nm_device_get_ifindex(parent); + g_warn_if_fail(parent_ifindex > 0); + + r = nm_platform_link_macsec_add(nm_device_get_platform(device), + iface, + parent_ifindex, + &lnk, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create macsec interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + nm_device_parent_set_ifindex(device, parent_ifindex); + + return TRUE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_macsec_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_macsec_parent_class)->link_changed(device, pllink); + update_properties(device); } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - if (new_state > NM_DEVICE_STATE_ACTIVATED) - macsec_secrets_cancel (NM_DEVICE_MACSEC (device)); + if (new_state > NM_DEVICE_STATE_ACTIVATED) + macsec_secrets_cancel(NM_DEVICE_MACSEC(device)); } /******************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (object); - NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_SCI: - g_value_set_uint64 (value, priv->props.sci); - break; - case PROP_CIPHER_SUITE: - g_value_set_uint64 (value, priv->props.cipher_suite); - break; - case PROP_ICV_LENGTH: - g_value_set_uchar (value, priv->props.icv_length); - break; - case PROP_WINDOW: - g_value_set_uint (value, priv->props.window); - break; - case PROP_ENCODING_SA: - g_value_set_uchar (value, priv->props.encoding_sa); - break; - case PROP_ENCRYPT: - g_value_set_boolean (value, priv->props.encrypt); - break; - case PROP_PROTECT: - g_value_set_boolean (value, priv->props.protect); - break; - case PROP_INCLUDE_SCI: - g_value_set_boolean (value, priv->props.include_sci); - break; - case PROP_ES: - g_value_set_boolean (value, priv->props.es); - break; - case PROP_SCB: - g_value_set_boolean (value, priv->props.scb); - break; - case PROP_REPLAY_PROTECT: - g_value_set_boolean (value, priv->props.replay_protect); - break; - case PROP_VALIDATION: - g_value_set_string (value, - validation_mode_to_string (priv->props.validation)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceMacsec * self = NM_DEVICE_MACSEC(object); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_SCI: + g_value_set_uint64(value, priv->props.sci); + break; + case PROP_CIPHER_SUITE: + g_value_set_uint64(value, priv->props.cipher_suite); + break; + case PROP_ICV_LENGTH: + g_value_set_uchar(value, priv->props.icv_length); + break; + case PROP_WINDOW: + g_value_set_uint(value, priv->props.window); + break; + case PROP_ENCODING_SA: + g_value_set_uchar(value, priv->props.encoding_sa); + break; + case PROP_ENCRYPT: + g_value_set_boolean(value, priv->props.encrypt); + break; + case PROP_PROTECT: + g_value_set_boolean(value, priv->props.protect); + break; + case PROP_INCLUDE_SCI: + g_value_set_boolean(value, priv->props.include_sci); + break; + case PROP_ES: + g_value_set_boolean(value, priv->props.es); + break; + case PROP_SCB: + g_value_set_boolean(value, priv->props.scb); + break; + case PROP_REPLAY_PROTECT: + g_value_set_boolean(value, priv->props.replay_protect); + break; + case PROP_VALIDATION: + g_value_set_string(value, validation_mode_to_string(priv->props.validation)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -nm_device_macsec_init (NMDeviceMacsec *self) -{ -} +nm_device_macsec_init(NMDeviceMacsec *self) +{} static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceMacsec *self = NM_DEVICE_MACSEC (object); + NMDeviceMacsec *self = NM_DEVICE_MACSEC(object); - macsec_secrets_cancel (self); - supplicant_interface_release (self); + macsec_secrets_cancel(self); + supplicant_interface_release(self); - G_OBJECT_CLASS (nm_device_macsec_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_macsec_parent_class)->dispose(object); - nm_assert (NM_DEVICE_MACSEC_GET_PRIVATE (self)->parent_state_id == 0); - nm_assert (NM_DEVICE_MACSEC_GET_PRIVATE (self)->parent_mtu_id == 0); + nm_assert(NM_DEVICE_MACSEC_GET_PRIVATE(self)->parent_state_id == 0); + nm_assert(NM_DEVICE_MACSEC_GET_PRIVATE(self)->parent_mtu_id == 0); } static const NMDBusInterfaceInfoExtended interface_info_device_macsec = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_MACSEC, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Sci", "t", NM_DEVICE_MACSEC_SCI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IcvLength", "y", NM_DEVICE_MACSEC_ICV_LENGTH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CipherSuite", "t", NM_DEVICE_MACSEC_CIPHER_SUITE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Window", "u", NM_DEVICE_MACSEC_WINDOW), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("EncodingSa", "y", NM_DEVICE_MACSEC_ENCODING_SA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Validation", "s", NM_DEVICE_MACSEC_VALIDATION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Encrypt", "b", NM_DEVICE_MACSEC_ENCRYPT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Protect", "b", NM_DEVICE_MACSEC_PROTECT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IncludeSci", "b", NM_DEVICE_MACSEC_INCLUDE_SCI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Es", "b", NM_DEVICE_MACSEC_ES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Scb", "b", NM_DEVICE_MACSEC_SCB), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ReplayProtect", "b", NM_DEVICE_MACSEC_REPLAY_PROTECT), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_MACSEC, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Sci", "t", NM_DEVICE_MACSEC_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IcvLength", + "y", + NM_DEVICE_MACSEC_ICV_LENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CipherSuite", + "t", + NM_DEVICE_MACSEC_CIPHER_SUITE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Window", + "u", + NM_DEVICE_MACSEC_WINDOW), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("EncodingSa", + "y", + NM_DEVICE_MACSEC_ENCODING_SA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Validation", + "s", + NM_DEVICE_MACSEC_VALIDATION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Encrypt", + "b", + NM_DEVICE_MACSEC_ENCRYPT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Protect", + "b", + NM_DEVICE_MACSEC_PROTECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IncludeSci", + "b", + NM_DEVICE_MACSEC_INCLUDE_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Es", "b", NM_DEVICE_MACSEC_ES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Scb", "b", NM_DEVICE_MACSEC_SCB), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ReplayProtect", + "b", + NM_DEVICE_MACSEC_REPLAY_PROTECT), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_macsec_class_init (NMDeviceMacsecClass *klass) +nm_device_macsec_class_init(NMDeviceMacsecClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - object_class->dispose = dispose; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macsec); - - device_class->connection_type_supported = NM_SETTING_MACSEC_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_MACSEC_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACSEC); - device_class->mtu_parent_delta = 32; - - device_class->act_stage2_config = act_stage2_config; - device_class->create_and_realize = create_and_realize; - device_class->deactivate = deactivate; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->link_changed = link_changed; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - device_class->state_changed = device_state_changed; - device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; - - obj_properties[PROP_SCI] = - g_param_spec_uint64 (NM_DEVICE_MACSEC_SCI, "", "", - 0, G_MAXUINT64, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_CIPHER_SUITE] = - g_param_spec_uint64 (NM_DEVICE_MACSEC_CIPHER_SUITE, "", "", - 0, G_MAXUINT64, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ICV_LENGTH] = - g_param_spec_uchar (NM_DEVICE_MACSEC_ICV_LENGTH, "", "", - 0, G_MAXUINT8, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_WINDOW] = - g_param_spec_uint (NM_DEVICE_MACSEC_WINDOW, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ENCODING_SA] = - g_param_spec_uchar (NM_DEVICE_MACSEC_ENCODING_SA, "", "", - 0, 3, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_VALIDATION] = - g_param_spec_string (NM_DEVICE_MACSEC_VALIDATION, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ENCRYPT] = - g_param_spec_boolean (NM_DEVICE_MACSEC_ENCRYPT, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PROTECT] = - g_param_spec_boolean (NM_DEVICE_MACSEC_PROTECT, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_INCLUDE_SCI] = - g_param_spec_boolean (NM_DEVICE_MACSEC_INCLUDE_SCI, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ES] = - g_param_spec_boolean (NM_DEVICE_MACSEC_ES, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_SCB] = - g_param_spec_boolean (NM_DEVICE_MACSEC_SCB, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_REPLAY_PROTECT] = - g_param_spec_boolean (NM_DEVICE_MACSEC_REPLAY_PROTECT, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->dispose = dispose; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_macsec); + + device_class->connection_type_supported = NM_SETTING_MACSEC_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_MACSEC_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_MACSEC); + device_class->mtu_parent_delta = 32; + + device_class->act_stage2_config = act_stage2_config; + device_class->create_and_realize = create_and_realize; + device_class->deactivate = deactivate; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->link_changed = link_changed; + device_class->is_available = is_available; + device_class->parent_changed_notify = parent_changed_notify; + device_class->state_changed = device_state_changed; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; + + obj_properties[PROP_SCI] = g_param_spec_uint64(NM_DEVICE_MACSEC_SCI, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CIPHER_SUITE] = + g_param_spec_uint64(NM_DEVICE_MACSEC_CIPHER_SUITE, + "", + "", + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ICV_LENGTH] = g_param_spec_uchar(NM_DEVICE_MACSEC_ICV_LENGTH, + "", + "", + 0, + G_MAXUINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_WINDOW] = g_param_spec_uint(NM_DEVICE_MACSEC_WINDOW, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ENCODING_SA] = + g_param_spec_uchar(NM_DEVICE_MACSEC_ENCODING_SA, + "", + "", + 0, + 3, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_VALIDATION] = + g_param_spec_string(NM_DEVICE_MACSEC_VALIDATION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ENCRYPT] = g_param_spec_boolean(NM_DEVICE_MACSEC_ENCRYPT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PROTECT] = g_param_spec_boolean(NM_DEVICE_MACSEC_PROTECT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_INCLUDE_SCI] = + g_param_spec_boolean(NM_DEVICE_MACSEC_INCLUDE_SCI, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ES] = g_param_spec_boolean(NM_DEVICE_MACSEC_ES, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_SCB] = g_param_spec_boolean(NM_DEVICE_MACSEC_SCB, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_REPLAY_PROTECT] = + g_param_spec_boolean(NM_DEVICE_MACSEC_REPLAY_PROTECT, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*************************************************************/ -#define NM_TYPE_MACSEC_DEVICE_FACTORY (nm_macsec_device_factory_get_type ()) -#define NM_MACSEC_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MACSEC_DEVICE_FACTORY, NMMacsecDeviceFactory)) +#define NM_TYPE_MACSEC_DEVICE_FACTORY (nm_macsec_device_factory_get_type()) +#define NM_MACSEC_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MACSEC_DEVICE_FACTORY, NMMacsecDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACSEC, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Macsec", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MACSEC, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_MACSEC, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_MACSEC, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Macsec", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_MACSEC, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_MACSEC, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingMacsec *s_macsec; - NMSettingWired *s_wired; - const char *parent = NULL; + NMSettingMacsec *s_macsec; + NMSettingWired * s_wired; + const char * parent = NULL; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); - s_macsec = nm_connection_get_setting_macsec (connection); - g_assert (s_macsec); + s_macsec = nm_connection_get_setting_macsec(connection); + g_assert(s_macsec); - parent = nm_setting_macsec_get_parent (s_macsec); - if (parent) - return parent; + parent = nm_setting_macsec_get_parent(s_macsec); + if (parent) + return parent; - /* Try the hardware address from the MACsec connection's hardware setting */ - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) - return nm_setting_wired_get_mac_address (s_wired); + /* Try the hardware address from the MACsec connection's hardware setting */ + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + return nm_setting_wired_get_mac_address(s_wired); - return NULL; + return NULL; } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - NMSettingMacsec *s_macsec; - const char *ifname; + NMSettingMacsec *s_macsec; + const char * ifname; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); - s_macsec = nm_connection_get_setting_macsec (connection); - g_assert (s_macsec); + s_macsec = nm_connection_get_setting_macsec(connection); + g_assert(s_macsec); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); - return g_strdup (ifname); + ifname = nm_connection_get_interface_name(connection); + return g_strdup(ifname); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (MACSEC, Macsec, macsec, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_MACSEC) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_MACSEC_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -) +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + MACSEC, + Macsec, + macsec, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_MACSEC) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_MACSEC_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;) diff --git a/src/devices/nm-device-macsec.h b/src/devices/nm-device-macsec.h index 38a7dbae..9a2f230b 100644 --- a/src/devices/nm-device-macsec.h +++ b/src/devices/nm-device-macsec.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -8,29 +8,32 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_MACSEC (nm_device_macsec_get_type ()) -#define NM_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsec)) -#define NM_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) -#define NM_IS_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACSEC)) -#define NM_IS_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACSEC)) -#define NM_DEVICE_MACSEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) +#define NM_TYPE_DEVICE_MACSEC (nm_device_macsec_get_type()) +#define NM_DEVICE_MACSEC(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsec)) +#define NM_DEVICE_MACSEC_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) +#define NM_IS_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MACSEC)) +#define NM_IS_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MACSEC)) +#define NM_DEVICE_MACSEC_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass)) -#define NM_DEVICE_MACSEC_SCI "sci" -#define NM_DEVICE_MACSEC_CIPHER_SUITE "cipher-suite" -#define NM_DEVICE_MACSEC_ICV_LENGTH "icv-length" -#define NM_DEVICE_MACSEC_WINDOW "window" -#define NM_DEVICE_MACSEC_ENCODING_SA "encoding-sa" -#define NM_DEVICE_MACSEC_VALIDATION "validation" -#define NM_DEVICE_MACSEC_ENCRYPT "encrypt" -#define NM_DEVICE_MACSEC_PROTECT "protect" -#define NM_DEVICE_MACSEC_INCLUDE_SCI "include-sci" -#define NM_DEVICE_MACSEC_ES "es" -#define NM_DEVICE_MACSEC_SCB "scb" -#define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect" +#define NM_DEVICE_MACSEC_SCI "sci" +#define NM_DEVICE_MACSEC_CIPHER_SUITE "cipher-suite" +#define NM_DEVICE_MACSEC_ICV_LENGTH "icv-length" +#define NM_DEVICE_MACSEC_WINDOW "window" +#define NM_DEVICE_MACSEC_ENCODING_SA "encoding-sa" +#define NM_DEVICE_MACSEC_VALIDATION "validation" +#define NM_DEVICE_MACSEC_ENCRYPT "encrypt" +#define NM_DEVICE_MACSEC_PROTECT "protect" +#define NM_DEVICE_MACSEC_INCLUDE_SCI "include-sci" +#define NM_DEVICE_MACSEC_ES "es" +#define NM_DEVICE_MACSEC_SCB "scb" +#define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect" -typedef struct _NMDeviceMacsec NMDeviceMacsec; +typedef struct _NMDeviceMacsec NMDeviceMacsec; typedef struct _NMDeviceMacsecClass NMDeviceMacsecClass; -GType nm_device_macsec_get_type (void); +GType nm_device_macsec_get_type(void); #endif /* __NM_DEVICE_MACSEC_H__ */ diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index 3435df1b..d9e71c8c 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - 2015 Red Hat, Inc. */ @@ -26,606 +26,640 @@ _LOG_DECLARE_SELF(NMDeviceMacvlan); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceMacvlan, - PROP_MODE, - PROP_NO_PROMISC, - PROP_TAP, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceMacvlan, PROP_MODE, PROP_NO_PROMISC, PROP_TAP, ); typedef struct { - gulong parent_state_id; - gulong parent_mtu_id; - NMPlatformLnkMacvlan props; + gulong parent_state_id; + gulong parent_mtu_id; + NMPlatformLnkMacvlan props; } NMDeviceMacvlanPrivate; struct _NMDeviceMacvlan { - NMDevice parent; - NMDeviceMacvlanPrivate _priv; + NMDevice parent; + NMDeviceMacvlanPrivate _priv; }; struct _NMDeviceMacvlanClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE) -#define NM_DEVICE_MACVLAN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceMacvlan, NM_IS_DEVICE_MACVLAN, NMDevice) +#define NM_DEVICE_MACVLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceMacvlan, NM_IS_DEVICE_MACVLAN, NMDevice) /*****************************************************************************/ static int modes[][2] = { - { NM_SETTING_MACVLAN_MODE_VEPA, MACVLAN_MODE_VEPA }, - { NM_SETTING_MACVLAN_MODE_BRIDGE, MACVLAN_MODE_BRIDGE }, - { NM_SETTING_MACVLAN_MODE_PRIVATE, MACVLAN_MODE_PRIVATE }, - { NM_SETTING_MACVLAN_MODE_PASSTHRU, MACVLAN_MODE_PASSTHRU }, + {NM_SETTING_MACVLAN_MODE_VEPA, MACVLAN_MODE_VEPA}, + {NM_SETTING_MACVLAN_MODE_BRIDGE, MACVLAN_MODE_BRIDGE}, + {NM_SETTING_MACVLAN_MODE_PRIVATE, MACVLAN_MODE_PRIVATE}, + {NM_SETTING_MACVLAN_MODE_PASSTHRU, MACVLAN_MODE_PASSTHRU}, }; static int -setting_mode_to_platform (int mode) +setting_mode_to_platform(int mode) { - guint i; + guint i; - for (i = 0; i < G_N_ELEMENTS (modes); i++) { - if (modes[i][0] == mode) - return modes[i][1]; - } + for (i = 0; i < G_N_ELEMENTS(modes); i++) { + if (modes[i][0] == mode) + return modes[i][1]; + } - return 0; + return 0; } static int -platform_mode_to_setting (int mode) +platform_mode_to_setting(int mode) { - guint i; + guint i; - for (i = 0; i < G_N_ELEMENTS (modes); i++) { - if (modes[i][1] == mode) - return modes[i][0]; - } + for (i = 0; i < G_N_ELEMENTS(modes); i++) { + if (modes[i][1] == mode) + return modes[i][0]; + } - return 0; + return 0; } static const char * -platform_mode_to_string (guint mode) +platform_mode_to_string(guint mode) { - switch (mode) { - case MACVLAN_MODE_PRIVATE: - return "private"; - case MACVLAN_MODE_VEPA: - return "vepa"; - case MACVLAN_MODE_BRIDGE: - return "bridge"; - case MACVLAN_MODE_PASSTHRU: - return "passthru"; - default: - return "unknown"; - } + switch (mode) { + case MACVLAN_MODE_PRIVATE: + return "private"; + case MACVLAN_MODE_VEPA: + return "vepa"; + case MACVLAN_MODE_BRIDGE: + return "bridge"; + case MACVLAN_MODE_PASSTHRU: + return "passthru"; + default: + return "unknown"; + } } /*****************************************************************************/ static void -parent_state_changed (NMDevice *parent, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) +parent_state_changed(NMDevice * parent, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) { - NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (user_data); + NMDeviceMacvlan *self = NM_DEVICE_MACVLAN(user_data); - /* We'll react to our own carrier state notifications. Ignore the parent's. */ - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CARRIER) - return; + /* We'll react to our own carrier state notifications. Ignore the parent's. */ + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_CARRIER) + return; - nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); + nm_device_set_unmanaged_by_flags(NM_DEVICE(self), + NM_UNMANAGED_PARENT, + !nm_device_get_managed(parent, FALSE), + reason); } static void -parent_mtu_maybe_changed (NMDevice *parent, - GParamSpec *pspec, - gpointer user_data) +parent_mtu_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_data) { - /* the MTU of a macvlan/macvtap device is limited by the parent's MTU. - * - * When the parent's MTU changes, try to re-set the MTU. */ - nm_device_commit_mtu (user_data); + /* the MTU of a macvlan/macvtap device is limited by the parent's MTU. + * + * When the parent's MTU changes, try to re-set the MTU. */ + nm_device_commit_mtu(user_data); } static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *device, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self); - - NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->parent_changed_notify (device, old_ifindex, old_parent, new_ifindex, new_parent); - - /* note that @self doesn't have to clear @parent_state_id on dispose, - * because NMDevice's dispose() will unset the parent, which in turn calls - * parent_changed_notify(). */ - nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); - nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id); - - if (new_parent) { - priv->parent_state_id = g_signal_connect (new_parent, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (parent_state_changed), - device); - priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU, - G_CALLBACK (parent_mtu_maybe_changed), device); - - /* Set parent-dependent unmanaged flag */ - nm_device_set_unmanaged_by_flags (device, - NM_UNMANAGED_PARENT, - !nm_device_get_managed (new_parent, FALSE), - NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); - } - - if (new_ifindex > 0) { - /* Recheck availability now that the parent has changed */ - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_PARENT_CHANGED, - NM_DEVICE_STATE_REASON_PARENT_CHANGED); - } + NMDeviceMacvlan * self = NM_DEVICE_MACVLAN(device); + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(self); + + NM_DEVICE_CLASS(nm_device_macvlan_parent_class) + ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent); + + /* note that @self doesn't have to clear @parent_state_id on dispose, + * because NMDevice's dispose() will unset the parent, which in turn calls + * parent_changed_notify(). */ + nm_clear_g_signal_handler(old_parent, &priv->parent_state_id); + nm_clear_g_signal_handler(old_parent, &priv->parent_mtu_id); + + if (new_parent) { + priv->parent_state_id = g_signal_connect(new_parent, + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(parent_state_changed), + device); + priv->parent_mtu_id = g_signal_connect(new_parent, + "notify::" NM_DEVICE_MTU, + G_CALLBACK(parent_mtu_maybe_changed), + device); + + /* Set parent-dependent unmanaged flag */ + nm_device_set_unmanaged_by_flags(device, + NM_UNMANAGED_PARENT, + !nm_device_get_managed(new_parent, FALSE), + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); + } + + if (new_ifindex > 0) { + /* Recheck availability now that the parent has changed */ + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_PARENT_CHANGED, + NM_DEVICE_STATE_REASON_PARENT_CHANGED); + } } static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (self); - GObject *object = G_OBJECT (device); - const NMPlatformLnkMacvlan *props; - const NMPlatformLink *plink; - - if (priv->props.tap) - props = nm_platform_link_get_lnk_macvtap (nm_device_get_platform (device), nm_device_get_ifindex (device), &plink); - else - props = nm_platform_link_get_lnk_macvlan (nm_device_get_platform (device), nm_device_get_ifindex (device), &plink); - - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get %s properties", priv->props.tap ? "macvtap" : "macvlan"); - return; - } - - g_object_freeze_notify (object); - - nm_device_parent_set_ifindex (device, plink->parent); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->props.field != props->field) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED (mode, PROP_MODE); - CHECK_PROPERTY_CHANGED (no_promisc, PROP_NO_PROMISC); - - g_object_thaw_notify (object); + NMDeviceMacvlan * self = NM_DEVICE_MACVLAN(device); + NMDeviceMacvlanPrivate * priv = NM_DEVICE_MACVLAN_GET_PRIVATE(self); + GObject * object = G_OBJECT(device); + const NMPlatformLnkMacvlan *props; + const NMPlatformLink * plink; + + if (priv->props.tap) + props = nm_platform_link_get_lnk_macvtap(nm_device_get_platform(device), + nm_device_get_ifindex(device), + &plink); + else + props = nm_platform_link_get_lnk_macvlan(nm_device_get_platform(device), + nm_device_get_ifindex(device), + &plink); + + if (!props) { + _LOGW(LOGD_PLATFORM, + "could not get %s properties", + priv->props.tap ? "macvtap" : "macvlan"); + return; + } + + g_object_freeze_notify(object); + + nm_device_parent_set_ifindex(device, plink->parent); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED(mode, PROP_MODE); + CHECK_PROPERTY_CHANGED(no_promisc, PROP_NO_PROMISC); + + g_object_thaw_notify(object); } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_macvlan_parent_class)->link_changed(device, pllink); + update_properties(device); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMSettingMacvlan *s_macvlan; - NMPlatformLnkMacvlan lnk = { }; - int parent_ifindex; - int r; - - s_macvlan = nm_connection_get_setting_macvlan (connection); - g_return_val_if_fail (s_macvlan, FALSE); - - parent_ifindex = parent ? nm_device_get_ifindex (parent) : 0; - - if (parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "MACVLAN devices can not be created without a parent interface"); - g_return_val_if_fail (!parent, FALSE); - return FALSE; - } - - lnk.mode = setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)); - if (!lnk.mode) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "unsupported MACVLAN mode %u in connection %s", - nm_setting_macvlan_get_mode (s_macvlan), - nm_connection_get_uuid (connection)); - return FALSE; - } - lnk.no_promisc = !nm_setting_macvlan_get_promiscuous (s_macvlan); - lnk.tap = nm_setting_macvlan_get_tap (s_macvlan); - - r = nm_platform_link_macvlan_add (nm_device_get_platform (device), iface, parent_ifindex, &lnk, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create %s interface '%s' for '%s': %s", - lnk.tap ? "macvtap" : "macvlan", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMSettingMacvlan * s_macvlan; + NMPlatformLnkMacvlan lnk = {}; + int parent_ifindex; + int r; + + s_macvlan = nm_connection_get_setting_macvlan(connection); + g_return_val_if_fail(s_macvlan, FALSE); + + parent_ifindex = parent ? nm_device_get_ifindex(parent) : 0; + + if (parent_ifindex <= 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "MACVLAN devices can not be created without a parent interface"); + g_return_val_if_fail(!parent, FALSE); + return FALSE; + } + + lnk.mode = setting_mode_to_platform(nm_setting_macvlan_get_mode(s_macvlan)); + if (!lnk.mode) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "unsupported MACVLAN mode %u in connection %s", + nm_setting_macvlan_get_mode(s_macvlan), + nm_connection_get_uuid(connection)); + return FALSE; + } + lnk.no_promisc = !nm_setting_macvlan_get_promiscuous(s_macvlan); + lnk.tap = nm_setting_macvlan_get_tap(s_macvlan); + + r = nm_platform_link_macvlan_add(nm_device_get_platform(device), + iface, + parent_ifindex, + &lnk, + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create %s interface '%s' for '%s': %s", + lnk.tap ? "macvtap" : "macvlan", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - /* We assume MACVLAN interfaces always support carrier detect */ - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + /* We assume MACVLAN interfaces always support carrier detect */ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } /*****************************************************************************/ static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - if (!nm_device_parent_get_device (device)) - return FALSE; - return NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->is_available (device, flags); + if (!nm_device_parent_get_device(device)) + return FALSE; + return NM_DEVICE_CLASS(nm_device_macvlan_parent_class)->is_available(device, flags); } /*****************************************************************************/ static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); - NMSettingMacvlan *s_macvlan; - const char *parent = NULL; - - if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - s_macvlan = nm_connection_get_setting_macvlan (connection); - - if (nm_setting_macvlan_get_tap (s_macvlan) != priv->props.tap) { - if (priv->props.tap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvtap device does not match macvlan profile"); - } else { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan device does not match macvtap profile"); - } - return FALSE; - } - - /* Before the device is realized some properties will not be set */ - if (nm_device_is_real (device)) { - - if (setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)) != priv->props.mode) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan mode setting differs"); - return FALSE; - } - - if (nm_setting_macvlan_get_promiscuous (s_macvlan) == priv->props.no_promisc) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan promiscuous setting differs"); - return FALSE; - } - - /* Check parent interface; could be an interface name or a UUID */ - parent = nm_setting_macvlan_get_parent (s_macvlan); - if (parent) { - if (!nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan parent setting differs"); - return FALSE; - } - } else { - /* Parent could be a MAC address in an NMSettingWired */ - if (!nm_device_match_parent_hwaddr (device, connection, TRUE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan parent mac setting differs"); - return FALSE; - } - } - } - - return TRUE; + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(device); + NMSettingMacvlan * s_macvlan; + const char * parent = NULL; + + if (!NM_DEVICE_CLASS(nm_device_macvlan_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + s_macvlan = nm_connection_get_setting_macvlan(connection); + + if (nm_setting_macvlan_get_tap(s_macvlan) != priv->props.tap) { + if (priv->props.tap) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvtap device does not match macvlan profile"); + } else { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvlan device does not match macvtap profile"); + } + return FALSE; + } + + /* Before the device is realized some properties will not be set */ + if (nm_device_is_real(device)) { + if (setting_mode_to_platform(nm_setting_macvlan_get_mode(s_macvlan)) != priv->props.mode) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvlan mode setting differs"); + return FALSE; + } + + if (nm_setting_macvlan_get_promiscuous(s_macvlan) == priv->props.no_promisc) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvlan promiscuous setting differs"); + return FALSE; + } + + /* Check parent interface; could be an interface name or a UUID */ + parent = nm_setting_macvlan_get_parent(s_macvlan); + if (parent) { + if (!nm_device_match_parent(device, parent)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvlan parent setting differs"); + return FALSE; + } + } else { + /* Parent could be a MAC address in an NMSettingWired */ + if (!nm_device_match_parent_hwaddr(device, connection, TRUE)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "macvlan parent mac setting differs"); + return FALSE; + } + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingMacvlan *s_macvlan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_MACVLAN_SETTING_NAME, - existing_connections, - NULL, - _("MACVLAN connection"), - NULL, - NULL, - TRUE); - - s_macvlan = nm_connection_get_setting_macvlan (connection); - if (!s_macvlan) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'macvlan' setting is required."); - return FALSE; - } - - /* If there's no MACVLAN interface, no parent, and no hardware address in the - * settings, then there's not enough information to complete the setting. - */ - if ( !nm_setting_macvlan_get_parent (s_macvlan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "The 'macvlan' setting had no interface name, parent, or hardware address."); - return FALSE; - } - - return TRUE; + NMSettingMacvlan *s_macvlan; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_MACVLAN_SETTING_NAME, + existing_connections, + NULL, + _("MACVLAN connection"), + NULL, + NULL, + TRUE); + + s_macvlan = nm_connection_get_setting_macvlan(connection); + if (!s_macvlan) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'macvlan' setting is required."); + return FALSE; + } + + /* If there's no MACVLAN interface, no parent, and no hardware address in the + * settings, then there's not enough information to complete the setting. + */ + if (!nm_setting_macvlan_get_parent(s_macvlan) + && !nm_device_match_parent_hwaddr(device, connection, TRUE)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "The 'macvlan' setting had no interface name, parent, or hardware address."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); - NMSettingMacvlan *s_macvlan = nm_connection_get_setting_macvlan (connection); - int new_mode; - - if (!s_macvlan) { - s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new (); - nm_connection_add_setting (connection, (NMSetting *) s_macvlan); - } - - new_mode = platform_mode_to_setting (priv->props.mode); - if (new_mode != nm_setting_macvlan_get_mode (s_macvlan)) - g_object_set (s_macvlan, NM_SETTING_MACVLAN_MODE, new_mode, NULL); - - if (priv->props.no_promisc == nm_setting_macvlan_get_promiscuous (s_macvlan)) - g_object_set (s_macvlan, NM_SETTING_MACVLAN_PROMISCUOUS, !priv->props.no_promisc, NULL); - - if (priv->props.tap != nm_setting_macvlan_get_tap (s_macvlan)) - g_object_set (s_macvlan, NM_SETTING_MACVLAN_TAP, !!priv->props.tap, NULL); - - g_object_set (s_macvlan, - NM_SETTING_MACVLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_macvlan_get_parent (s_macvlan)), - NULL); + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(device); + NMSettingMacvlan * s_macvlan = nm_connection_get_setting_macvlan(connection); + int new_mode; + + if (!s_macvlan) { + s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new(); + nm_connection_add_setting(connection, (NMSetting *) s_macvlan); + } + + new_mode = platform_mode_to_setting(priv->props.mode); + if (new_mode != nm_setting_macvlan_get_mode(s_macvlan)) + g_object_set(s_macvlan, NM_SETTING_MACVLAN_MODE, new_mode, NULL); + + if (priv->props.no_promisc == nm_setting_macvlan_get_promiscuous(s_macvlan)) + g_object_set(s_macvlan, NM_SETTING_MACVLAN_PROMISCUOUS, !priv->props.no_promisc, NULL); + + if (priv->props.tap != nm_setting_macvlan_get_tap(s_macvlan)) + g_object_set(s_macvlan, NM_SETTING_MACVLAN_TAP, !!priv->props.tap, NULL); + + g_object_set( + s_macvlan, + NM_SETTING_MACVLAN_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_macvlan_get_parent(s_macvlan)), + NULL); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MODE: - g_value_set_string (value, platform_mode_to_string (priv->props.mode)); - break; - case PROP_NO_PROMISC: - g_value_set_boolean (value, priv->props.no_promisc); - break; - case PROP_TAP: - g_value_set_boolean (value, priv->props.tap); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODE: + g_value_set_string(value, platform_mode_to_string(priv->props.mode)); + break; + case PROP_NO_PROMISC: + g_value_set_boolean(value, priv->props.no_promisc); + break; + case PROP_TAP: + g_value_set_boolean(value, priv->props.tap); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_TAP: - priv->props.tap = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_TAP: + priv->props.tap = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } } /*****************************************************************************/ static void -nm_device_macvlan_init (NMDeviceMacvlan *self) -{ -} +nm_device_macvlan_init(NMDeviceMacvlan *self) +{} #if NM_MORE_ASSERTS static void -dispose (GObject *object) +dispose(GObject *object) { - G_OBJECT_CLASS (nm_device_macvlan_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_macvlan_parent_class)->dispose(object); - nm_assert (NM_DEVICE_MACVLAN_GET_PRIVATE (object)->parent_state_id == 0); - nm_assert (NM_DEVICE_MACVLAN_GET_PRIVATE (object)->parent_mtu_id == 0); + nm_assert(NM_DEVICE_MACVLAN_GET_PRIVATE(object)->parent_state_id == 0); + nm_assert(NM_DEVICE_MACVLAN_GET_PRIVATE(object)->parent_mtu_id == 0); } #endif static const NMDBusInterfaceInfoExtended interface_info_device_macvlan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_MACVLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "s", NM_DEVICE_MACVLAN_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NoPromisc", "b", NM_DEVICE_MACVLAN_NO_PROMISC), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tab", "b", NM_DEVICE_MACVLAN_TAP), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_MACVLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "s", NM_DEVICE_MACVLAN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NoPromisc", + "b", + NM_DEVICE_MACVLAN_NO_PROMISC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tab", + "b", + NM_DEVICE_MACVLAN_TAP), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) +nm_device_macvlan_class_init(NMDeviceMacvlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); #if NM_MORE_ASSERTS - object_class->dispose = dispose; + object_class->dispose = dispose; #endif - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macvlan); - - device_class->connection_type_supported = NM_SETTING_MACVLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_MACVLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP); - device_class->mtu_parent_delta = 0; - - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; - device_class->is_available = is_available; - device_class->link_changed = link_changed; - device_class->parent_changed_notify = parent_changed_notify; - device_class->update_connection = update_connection; - - obj_properties[PROP_MODE] = - g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_NO_PROMISC] = - g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_TAP] = - g_param_spec_boolean (NM_DEVICE_MACVLAN_TAP, "", "", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_macvlan); + + device_class->connection_type_supported = NM_SETTING_MACVLAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_MACVLAN_SETTING_NAME; + device_class->link_types = + NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP); + device_class->mtu_parent_delta = 0; + + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; + device_class->is_available = is_available; + device_class->link_changed = link_changed; + device_class->parent_changed_notify = parent_changed_notify; + device_class->update_connection = update_connection; + + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_MACVLAN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_NO_PROMISC] = + g_param_spec_boolean(NM_DEVICE_MACVLAN_NO_PROMISC, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_TAP] = + g_param_spec_boolean(NM_DEVICE_MACVLAN_TAP, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_MACVLAN_DEVICE_FACTORY (nm_macvlan_device_factory_get_type ()) -#define NM_MACVLAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MACVLAN_DEVICE_FACTORY, NMMacvlanDeviceFactory)) +#define NM_TYPE_MACVLAN_DEVICE_FACTORY (nm_macvlan_device_factory_get_type()) +#define NM_MACVLAN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MACVLAN_DEVICE_FACTORY, NMMacvlanDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - NMSettingMacvlan *s_macvlan; - NMLinkType link_type; - gboolean tap; - - if (connection) { - s_macvlan = nm_connection_get_setting_macvlan (connection); - g_assert (s_macvlan); - tap = nm_setting_macvlan_get_tap (s_macvlan); - } else { - g_assert (plink); - tap = plink->type == NM_LINK_TYPE_MACVTAP; - } - - link_type = tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Macvlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MACVLAN, - NM_DEVICE_LINK_TYPE, link_type, - NM_DEVICE_MACVLAN_TAP, tap, - NULL); + NMSettingMacvlan *s_macvlan; + NMLinkType link_type; + gboolean tap; + + if (connection) { + s_macvlan = nm_connection_get_setting_macvlan(connection); + g_assert(s_macvlan); + tap = nm_setting_macvlan_get_tap(s_macvlan); + } else { + g_assert(plink); + tap = plink->type == NM_LINK_TYPE_MACVTAP; + } + + link_type = tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_MACVLAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Macvlan", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_MACVLAN, + NM_DEVICE_LINK_TYPE, + link_type, + NM_DEVICE_MACVLAN_TAP, + tap, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingMacvlan *s_macvlan; - NMSettingWired *s_wired; - const char *parent = NULL; + NMSettingMacvlan *s_macvlan; + NMSettingWired * s_wired; + const char * parent = NULL; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); - s_macvlan = nm_connection_get_setting_macvlan (connection); - g_assert (s_macvlan); + s_macvlan = nm_connection_get_setting_macvlan(connection); + g_assert(s_macvlan); - parent = nm_setting_macvlan_get_parent (s_macvlan); - if (parent) - return parent; + parent = nm_setting_macvlan_get_parent(s_macvlan); + if (parent) + return parent; - /* Try the hardware address from the MACVLAN connection's hardware setting */ - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) - return nm_setting_wired_get_mac_address (s_wired); + /* Try the hardware address from the MACVLAN connection's hardware setting */ + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + return nm_setting_wired_get_mac_address(s_wired); - return NULL; + return NULL; } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - NMSettingMacvlan *s_macvlan; - const char *ifname; + NMSettingMacvlan *s_macvlan; + const char * ifname; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); - s_macvlan = nm_connection_get_setting_macvlan (connection); - g_assert (s_macvlan); + s_macvlan = nm_connection_get_setting_macvlan(connection); + g_assert(s_macvlan); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); - return g_strdup (ifname); + ifname = nm_connection_get_interface_name(connection); + return g_strdup(ifname); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (MACVLAN, Macvlan, macvlan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_MACVLAN_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + MACVLAN, + Macvlan, + macvlan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_MACVLAN_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-macvlan.h b/src/devices/nm-device-macvlan.h index 8fcf97cd..f36a7a4a 100644 --- a/src/devices/nm-device-macvlan.h +++ b/src/devices/nm-device-macvlan.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -8,20 +8,23 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type ()) -#define NM_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) -#define NM_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) -#define NM_IS_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACVLAN)) -#define NM_IS_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACVLAN)) -#define NM_DEVICE_MACVLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) +#define NM_TYPE_DEVICE_MACVLAN (nm_device_macvlan_get_type()) +#define NM_DEVICE_MACVLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan)) +#define NM_DEVICE_MACVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) +#define NM_IS_DEVICE_MACVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MACVLAN)) +#define NM_IS_DEVICE_MACVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MACVLAN)) +#define NM_DEVICE_MACVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanClass)) #define NM_DEVICE_MACVLAN_MODE "mode" #define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" #define NM_DEVICE_MACVLAN_TAP "tap" -typedef struct _NMDeviceMacvlan NMDeviceMacvlan; +typedef struct _NMDeviceMacvlan NMDeviceMacvlan; typedef struct _NMDeviceMacvlanClass NMDeviceMacvlanClass; -GType nm_device_macvlan_get_type (void); +GType nm_device_macvlan_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_MACVLAN_H__ */ diff --git a/src/devices/nm-device-ppp.c b/src/devices/nm-device-ppp.c index cbc87141..82861bda 100644 --- a/src/devices/nm-device-ppp.c +++ b/src/devices/nm-device-ppp.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -24,347 +24,352 @@ _LOG_DECLARE_SELF(NMDevicePpp); /*****************************************************************************/ typedef struct _NMDevicePppPrivate { - NMPPPManager *ppp_manager; - NMIP4Config *ip4_config; + NMPPPManager *ppp_manager; + NMIP4Config * ip4_config; } NMDevicePppPrivate; struct _NMDevicePpp { - NMDevice parent; - NMDevicePppPrivate _priv; + NMDevice parent; + NMDevicePppPrivate _priv; }; struct _NMDevicePppClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE) -#define NM_DEVICE_PPP_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDevicePpp, NM_IS_DEVICE_PPP, NMDevice) +#define NM_DEVICE_PPP_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDevicePpp, NM_IS_DEVICE_PPP, NMDevice) static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static void -ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) +ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - - switch (status) { - case NM_PPP_STATUS_DISCONNECT: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); - break; - case NM_PPP_STATUS_DEAD: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); - break; - default: - break; - } + NMDevice *device = NM_DEVICE(user_data); + + switch (status) { + case NM_PPP_STATUS_DISCONNECT: + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT); + break; + case NM_PPP_STATUS_DEAD: + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); + break; + default: + break; + } } static void -ppp_ifindex_set (NMPPPManager *ppp_manager, - int ifindex, - const char *iface, - gpointer user_data) +ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePpp *self = NM_DEVICE_PPP (device); - gs_free char *old_name = NULL; - gs_free_error GError *error = NULL; - - if (!nm_device_take_over_link (device, ifindex, &old_name, &error)) { - _LOGW (LOGD_DEVICE | LOGD_PPP, "could not take control of link %d: %s", - ifindex, error->message); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return; - } - - if (old_name) - nm_manager_remove_device (NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP); - - nm_device_activate_schedule_stage3_ip_config_start (device); + NMDevice * device = NM_DEVICE(user_data); + NMDevicePpp * self = NM_DEVICE_PPP(device); + gs_free char *old_name = NULL; + gs_free_error GError *error = NULL; + + if (!nm_device_take_over_link(device, ifindex, &old_name, &error)) { + _LOGW(LOGD_DEVICE | LOGD_PPP, + "could not take control of link %d: %s", + ifindex, + error->message); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + if (old_name) + nm_manager_remove_device(NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP); + + nm_device_activate_schedule_stage3_ip_config_start(device); } static void -ppp_ip4_config (NMPPPManager *ppp_manager, - NMIP4Config *config, - gpointer user_data) +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePpp *self = NM_DEVICE_PPP (device); - NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self); - - _LOGT (LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); - - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { - if (nm_device_activate_ip4_state_in_conf (device)) { - nm_device_activate_schedule_ip_config_result (device, AF_INET, NM_IP_CONFIG_CAST (config)); - return; - } - } else { - if (priv->ip4_config) - g_object_unref (priv->ip4_config); - priv->ip4_config = g_object_ref (config); - } + NMDevice * device = NM_DEVICE(user_data); + NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + + _LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); + + if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) { + if (nm_device_activate_ip4_state_in_conf(device)) { + nm_device_activate_schedule_ip_config_result(device, + AF_INET, + NM_IP_CONFIG_CAST(config)); + return; + } + } else { + if (priv->ip4_config) + g_object_unref(priv->ip4_config); + priv->ip4_config = g_object_ref(config); + } } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingPppoe *s_pppoe; + NMSettingPppoe *s_pppoe; - if (!NM_DEVICE_CLASS (nm_device_ppp_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_ppp_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - s_pppoe = nm_connection_get_setting_pppoe (connection); - if ( !s_pppoe - || !nm_setting_pppoe_get_parent (s_pppoe)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "the connection doesn't specify a PPPoE parent interface"); - return FALSE; - } + s_pppoe = nm_connection_get_setting_pppoe(connection); + if (!s_pppoe || !nm_setting_pppoe_get_parent(s_pppoe)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "the connection doesn't specify a PPPoE parent interface"); + return FALSE; + } - return TRUE; + return TRUE; } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDevicePpp *self = NM_DEVICE_PPP (device); - NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self); - NMSettingPppoe *s_pppoe; - NMActRequest *req; - GError *error = NULL; - - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - s_pppoe = nm_device_get_applied_setting (device, NM_TYPE_SETTING_PPPOE); - g_return_val_if_fail (s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); - - g_clear_object (&priv->ip4_config); - - priv->ppp_manager = nm_ppp_manager_create (nm_setting_pppoe_get_parent (s_pppoe), &error); - - if (priv->ppp_manager) { - nm_ppp_manager_set_route_parameters (priv->ppp_manager, - nm_device_get_route_table (device, AF_INET), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_table (device, AF_INET6), - nm_device_get_route_metric (device, AF_INET6)); - } - - if ( !priv->ppp_manager - || !nm_ppp_manager_start (priv->ppp_manager, - req, - nm_setting_pppoe_get_username (s_pppoe), - 30, - 0, - &error)) { - _LOGW (LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", error->message); - g_error_free (error); - - g_clear_object (&priv->ppp_manager); - - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - g_signal_connect (priv->ppp_manager, - NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, - G_CALLBACK (ppp_state_changed), - self); - g_signal_connect (priv->ppp_manager, - NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, - G_CALLBACK (ppp_ifindex_set), - self); - g_signal_connect (priv->ppp_manager, - NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, - G_CALLBACK (ppp_ip4_config), - self); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + NMSettingPppoe * s_pppoe; + NMActRequest * req; + GError * error = NULL; + + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + s_pppoe = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE); + g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); + + g_clear_object(&priv->ip4_config); + + priv->ppp_manager = nm_ppp_manager_create(nm_setting_pppoe_get_parent(s_pppoe), &error); + + if (priv->ppp_manager) { + nm_ppp_manager_set_route_parameters(priv->ppp_manager, + nm_device_get_route_table(device, AF_INET), + nm_device_get_route_metric(device, AF_INET), + nm_device_get_route_table(device, AF_INET6), + nm_device_get_route_metric(device, AF_INET6)); + } + + if (!priv->ppp_manager + || !nm_ppp_manager_start(priv->ppp_manager, + req, + nm_setting_pppoe_get_username(s_pppoe), + 30, + 0, + &error)) { + _LOGW(LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", error->message); + g_error_free(error); + + g_clear_object(&priv->ppp_manager); + + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, + G_CALLBACK(ppp_state_changed), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, + G_CALLBACK(ppp_ifindex_set), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, + G_CALLBACK(ppp_ip4_config), + self); + return NM_ACT_STAGE_RETURN_POSTPONE; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - if (addr_family == AF_INET) { - NMDevicePpp *self = NM_DEVICE_PPP (device); - NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self); - - if (priv->ip4_config) { - if (out_config) - *out_config = g_steal_pointer (&priv->ip4_config); - else - g_clear_object (&priv->ip4_config); - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - /* Wait IPCP termination */ - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - return NM_DEVICE_CLASS (nm_device_ppp_parent_class)->act_stage3_ip_config_start (device, - addr_family, - out_config, - out_failure_reason); + if (addr_family == AF_INET) { + NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + + if (priv->ip4_config) { + if (out_config) + *out_config = g_steal_pointer(&priv->ip4_config); + else + g_clear_object(&priv->ip4_config); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + /* Wait IPCP termination */ + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + return NM_DEVICE_CLASS(nm_device_ppp_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - int parent_ifindex; + int parent_ifindex; - if (!parent) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "PPP devices can not be created without a parent interface"); - return FALSE; - } + if (!parent) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "PPP devices can not be created without a parent interface"); + return FALSE; + } - parent_ifindex = nm_device_get_ifindex (parent); - g_warn_if_fail (parent_ifindex > 0); + parent_ifindex = nm_device_get_ifindex(parent); + g_warn_if_fail(parent_ifindex > 0); - nm_device_parent_set_ifindex (device, parent_ifindex); + nm_device_parent_set_ifindex(device, parent_ifindex); - /* The interface is created later */ + /* The interface is created later */ - return TRUE; + return TRUE; } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDevicePpp *self = NM_DEVICE_PPP (device); - NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self); + NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - if (priv->ppp_manager) { - nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL); - g_clear_object (&priv->ppp_manager); - } + if (priv->ppp_manager) { + nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); + g_clear_object(&priv->ppp_manager); + } } static void -nm_device_ppp_init (NMDevicePpp *self) -{ -} +nm_device_ppp_init(NMDevicePpp *self) +{} static void -dispose (GObject *object) +dispose(GObject *object) { - NMDevicePpp *self = NM_DEVICE_PPP (object); - NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self); + NMDevicePpp * self = NM_DEVICE_PPP(object); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - g_clear_object (&priv->ip4_config); + g_clear_object(&priv->ip4_config); - G_OBJECT_CLASS (nm_device_ppp_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_ppp_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_ppp = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_PPP, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_PPP, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ppp_class_init (NMDevicePppClass *klass) +nm_device_ppp_class_init(NMDevicePppClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ppp); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_ppp); - device_class->connection_type_supported = NM_SETTING_PPPOE_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_PPPOE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_PPP); + device_class->connection_type_supported = NM_SETTING_PPPOE_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_PPPOE_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_PPP); - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->check_connection_compatible = check_connection_compatible; - device_class->create_and_realize = create_and_realize; - device_class->deactivate = deactivate; - device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->check_connection_compatible = check_connection_compatible; + device_class->create_and_realize = create_and_realize; + device_class->deactivate = deactivate; + device_class->get_generic_capabilities = get_generic_capabilities; } /*****************************************************************************/ -#define NM_TYPE_PPP_DEVICE_FACTORY (nm_ppp_device_factory_get_type ()) -#define NM_PPP_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPP_DEVICE_FACTORY, NMPppDeviceFactory)) +#define NM_TYPE_PPP_DEVICE_FACTORY (nm_ppp_device_factory_get_type()) +#define NM_PPP_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_PPP_DEVICE_FACTORY, NMPppDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_PPP, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Ppp", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_PPP, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_PPP, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_PPP, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Ppp", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_PPP, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_PPP, + NULL); } static gboolean -match_connection (NMDeviceFactory *factory, NMConnection *connection) +match_connection(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingPppoe *s_pppoe; + NMSettingPppoe *s_pppoe; - s_pppoe = nm_connection_get_setting_pppoe (connection); - nm_assert (s_pppoe); + s_pppoe = nm_connection_get_setting_pppoe(connection); + nm_assert(s_pppoe); - return !!nm_setting_pppoe_get_parent (s_pppoe); + return !!nm_setting_pppoe_get_parent(s_pppoe); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingPppoe *s_pppoe; + NMSettingPppoe *s_pppoe; - nm_assert (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)); + nm_assert(nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)); - s_pppoe = nm_connection_get_setting_pppoe (connection); - nm_assert (s_pppoe); + s_pppoe = nm_connection_get_setting_pppoe(connection); + nm_assert(s_pppoe); - return nm_setting_pppoe_get_parent (s_pppoe); + return nm_setting_pppoe_get_parent(s_pppoe); } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - nm_assert (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)); + nm_assert(nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - return g_strdup (nm_connection_get_interface_name (connection)); + return g_strdup(nm_connection_get_interface_name(connection)); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (PPP, Ppp, ppp, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_PPP) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_PPPOE_SETTING_NAME), - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; - factory_class->create_device = create_device; - factory_class->match_connection = match_connection; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + PPP, + Ppp, + ppp, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_PPP) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_PPPOE_SETTING_NAME), + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface; + factory_class->create_device = create_device; + factory_class->match_connection = match_connection;); diff --git a/src/devices/nm-device-ppp.h b/src/devices/nm-device-ppp.h index 5a169b37..99132a3e 100644 --- a/src/devices/nm-device-ppp.h +++ b/src/devices/nm-device-ppp.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -6,16 +6,18 @@ #ifndef __NETWORKMANAGER_DEVICE_PPP_H__ #define __NETWORKMANAGER_DEVICE_PPP_H__ -#define NM_TYPE_DEVICE_PPP (nm_device_ppp_get_type ()) -#define NM_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_PPP, NMDevicePpp)) -#define NM_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) -#define NM_IS_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_PPP)) -#define NM_IS_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_PPP)) -#define NM_DEVICE_PPP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) +#define NM_TYPE_DEVICE_PPP (nm_device_ppp_get_type()) +#define NM_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_PPP, NMDevicePpp)) +#define NM_DEVICE_PPP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) +#define NM_IS_DEVICE_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_PPP)) +#define NM_IS_DEVICE_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_PPP)) +#define NM_DEVICE_PPP_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_PPP, NMDevicePppClass)) -typedef struct _NMDevicePpp NMDevicePpp; +typedef struct _NMDevicePpp NMDevicePpp; typedef struct _NMDevicePppClass NMDevicePppClass; -GType nm_device_ppp_get_type (void); +GType nm_device_ppp_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_PPP_H__ */ diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index cd72f3d7..5f8eff18 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2007 - 2008 Novell, Inc. * Copyright (C) 2007 - 2011 Red Hat, Inc. @@ -12,29 +12,29 @@ /* This file should only be used by subclasses of NMDevice */ typedef enum { - NM_DEVICE_STAGE_STATE_INIT = 0, - NM_DEVICE_STAGE_STATE_PENDING = 1, - NM_DEVICE_STAGE_STATE_COMPLETED = 2, + NM_DEVICE_STAGE_STATE_INIT = 0, + NM_DEVICE_STAGE_STATE_PENDING = 1, + NM_DEVICE_STAGE_STATE_COMPLETED = 2, } NMDeviceStageState; typedef enum { - NM_DEVICE_IP_STATE_NONE, - NM_DEVICE_IP_STATE_WAIT, - NM_DEVICE_IP_STATE_CONF, - NM_DEVICE_IP_STATE_DONE, - NM_DEVICE_IP_STATE_FAIL, + NM_DEVICE_IP_STATE_NONE, + NM_DEVICE_IP_STATE_WAIT, + NM_DEVICE_IP_STATE_CONF, + NM_DEVICE_IP_STATE_DONE, + NM_DEVICE_IP_STATE_FAIL, } NMDeviceIPState; enum NMActStageReturn { - NM_ACT_STAGE_RETURN_FAILURE = 0, /* Hard failure of activation */ - NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */ - NM_ACT_STAGE_RETURN_POSTPONE, /* Long-running operation in progress */ - NM_ACT_STAGE_RETURN_IP_WAIT, /* IP config stage is waiting (state IP_WAIT) */ - NM_ACT_STAGE_RETURN_IP_DONE, /* IP config stage is done (state IP_DONE), - For the ip-config stage, this is similar to - NM_ACT_STAGE_RETURN_SUCCESS, except that no - IP config should be committed. */ - NM_ACT_STAGE_RETURN_IP_FAIL, /* IP config stage failed (state IP_FAIL), activation may proceed */ + NM_ACT_STAGE_RETURN_FAILURE = 0, /* Hard failure of activation */ + NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */ + NM_ACT_STAGE_RETURN_POSTPONE, /* Long-running operation in progress */ + NM_ACT_STAGE_RETURN_IP_WAIT, /* IP config stage is waiting (state IP_WAIT) */ + NM_ACT_STAGE_RETURN_IP_DONE, /* IP config stage is done (state IP_DONE), + * For the ip-config stage, this is similar to + * NM_ACT_STAGE_RETURN_SUCCESS, except that no + * IP config should be committed. */ + NM_ACT_STAGE_RETURN_IP_FAIL, /* IP config stage failed (state IP_FAIL), activation may proceed */ }; #define NM_DEVICE_CAP_NONSTANDARD_CARRIER 0x80000000 @@ -42,178 +42,172 @@ enum NMActStageReturn { #define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000 -void nm_device_arp_announce (NMDevice *self); +void nm_device_arp_announce(NMDevice *self); -NMSettings *nm_device_get_settings (NMDevice *self); +NMSettings *nm_device_get_settings(NMDevice *self); -NMManager *nm_device_get_manager (NMDevice *self); +NMManager *nm_device_get_manager(NMDevice *self); -gboolean nm_device_set_ip_ifindex (NMDevice *self, int ifindex); +gboolean nm_device_set_ip_ifindex(NMDevice *self, int ifindex); -gboolean nm_device_set_ip_iface (NMDevice *self, const char *iface); +gboolean nm_device_set_ip_iface(NMDevice *self, const char *iface); -void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device); +void nm_device_activate_schedule_stage3_ip_config_start(NMDevice *device); -gboolean nm_device_activate_stage3_ip4_start (NMDevice *self); +gboolean nm_device_activate_stage3_ip4_start(NMDevice *self); -gboolean nm_device_activate_stage3_ip6_start (NMDevice *self); +gboolean nm_device_activate_stage3_ip6_start(NMDevice *self); -gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmware); +gboolean nm_device_bring_up(NMDevice *self, gboolean wait, gboolean *no_firmware); -void nm_device_take_down (NMDevice *self, gboolean block); +void nm_device_take_down(NMDevice *self, gboolean block); -gboolean nm_device_take_over_link (NMDevice *self, int ifindex, char **old_name, GError **error); +gboolean nm_device_take_over_link(NMDevice *self, int ifindex, char **old_name, GError **error); -gboolean nm_device_hw_addr_set (NMDevice *device, - const char *addr, - const char *detail, - gboolean set_permanent); -gboolean nm_device_hw_addr_set_cloned (NMDevice *device, NMConnection *connection, gboolean is_wifi); -gboolean nm_device_hw_addr_reset (NMDevice *device, const char *detail); +gboolean nm_device_hw_addr_set(NMDevice * device, + const char *addr, + const char *detail, + gboolean set_permanent); +gboolean nm_device_hw_addr_set_cloned(NMDevice *device, NMConnection *connection, gboolean is_wifi); +gboolean nm_device_hw_addr_reset(NMDevice *device, const char *detail); -void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); +void nm_device_set_firmware_missing(NMDevice *self, gboolean missing); -void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device, - gboolean do_sync); -void nm_device_activate_schedule_stage2_device_config (NMDevice *device, - gboolean do_sync); +void nm_device_activate_schedule_stage1_device_prepare(NMDevice *device, gboolean do_sync); +void nm_device_activate_schedule_stage2_device_config(NMDevice *device, gboolean do_sync); -void nm_device_activate_schedule_ip_config_result (NMDevice *device, - int addr_family, - NMIPConfig *config); +void +nm_device_activate_schedule_ip_config_result(NMDevice *device, int addr_family, NMIPConfig *config); -void nm_device_activate_schedule_ip_config_timeout (NMDevice *device, - int addr_family); +void nm_device_activate_schedule_ip_config_timeout(NMDevice *device, int addr_family); -NMDeviceIPState nm_device_activate_get_ip_state (NMDevice *self, - int addr_family); +NMDeviceIPState nm_device_activate_get_ip_state(NMDevice *self, int addr_family); static inline gboolean -nm_device_activate_ip4_state_in_conf (NMDevice *self) +nm_device_activate_ip4_state_in_conf(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET) == NM_DEVICE_IP_STATE_CONF; + return nm_device_activate_get_ip_state(self, AF_INET) == NM_DEVICE_IP_STATE_CONF; } static inline gboolean -nm_device_activate_ip4_state_in_wait (NMDevice *self) +nm_device_activate_ip4_state_in_wait(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET) == NM_DEVICE_IP_STATE_WAIT; + return nm_device_activate_get_ip_state(self, AF_INET) == NM_DEVICE_IP_STATE_WAIT; } static inline gboolean -nm_device_activate_ip4_state_done (NMDevice *self) +nm_device_activate_ip4_state_done(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET) == NM_DEVICE_IP_STATE_DONE; + return nm_device_activate_get_ip_state(self, AF_INET) == NM_DEVICE_IP_STATE_DONE; } static inline gboolean -nm_device_activate_ip6_state_in_conf (NMDevice *self) +nm_device_activate_ip6_state_in_conf(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET6) == NM_DEVICE_IP_STATE_CONF; + return nm_device_activate_get_ip_state(self, AF_INET6) == NM_DEVICE_IP_STATE_CONF; } static inline gboolean -nm_device_activate_ip6_state_in_wait (NMDevice *self) +nm_device_activate_ip6_state_in_wait(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET6) == NM_DEVICE_IP_STATE_WAIT; + return nm_device_activate_get_ip_state(self, AF_INET6) == NM_DEVICE_IP_STATE_WAIT; } static inline gboolean -nm_device_activate_ip6_state_done (NMDevice *self) +nm_device_activate_ip6_state_done(NMDevice *self) { - return nm_device_activate_get_ip_state (self, AF_INET6) == NM_DEVICE_IP_STATE_DONE; + return nm_device_activate_get_ip_state(self, AF_INET6) == NM_DEVICE_IP_STATE_DONE; } -void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr); +void nm_device_set_dhcp_anycast_address(NMDevice *device, const char *addr); -gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); -gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release); +gboolean nm_device_dhcp4_renew(NMDevice *device, gboolean release); +gboolean nm_device_dhcp6_renew(NMDevice *device, gboolean release); -void nm_device_recheck_available_connections (NMDevice *device); +void nm_device_recheck_available_connections(NMDevice *device); -void nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, - NMLogDomain log_domain); +void +nm_device_master_check_slave_physical_port(NMDevice *self, NMDevice *slave, NMLogDomain log_domain); -void nm_device_set_carrier (NMDevice *self, gboolean carrier); +void nm_device_set_carrier(NMDevice *self, gboolean carrier); -void nm_device_queue_recheck_assume (NMDevice *device); -void nm_device_queue_recheck_available (NMDevice *device, - NMDeviceStateReason available_reason, - NMDeviceStateReason unavailable_reason); +void nm_device_queue_recheck_assume(NMDevice *device); +void nm_device_queue_recheck_available(NMDevice * device, + NMDeviceStateReason available_reason, + NMDeviceStateReason unavailable_reason); -void nm_device_set_dev2_ip_config (NMDevice *device, - int addr_family, - NMIPConfig *config); +void nm_device_set_dev2_ip_config(NMDevice *device, int addr_family, NMIPConfig *config); -gboolean nm_device_hw_addr_is_explict (NMDevice *device); +gboolean nm_device_hw_addr_is_explict(NMDevice *device); -void nm_device_ip_method_failed (NMDevice *self, int addr_family, NMDeviceStateReason reason); +void nm_device_ip_method_failed(NMDevice *self, int addr_family, NMDeviceStateReason reason); -gboolean nm_device_sysctl_ip_conf_set (NMDevice *self, - int addr_family, - const char *property, - const char *value); +gboolean nm_device_sysctl_ip_conf_set(NMDevice * self, + int addr_family, + const char *property, + const char *value); -NMIP4Config *nm_device_ip4_config_new (NMDevice *self); +NMIP4Config *nm_device_ip4_config_new(NMDevice *self); -NMIP6Config *nm_device_ip6_config_new (NMDevice *self); +NMIP6Config *nm_device_ip6_config_new(NMDevice *self); -NMIPConfig *nm_device_ip_config_new (NMDevice *self, int addr_family); +NMIPConfig *nm_device_ip_config_new(NMDevice *self, int addr_family); + +NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self); /*****************************************************************************/ -gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self, - const char *property_name, - guint32 max_mtu); +gint64 nm_device_get_configured_mtu_from_connection_default(NMDevice * self, + const char *property_name, + guint32 max_mtu); -guint32 nm_device_get_configured_mtu_from_connection (NMDevice *device, - GType setting_type, - NMDeviceMtuSource *out_source); +guint32 nm_device_get_configured_mtu_from_connection(NMDevice * device, + GType setting_type, + NMDeviceMtuSource *out_source); -guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force); +guint32 nm_device_get_configured_mtu_for_wired(NMDevice * self, + NMDeviceMtuSource *out_source, + gboolean * out_force); -guint32 nm_device_get_configured_mtu_wired_parent (NMDevice *self, - NMDeviceMtuSource *out_source, - gboolean *out_force); +guint32 nm_device_get_configured_mtu_wired_parent(NMDevice * self, + NMDeviceMtuSource *out_source, + gboolean * out_force); -void nm_device_commit_mtu (NMDevice *self); +void nm_device_commit_mtu(NMDevice *self); /*****************************************************************************/ -#define NM_DEVICE_DEFINE_LINK_TYPES(...) \ - ((NM_NARG (__VA_ARGS__) == 0) \ - ? NULL \ - : ({ \ - static const NMLinkType _types[NM_NARG (__VA_ARGS__) + 1] = { \ - __VA_ARGS__ \ - _NM_MACRO_COMMA_IF_ARGS (__VA_ARGS__) \ - NM_LINK_TYPE_NONE, \ - }; \ - \ - nm_assert (_types[NM_NARG (__VA_ARGS__)] == NM_LINK_TYPE_NONE); \ - _types; \ - })\ - ) - -gboolean _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, - GError **error, const char *const*whitelist); +#define NM_DEVICE_DEFINE_LINK_TYPES(...) \ + ((NM_NARG(__VA_ARGS__) == 0) ? NULL : ({ \ + static const NMLinkType _types[NM_NARG(__VA_ARGS__) + 1] = { \ + __VA_ARGS__ _NM_MACRO_COMMA_IF_ARGS(__VA_ARGS__) NM_LINK_TYPE_NONE, \ + }; \ + \ + nm_assert(_types[NM_NARG(__VA_ARGS__)] == NM_LINK_TYPE_NONE); \ + _types; \ + })) + +gboolean _nm_device_hash_check_invalid_keys(GHashTable * hash, + const char * setting_name, + GError ** error, + const char *const *whitelist); #define nm_device_hash_check_invalid_keys(hash, setting_name, error, ...) \ - _nm_device_hash_check_invalid_keys (hash, setting_name, error, NM_MAKE_STRV (__VA_ARGS__)) + _nm_device_hash_check_invalid_keys(hash, setting_name, error, NM_MAKE_STRV(__VA_ARGS__)) -gboolean nm_device_match_parent (NMDevice *device, const char *parent); -gboolean nm_device_match_parent_hwaddr (NMDevice *device, - NMConnection *connection, - gboolean fail_if_no_hwaddr); +gboolean nm_device_match_parent(NMDevice *device, const char *parent); +gboolean nm_device_match_parent_hwaddr(NMDevice * device, + NMConnection *connection, + gboolean fail_if_no_hwaddr); /*****************************************************************************/ -void nm_device_auth_request (NMDevice *self, - GDBusMethodInvocation *context, - NMConnection *connection, - const char *permission, - gboolean allow_interaction, - GCancellable *cancellable, - NMManagerDeviceAuthRequestFunc callback, - gpointer user_data); +void nm_device_auth_request(NMDevice * self, + GDBusMethodInvocation * context, + NMConnection * connection, + const char * permission, + gboolean allow_interaction, + GCancellable * cancellable, + NMManagerDeviceAuthRequestFunc callback, + gpointer user_data); #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 8d4680e2..94805255 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - 2015 Red Hat, Inc. */ @@ -24,490 +24,548 @@ _LOG_DECLARE_SELF(NMDeviceTun); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceTun, - PROP_OWNER, - PROP_GROUP, - PROP_MODE, - PROP_NO_PI, - PROP_VNET_HDR, - PROP_MULTI_QUEUE, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceTun, + PROP_OWNER, + PROP_GROUP, + PROP_MODE, + PROP_NO_PI, + PROP_VNET_HDR, + PROP_MULTI_QUEUE, ); typedef struct { - NMPlatformLnkTun props; + NMPlatformLnkTun props; } NMDeviceTunPrivate; struct _NMDeviceTun { - NMDevice parent; - NMDeviceTunPrivate _priv; + NMDevice parent; + NMDeviceTunPrivate _priv; }; struct _NMDeviceTunClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE) -#define NM_DEVICE_TUN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceTun, NM_IS_DEVICE_TUN, NMDevice) +#define NM_DEVICE_TUN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceTun, NM_IS_DEVICE_TUN, NMDevice) /*****************************************************************************/ static void -update_properties_from_struct (NMDeviceTun *self, - const NMPlatformLnkTun *props) +update_properties_from_struct(NMDeviceTun *self, const NMPlatformLnkTun *props) { - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - const NMPlatformLnkTun props0 = { }; - - if (!props) { - /* allow passing %NULL to reset all properties. */ - props = &props0; - } - - g_object_freeze_notify (G_OBJECT (self)); - -#define CHECK_PROPERTY_CHANGED_VALID(field, prop) \ - G_STMT_START { \ - if ( priv->props.field != props->field \ - || priv->props.field##_valid != props->field##_valid) { \ - priv->props.field##_valid = props->field##_valid; \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->props.field != props->field) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED_VALID (owner, PROP_OWNER); - CHECK_PROPERTY_CHANGED_VALID (group, PROP_GROUP); - CHECK_PROPERTY_CHANGED (type, PROP_MODE); - CHECK_PROPERTY_CHANGED (pi, PROP_NO_PI); - CHECK_PROPERTY_CHANGED (vnet_hdr, PROP_VNET_HDR); - CHECK_PROPERTY_CHANGED (multi_queue, PROP_MULTI_QUEUE); - - g_object_thaw_notify (G_OBJECT (self)); + NMDeviceTunPrivate * priv = NM_DEVICE_TUN_GET_PRIVATE(self); + const NMPlatformLnkTun props0 = {}; + + if (!props) { + /* allow passing %NULL to reset all properties. */ + props = &props0; + } + + g_object_freeze_notify(G_OBJECT(self)); + +#define CHECK_PROPERTY_CHANGED_VALID(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field \ + || priv->props.field##_valid != props->field##_valid) { \ + priv->props.field##_valid = props->field##_valid; \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED_VALID(owner, PROP_OWNER); + CHECK_PROPERTY_CHANGED_VALID(group, PROP_GROUP); + CHECK_PROPERTY_CHANGED(type, PROP_MODE); + CHECK_PROPERTY_CHANGED(pi, PROP_NO_PI); + CHECK_PROPERTY_CHANGED(vnet_hdr, PROP_VNET_HDR); + CHECK_PROPERTY_CHANGED(multi_queue, PROP_MULTI_QUEUE); + + g_object_thaw_notify(G_OBJECT(self)); } static void -update_properties (NMDeviceTun *self) +update_properties(NMDeviceTun *self) { - NMPlatformLnkTun props_storage; - const NMPlatformLnkTun *props = NULL; - int ifindex; - - ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - if ( ifindex > 0 - && nm_platform_link_tun_get_properties (nm_device_get_platform (NM_DEVICE (self)), - ifindex, - &props_storage)) - props = &props_storage; - - update_properties_from_struct (self, props); + NMPlatformLnkTun props_storage; + const NMPlatformLnkTun *props = NULL; + int ifindex; + + ifindex = nm_device_get_ifindex(NM_DEVICE(self)); + if (ifindex > 0 + && nm_platform_link_tun_get_properties(nm_device_get_platform(NM_DEVICE(self)), + ifindex, + &props_storage)) + props = &props_storage; + + update_properties_from_struct(self, props); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_tun_parent_class)->link_changed (device, pllink); - update_properties (NM_DEVICE_TUN (device)); + NM_DEVICE_CLASS(nm_device_tun_parent_class)->link_changed(device, pllink); + update_properties(NM_DEVICE_TUN(device)); } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingTun *s_tun; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_TUN_SETTING_NAME, - existing_connections, - NULL, - _("TUN connection"), - NULL, - NULL, - TRUE); - - s_tun = nm_connection_get_setting_tun (connection); - if (!s_tun) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'tun' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingTun *s_tun; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_TUN_SETTING_NAME, + existing_connections, + NULL, + _("TUN connection"), + NULL, + NULL, + TRUE); + + s_tun = nm_connection_get_setting_tun(connection); + if (!s_tun) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'tun' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceTun *self = NM_DEVICE_TUN (device); - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - NMSettingTun *s_tun; - NMSettingTunMode mode; - char s_buf[100]; - const char *str; - - /* Note: since we read tun properties from sysctl for older kernels, - * we don't get proper change notifications. Make sure that all our - * tun properties are up to date at this point. We should not do this, - * if we would entirely rely on netlink events. */ - update_properties (NM_DEVICE_TUN (device)); - - switch (priv->props.type) { - case IFF_TUN: mode = NM_SETTING_TUN_MODE_TUN; break; - case IFF_TAP: mode = NM_SETTING_TUN_MODE_TAP; break; - default: - /* Huh? */ - return; - } - - s_tun = nm_connection_get_setting_tun (connection); - if (!s_tun) { - s_tun = (NMSettingTun *) nm_setting_tun_new (); - nm_connection_add_setting (connection, (NMSetting *) s_tun); - } - - if (mode != nm_setting_tun_get_mode (s_tun)) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MODE, (guint) mode, NULL); - - str = priv->props.owner_valid - ? nm_sprintf_buf (s_buf, "%" G_GINT32_FORMAT, priv->props.owner) - : NULL; - if (!nm_streq0 (str, nm_setting_tun_get_owner (s_tun))) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_OWNER, str, NULL); - - str = priv->props.group_valid - ? nm_sprintf_buf (s_buf, "%" G_GINT32_FORMAT, priv->props.group) - : NULL; - if (!nm_streq0 (str, nm_setting_tun_get_group (s_tun))) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_GROUP, str, NULL); - - if (priv->props.pi != nm_setting_tun_get_pi (s_tun)) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_PI, (gboolean) priv->props.pi, NULL); - if (priv->props.vnet_hdr != nm_setting_tun_get_vnet_hdr (s_tun)) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_VNET_HDR, (gboolean) priv->props.vnet_hdr, NULL); - if (priv->props.multi_queue != nm_setting_tun_get_multi_queue (s_tun)) - g_object_set (G_OBJECT (s_tun), NM_SETTING_TUN_MULTI_QUEUE, (gboolean) priv->props.multi_queue, NULL); + NMDeviceTun * self = NM_DEVICE_TUN(device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(self); + NMSettingTun * s_tun; + NMSettingTunMode mode; + char s_buf[100]; + const char * str; + + /* Note: since we read tun properties from sysctl for older kernels, + * we don't get proper change notifications. Make sure that all our + * tun properties are up to date at this point. We should not do this, + * if we would entirely rely on netlink events. */ + update_properties(NM_DEVICE_TUN(device)); + + switch (priv->props.type) { + case IFF_TUN: + mode = NM_SETTING_TUN_MODE_TUN; + break; + case IFF_TAP: + mode = NM_SETTING_TUN_MODE_TAP; + break; + default: + /* Huh? */ + return; + } + + s_tun = nm_connection_get_setting_tun(connection); + if (!s_tun) { + s_tun = (NMSettingTun *) nm_setting_tun_new(); + nm_connection_add_setting(connection, (NMSetting *) s_tun); + } + + if (mode != nm_setting_tun_get_mode(s_tun)) + g_object_set(G_OBJECT(s_tun), NM_SETTING_TUN_MODE, (guint) mode, NULL); + + str = priv->props.owner_valid ? nm_sprintf_buf(s_buf, "%" G_GINT32_FORMAT, priv->props.owner) + : NULL; + if (!nm_streq0(str, nm_setting_tun_get_owner(s_tun))) + g_object_set(G_OBJECT(s_tun), NM_SETTING_TUN_OWNER, str, NULL); + + str = priv->props.group_valid ? nm_sprintf_buf(s_buf, "%" G_GINT32_FORMAT, priv->props.group) + : NULL; + if (!nm_streq0(str, nm_setting_tun_get_group(s_tun))) + g_object_set(G_OBJECT(s_tun), NM_SETTING_TUN_GROUP, str, NULL); + + if (priv->props.pi != nm_setting_tun_get_pi(s_tun)) + g_object_set(G_OBJECT(s_tun), NM_SETTING_TUN_PI, (gboolean) priv->props.pi, NULL); + if (priv->props.vnet_hdr != nm_setting_tun_get_vnet_hdr(s_tun)) + g_object_set(G_OBJECT(s_tun), + NM_SETTING_TUN_VNET_HDR, + (gboolean) priv->props.vnet_hdr, + NULL); + if (priv->props.multi_queue != nm_setting_tun_get_multi_queue(s_tun)) + g_object_set(G_OBJECT(s_tun), + NM_SETTING_TUN_MULTI_QUEUE, + (gboolean) priv->props.multi_queue, + NULL); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMPlatformLnkTun props = { }; - NMSettingTun *s_tun; - gint64 owner; - gint64 group; - int r; - - s_tun = nm_connection_get_setting_tun (connection); - g_return_val_if_fail (s_tun, FALSE); - - switch (nm_setting_tun_get_mode (s_tun)) { - case NM_SETTING_TUN_MODE_TAP: props.type = IFF_TAP; break; - case NM_SETTING_TUN_MODE_TUN: props.type = IFF_TUN; break; - default: - g_return_val_if_reached (FALSE); - } - - owner = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_owner (s_tun), 10, 0, G_MAXINT32, -1); - if (owner != -1) { - props.owner_valid = TRUE; - props.owner = owner; - } - group = _nm_utils_ascii_str_to_int64 (nm_setting_tun_get_group (s_tun), 10, 0, G_MAXINT32, -1); - if (group != -1) { - props.group_valid = TRUE; - props.group = group; - } - - props.pi = nm_setting_tun_get_pi (s_tun); - props.vnet_hdr = nm_setting_tun_get_vnet_hdr (s_tun); - props.multi_queue = nm_setting_tun_get_multi_queue (s_tun); - props.persist = TRUE; - - r = nm_platform_link_tun_add (nm_device_get_platform (device), - iface, - &props, - out_plink, - NULL); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create TUN/TAP interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMPlatformLnkTun props = {}; + NMSettingTun * s_tun; + gint64 owner; + gint64 group; + int r; + + s_tun = nm_connection_get_setting_tun(connection); + g_return_val_if_fail(s_tun, FALSE); + + switch (nm_setting_tun_get_mode(s_tun)) { + case NM_SETTING_TUN_MODE_TAP: + props.type = IFF_TAP; + break; + case NM_SETTING_TUN_MODE_TUN: + props.type = IFF_TUN; + break; + default: + g_return_val_if_reached(FALSE); + } + + owner = _nm_utils_ascii_str_to_int64(nm_setting_tun_get_owner(s_tun), 10, 0, G_MAXINT32, -1); + if (owner != -1) { + props.owner_valid = TRUE; + props.owner = owner; + } + group = _nm_utils_ascii_str_to_int64(nm_setting_tun_get_group(s_tun), 10, 0, G_MAXINT32, -1); + if (group != -1) { + props.group_valid = TRUE; + props.group = group; + } + + props.pi = nm_setting_tun_get_pi(s_tun); + props.vnet_hdr = nm_setting_tun_get_vnet_hdr(s_tun); + props.multi_queue = nm_setting_tun_get_multi_queue(s_tun); + props.persist = TRUE; + + r = nm_platform_link_tun_add(nm_device_get_platform(device), iface, &props, out_plink, NULL); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create TUN/TAP interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } static gboolean -_same_og (const char *str, gboolean og_valid, guint32 og_num) +_same_og(const char *str, gboolean og_valid, guint32 og_num) { - gint64 v; + gint64 v; - v = _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXINT32, -1); - return (!og_valid && ( v == (gint64) -1)) - || ( og_valid && (((guint32) v) == og_num )); + v = _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXINT32, -1); + return (!og_valid && (v == (gint64) -1)) || (og_valid && (((guint32) v) == og_num)); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceTun *self = NM_DEVICE_TUN (device); - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - NMSettingTunMode mode; - NMSettingTun *s_tun; - - if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (nm_device_is_real (device)) { - switch (priv->props.type) { - case IFF_TUN: mode = NM_SETTING_TUN_MODE_TUN; break; - case IFF_TAP: mode = NM_SETTING_TUN_MODE_TAP; break; - default: - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "invalid tun type on device"); - return FALSE; - } - - s_tun = nm_connection_get_setting_tun (connection); - - if (mode != nm_setting_tun_get_mode (s_tun)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun mode setting mismatches"); - return FALSE; - } - if (!_same_og (nm_setting_tun_get_owner (s_tun), priv->props.owner_valid, priv->props.owner)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun owner setting mismatches"); - return FALSE; - } - if (!_same_og (nm_setting_tun_get_group (s_tun), priv->props.group_valid, priv->props.group)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun group setting mismatches"); - return FALSE; - } - if (nm_setting_tun_get_pi (s_tun) != priv->props.pi) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun pi setting mismatches"); - return FALSE; - } - if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun vnet-hdr setting mismatches"); - return FALSE; - } - if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun multi-queue setting mismatches"); - return FALSE; - } - } - - return TRUE; + NMDeviceTun * self = NM_DEVICE_TUN(device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(self); + NMSettingTunMode mode; + NMSettingTun * s_tun; + + if (!NM_DEVICE_CLASS(nm_device_tun_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_device_is_real(device)) { + switch (priv->props.type) { + case IFF_TUN: + mode = NM_SETTING_TUN_MODE_TUN; + break; + case IFF_TAP: + mode = NM_SETTING_TUN_MODE_TAP; + break; + default: + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "invalid tun type on device"); + return FALSE; + } + + s_tun = nm_connection_get_setting_tun(connection); + + if (mode != nm_setting_tun_get_mode(s_tun)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun mode setting mismatches"); + return FALSE; + } + if (!_same_og(nm_setting_tun_get_owner(s_tun), + priv->props.owner_valid, + priv->props.owner)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun owner setting mismatches"); + return FALSE; + } + if (!_same_og(nm_setting_tun_get_group(s_tun), + priv->props.group_valid, + priv->props.group)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun group setting mismatches"); + return FALSE; + } + if (nm_setting_tun_get_pi(s_tun) != priv->props.pi) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun pi setting mismatches"); + return FALSE; + } + if (nm_setting_tun_get_vnet_hdr(s_tun) != priv->props.vnet_hdr) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun vnet-hdr setting mismatches"); + return FALSE; + } + if (nm_setting_tun_get_multi_queue(s_tun) != priv->props.multi_queue) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "tun multi-queue setting mismatches"); + return FALSE; + } + } + + return TRUE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceTun *self = NM_DEVICE_TUN (device); - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - - if (priv->props.type == IFF_TUN) { - /* Nothing to do for TUN devices */ - } else { - if (!nm_device_hw_addr_set_cloned (device, - nm_device_get_applied_connection (device), - FALSE)) { - *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceTun * self = NM_DEVICE_TUN(device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(self); + + if (priv->props.type == IFF_TUN) { + /* Nothing to do for TUN devices */ + } else { + if (!nm_device_hw_addr_set_cloned(device, + nm_device_get_applied_connection(device), + FALSE)) { + *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -unrealize_notify (NMDevice *device) +unrealize_notify(NMDevice *device) { - NM_DEVICE_CLASS (nm_device_tun_parent_class)->unrealize_notify (device); - update_properties_from_struct (NM_DEVICE_TUN (device), NULL); + NM_DEVICE_CLASS(nm_device_tun_parent_class)->unrealize_notify(device); + update_properties_from_struct(NM_DEVICE_TUN(device), NULL); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceTun *self = NM_DEVICE_TUN (object); - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - const char *s; - - switch (prop_id) { - case PROP_OWNER: - g_value_set_int64 (value, priv->props.owner_valid ? (gint64) priv->props.owner : (gint64) -1); - break; - case PROP_GROUP: - g_value_set_int64 (value, priv->props.group_valid ? (gint64) priv->props.group : (gint64) -1); - break; - case PROP_MODE: - switch (priv->props.type) { - case IFF_TUN: s = "tun"; break; - case IFF_TAP: s = "tap"; break; - default: s = NULL; break; - } - g_value_set_static_string (value, s); - break; - case PROP_NO_PI: - g_value_set_boolean (value, !priv->props.pi); - break; - case PROP_VNET_HDR: - g_value_set_boolean (value, priv->props.vnet_hdr); - break; - case PROP_MULTI_QUEUE: - g_value_set_boolean (value, priv->props.multi_queue); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceTun * self = NM_DEVICE_TUN(object); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE(self); + const char * s; + + switch (prop_id) { + case PROP_OWNER: + g_value_set_int64(value, + priv->props.owner_valid ? (gint64) priv->props.owner : (gint64) -1); + break; + case PROP_GROUP: + g_value_set_int64(value, + priv->props.group_valid ? (gint64) priv->props.group : (gint64) -1); + break; + case PROP_MODE: + switch (priv->props.type) { + case IFF_TUN: + s = "tun"; + break; + case IFF_TAP: + s = "tap"; + break; + default: + s = NULL; + break; + } + g_value_set_static_string(value, s); + break; + case PROP_NO_PI: + g_value_set_boolean(value, !priv->props.pi); + break; + case PROP_VNET_HDR: + g_value_set_boolean(value, priv->props.vnet_hdr); + break; + case PROP_MULTI_QUEUE: + g_value_set_boolean(value, priv->props.multi_queue); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_tun_init (NMDeviceTun *self) -{ -} +nm_device_tun_init(NMDeviceTun *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_tun = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_TUN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Owner", "x", NM_DEVICE_TUN_OWNER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Group", "x", NM_DEVICE_TUN_GROUP), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "s", NM_DEVICE_TUN_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NoPi", "b", NM_DEVICE_TUN_NO_PI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VnetHdr", "b", NM_DEVICE_TUN_VNET_HDR), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("MultiQueue", "b", NM_DEVICE_TUN_MULTI_QUEUE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_TUN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Owner", "x", NM_DEVICE_TUN_OWNER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Group", "x", NM_DEVICE_TUN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "s", NM_DEVICE_TUN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NoPi", "b", NM_DEVICE_TUN_NO_PI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("VnetHdr", + "b", + NM_DEVICE_TUN_VNET_HDR), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("MultiQueue", + "b", + NM_DEVICE_TUN_MULTI_QUEUE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_tun_class_init (NMDeviceTunClass *klass) +nm_device_tun_class_init(NMDeviceTunClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_tun); - - device_class->connection_type_supported = NM_SETTING_TUN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_TUN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_TUN); - - device_class->link_changed = link_changed; - device_class->complete_connection = complete_connection; - device_class->check_connection_compatible = check_connection_compatible; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->unrealize_notify = unrealize_notify; - device_class->update_connection = update_connection; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - - obj_properties[PROP_OWNER] = - g_param_spec_int64 (NM_DEVICE_TUN_OWNER, "", "", - -1, G_MAXUINT32, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_GROUP] = - g_param_spec_int64 (NM_DEVICE_TUN_GROUP, "", "", - -1, G_MAXUINT32, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MODE] = - g_param_spec_string (NM_DEVICE_TUN_MODE, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_NO_PI] = - g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_VNET_HDR] = - g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MULTI_QUEUE] = - g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, "", "", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_tun); + + device_class->connection_type_supported = NM_SETTING_TUN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_TUN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_TUN); + + device_class->link_changed = link_changed; + device_class->complete_connection = complete_connection; + device_class->check_connection_compatible = check_connection_compatible; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->unrealize_notify = unrealize_notify; + device_class->update_connection = update_connection; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + + obj_properties[PROP_OWNER] = g_param_spec_int64(NM_DEVICE_TUN_OWNER, + "", + "", + -1, + G_MAXUINT32, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_GROUP] = g_param_spec_int64(NM_DEVICE_TUN_GROUP, + "", + "", + -1, + G_MAXUINT32, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_TUN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_NO_PI] = g_param_spec_boolean(NM_DEVICE_TUN_NO_PI, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_VNET_HDR] = g_param_spec_boolean(NM_DEVICE_TUN_VNET_HDR, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MULTI_QUEUE] = + g_param_spec_boolean(NM_DEVICE_TUN_MULTI_QUEUE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_TUN_DEVICE_FACTORY (nm_tun_device_factory_get_type ()) -#define NM_TUN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TUN_DEVICE_FACTORY, NMTunDeviceFactory)) +#define NM_TYPE_TUN_DEVICE_FACTORY (nm_tun_device_factory_get_type()) +#define NM_TUN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_TUN_DEVICE_FACTORY, NMTunDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - g_return_val_if_fail (!plink || plink->type == NM_LINK_TYPE_TUN, NULL); - g_return_val_if_fail (!connection || nm_streq0 (nm_connection_get_connection_type (connection), NM_SETTING_TUN_SETTING_NAME), NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Tun", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TUN, - NM_DEVICE_LINK_TYPE, (guint) NM_LINK_TYPE_TUN, - NULL); + g_return_val_if_fail(!plink || plink->type == NM_LINK_TYPE_TUN, NULL); + g_return_val_if_fail(!connection + || nm_streq0(nm_connection_get_connection_type(connection), + NM_SETTING_TUN_SETTING_NAME), + NULL); + + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_TUN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Tun", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_TUN, + NM_DEVICE_LINK_TYPE, + (guint) NM_LINK_TYPE_TUN, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (TUN, Tun, tun, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_TUN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_TUN_SETTING_NAME), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + TUN, + Tun, + tun, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_TUN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_TUN_SETTING_NAME), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-tun.h b/src/devices/nm-device-tun.h index 2f87d3bc..32d515c1 100644 --- a/src/devices/nm-device-tun.h +++ b/src/devices/nm-device-tun.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -8,12 +8,14 @@ #include "nm-device-generic.h" -#define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type ()) -#define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) -#define NM_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) -#define NM_IS_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TUN)) -#define NM_IS_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TUN)) -#define NM_DEVICE_TUN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) +#define NM_TYPE_DEVICE_TUN (nm_device_tun_get_type()) +#define NM_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_TUN, NMDeviceTun)) +#define NM_DEVICE_TUN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) +#define NM_IS_DEVICE_TUN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_TUN)) +#define NM_IS_DEVICE_TUN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_TUN)) +#define NM_DEVICE_TUN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_TUN, NMDeviceTunClass)) #define NM_DEVICE_TUN_OWNER "owner" #define NM_DEVICE_TUN_GROUP "group" @@ -22,9 +24,9 @@ #define NM_DEVICE_TUN_VNET_HDR "vnet-hdr" #define NM_DEVICE_TUN_MULTI_QUEUE "multi-queue" -typedef struct _NMDeviceTun NMDeviceTun; +typedef struct _NMDeviceTun NMDeviceTun; typedef struct _NMDeviceTunClass NMDeviceTunClass; -GType nm_device_tun_get_type (void); +GType nm_device_tun_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_TUN_H__ */ diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 5c26a036..f61bc99f 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -19,164 +19,160 @@ _LOG_DECLARE_SELF(NMDeviceVeth); /*****************************************************************************/ struct _NMDeviceVeth { - NMDeviceEthernet parent; + NMDeviceEthernet parent; }; struct _NMDeviceVethClass { - NMDeviceEthernetClass parent; + NMDeviceEthernetClass parent; }; -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVeth, - PROP_PEER, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceVeth, PROP_PEER, ); /*****************************************************************************/ -G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) +G_DEFINE_TYPE(NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) /*****************************************************************************/ static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDevice *peer; - int ifindex, peer_ifindex; + NMDevice *peer; + int ifindex, peer_ifindex; - ifindex = nm_device_get_ifindex (device); + ifindex = nm_device_get_ifindex(device); - if (!nm_platform_link_veth_get_properties (nm_device_get_platform (device), ifindex, &peer_ifindex)) - peer_ifindex = 0; + if (!nm_platform_link_veth_get_properties(nm_device_get_platform(device), + ifindex, + &peer_ifindex)) + peer_ifindex = 0; - nm_device_parent_set_ifindex (device, peer_ifindex); + nm_device_parent_set_ifindex(device, peer_ifindex); - peer = nm_device_parent_get_device (device); - if ( peer - && NM_IS_DEVICE_VETH (peer) - && nm_device_parent_get_ifindex (peer) <= 0) - update_properties (peer); + peer = nm_device_parent_get_device(device); + if (peer && NM_IS_DEVICE_VETH(peer) && nm_device_parent_get_ifindex(peer) <= 0) + update_properties(peer); } static gboolean -can_unmanaged_external_down (NMDevice *self) +can_unmanaged_external_down(NMDevice *self) { - /* Unless running in a container, an udev rule causes these to be - * unmanaged. If there's no udev then we're probably in a container - * and should IFF_UP and configure the veth ourselves even if we - * didn't create it. */ - return FALSE; + /* Unless running in a container, an udev rule causes these to be + * unmanaged. If there's no udev then we're probably in a container + * and should IFF_UP and configure the veth ourselves even if we + * didn't create it. */ + return FALSE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_veth_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_veth_parent_class)->link_changed(device, pllink); + update_properties(device); } /*****************************************************************************/ static void -nm_device_veth_init (NMDeviceVeth *self) -{ -} +nm_device_veth_init(NMDeviceVeth *self) +{} static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *device, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - NM_DEVICE_CLASS (nm_device_veth_parent_class)->parent_changed_notify (device, - old_ifindex, - old_parent, - new_ifindex, - new_parent); - _notify (NM_DEVICE_VETH (device), PROP_PEER); + NM_DEVICE_CLASS(nm_device_veth_parent_class) + ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent); + _notify(NM_DEVICE_VETH(device), PROP_PEER); } static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceVeth *self = NM_DEVICE_VETH (object); - NMDevice *peer; - - switch (prop_id) { - case PROP_PEER: - peer = nm_device_parent_get_device (NM_DEVICE (self)); - if (peer && !NM_IS_DEVICE_VETH (peer)) - peer = NULL; - nm_dbus_utils_g_value_set_object_path (value, peer); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceVeth *self = NM_DEVICE_VETH(object); + NMDevice * peer; + + switch (prop_id) { + case PROP_PEER: + peer = nm_device_parent_get_device(NM_DEVICE(self)); + if (peer && !NM_IS_DEVICE_VETH(peer)) + peer = NULL; + nm_dbus_utils_g_value_set_object_path(value, peer); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static const NMDBusInterfaceInfoExtended interface_info_device_veth = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_VETH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Peer", "o", NM_DEVICE_VETH_PEER), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_VETH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Peer", + "o", + NM_DEVICE_VETH_PEER), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_veth_class_init (NMDeviceVethClass *klass) +nm_device_veth_class_init(NMDeviceVethClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - object_class->get_property = get_property; + object_class->get_property = get_property; - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_veth); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_veth); - device_class->connection_type_supported = NULL; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VETH); + device_class->connection_type_supported = NULL; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_VETH); - device_class->can_unmanaged_external_down = can_unmanaged_external_down; - device_class->link_changed = link_changed; - device_class->parent_changed_notify = parent_changed_notify; + device_class->can_unmanaged_external_down = can_unmanaged_external_down; + device_class->link_changed = link_changed; + device_class->parent_changed_notify = parent_changed_notify; - obj_properties[PROP_PEER] = - g_param_spec_string (NM_DEVICE_VETH_PEER, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PEER] = g_param_spec_string(NM_DEVICE_VETH_PEER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_VETH_DEVICE_FACTORY (nm_veth_device_factory_get_type ()) -#define NM_VETH_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VETH_DEVICE_FACTORY, NMVethDeviceFactory)) +#define NM_TYPE_VETH_DEVICE_FACTORY (nm_veth_device_factory_get_type()) +#define NM_VETH_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VETH_DEVICE_FACTORY, NMVethDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Veth", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VETH, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VETH, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_VETH, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Veth", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_VETH, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_VETH, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (VETH, Veth, veth, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VETH), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL(VETH, + Veth, + veth, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VETH), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-veth.h b/src/devices/nm-device-veth.h index 15da6ab8..e3867446 100644 --- a/src/devices/nm-device-veth.h +++ b/src/devices/nm-device-veth.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Red Hat, Inc. */ @@ -8,18 +8,20 @@ #include "nm-device-ethernet.h" -#define NM_TYPE_DEVICE_VETH (nm_device_veth_get_type ()) -#define NM_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VETH, NMDeviceVeth)) -#define NM_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) -#define NM_IS_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VETH)) -#define NM_IS_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VETH)) -#define NM_DEVICE_VETH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) +#define NM_TYPE_DEVICE_VETH (nm_device_veth_get_type()) +#define NM_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VETH, NMDeviceVeth)) +#define NM_DEVICE_VETH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) +#define NM_IS_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VETH)) +#define NM_IS_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VETH)) +#define NM_DEVICE_VETH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) #define NM_DEVICE_VETH_PEER "peer" -typedef struct _NMDeviceVeth NMDeviceVeth; +typedef struct _NMDeviceVeth NMDeviceVeth; typedef struct _NMDeviceVethClass NMDeviceVethClass; -GType nm_device_veth_get_type (void); +GType nm_device_veth_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_VETH_H__ */ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 183e9eff..bb6fdc05 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 - 2012 Red Hat, Inc. */ @@ -27,638 +27,662 @@ _LOG_DECLARE_SELF(NMDeviceVlan); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVlan, - PROP_VLAN_ID, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceVlan, PROP_VLAN_ID, ); typedef struct { - gulong parent_state_id; - gulong parent_hwaddr_id; - gulong parent_mtu_id; - guint vlan_id; + gulong parent_state_id; + gulong parent_hwaddr_id; + gulong parent_mtu_id; + guint vlan_id; } NMDeviceVlanPrivate; struct _NMDeviceVlan { - NMDevice parent; - NMDeviceVlanPrivate _priv; + NMDevice parent; + NMDeviceVlanPrivate _priv; }; struct _NMDeviceVlanClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) -#define NM_DEVICE_VLAN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceVlan, NM_IS_DEVICE_VLAN, NMDevice) +#define NM_DEVICE_VLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVlan, NM_IS_DEVICE_VLAN, NMDevice) /*****************************************************************************/ static void -parent_state_changed (NMDevice *parent, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) +parent_state_changed(NMDevice * parent, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) { - NMDeviceVlan *self = NM_DEVICE_VLAN (user_data); + NMDeviceVlan *self = NM_DEVICE_VLAN(user_data); - /* We'll react to our own carrier state notifications. Ignore the parent's. */ - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CARRIER) - return; + /* We'll react to our own carrier state notifications. Ignore the parent's. */ + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_CARRIER) + return; - nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); + nm_device_set_unmanaged_by_flags(NM_DEVICE(self), + NM_UNMANAGED_PARENT, + !nm_device_get_managed(parent, FALSE), + reason); } static void -parent_mtu_maybe_changed (NMDevice *parent, - GParamSpec *pspec, - gpointer user_data) +parent_mtu_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_data) { - /* the MTU of a VLAN device is limited by the parent's MTU. - * - * When the parent's MTU changes, try to re-set the MTU. */ - nm_device_commit_mtu (user_data); + /* the MTU of a VLAN device is limited by the parent's MTU. + * + * When the parent's MTU changes, try to re-set the MTU. */ + nm_device_commit_mtu(user_data); } static void -parent_hwaddr_maybe_changed (NMDevice *parent, - GParamSpec *pspec, - gpointer user_data) +parent_hwaddr_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceVlan *self = NM_DEVICE_VLAN (device); - NMConnection *connection; - const char *new_mac, *old_mac; - NMSettingIPConfig *s_ip6; - - /* Never touch assumed devices */ - if (nm_device_sys_iface_state_is_external_or_assume (device)) - return; - - connection = nm_device_get_applied_connection (device); - if (!connection) - return; - - /* Update the VLAN MAC only if configuration does not specify one */ - if (nm_device_hw_addr_is_explict (device)) - return; - - old_mac = nm_device_get_hw_address (device); - new_mac = nm_device_get_hw_address (parent); - if (nm_streq0 (old_mac, new_mac)) - return; - - _LOGD (LOGD_VLAN, "parent hardware address changed to %s%s%s", - NM_PRINT_FMT_QUOTE_STRING (new_mac)); - if (new_mac) { - nm_device_hw_addr_set (device, new_mac, "vlan-parent", TRUE); - nm_device_arp_announce (device); - /* When changing the hw address the interface is taken down, - * removing the IPv6 configuration; reapply it. - */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6) - nm_device_reactivate_ip6_config (device, s_ip6, s_ip6); - } + NMDevice * device = NM_DEVICE(user_data); + NMDeviceVlan * self = NM_DEVICE_VLAN(device); + NMConnection * connection; + const char * new_mac, *old_mac; + NMSettingIPConfig *s_ip6; + + /* Never touch assumed devices */ + if (nm_device_sys_iface_state_is_external_or_assume(device)) + return; + + connection = nm_device_get_applied_connection(device); + if (!connection) + return; + + /* Update the VLAN MAC only if configuration does not specify one */ + if (nm_device_hw_addr_is_explict(device)) + return; + + old_mac = nm_device_get_hw_address(device); + new_mac = nm_device_get_hw_address(parent); + if (nm_streq0(old_mac, new_mac)) + return; + + _LOGD(LOGD_VLAN, + "parent hardware address changed to %s%s%s", + NM_PRINT_FMT_QUOTE_STRING(new_mac)); + if (new_mac) { + nm_device_hw_addr_set(device, new_mac, "vlan-parent", TRUE); + nm_device_arp_announce(device); + /* When changing the hw address the interface is taken down, + * removing the IPv6 configuration; reapply it. + */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (s_ip6) + nm_device_reactivate_ip6_config(device, s_ip6, s_ip6); + } } static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *device, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - NMDeviceVlan *self = NM_DEVICE_VLAN (device); - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); - - NM_DEVICE_CLASS (nm_device_vlan_parent_class)->parent_changed_notify (device, old_ifindex, old_parent, new_ifindex, new_parent); - - /* note that @self doesn't have to clear @parent_state_id on dispose, - * because NMDevice's dispose() will unset the parent, which in turn calls - * parent_changed_notify(). */ - nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); - nm_clear_g_signal_handler (old_parent, &priv->parent_hwaddr_id); - nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id); - - if (new_parent) { - priv->parent_state_id = g_signal_connect (new_parent, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (parent_state_changed), - device); - - priv->parent_hwaddr_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_HW_ADDRESS, - G_CALLBACK (parent_hwaddr_maybe_changed), device); - parent_hwaddr_maybe_changed (new_parent, NULL, self); - - priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU, - G_CALLBACK (parent_mtu_maybe_changed), device); - parent_mtu_maybe_changed (new_parent, NULL, self); - - /* Set parent-dependent unmanaged flag */ - nm_device_set_unmanaged_by_flags (device, - NM_UNMANAGED_PARENT, - !nm_device_get_managed (new_parent, FALSE), - NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); - } - - /* Recheck availability now that the parent has changed */ - if (new_ifindex > 0) { - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_PARENT_CHANGED, - NM_DEVICE_STATE_REASON_PARENT_CHANGED); - } + NMDeviceVlan * self = NM_DEVICE_VLAN(device); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE(self); + + NM_DEVICE_CLASS(nm_device_vlan_parent_class) + ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent); + + /* note that @self doesn't have to clear @parent_state_id on dispose, + * because NMDevice's dispose() will unset the parent, which in turn calls + * parent_changed_notify(). */ + nm_clear_g_signal_handler(old_parent, &priv->parent_state_id); + nm_clear_g_signal_handler(old_parent, &priv->parent_hwaddr_id); + nm_clear_g_signal_handler(old_parent, &priv->parent_mtu_id); + + if (new_parent) { + priv->parent_state_id = g_signal_connect(new_parent, + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(parent_state_changed), + device); + + priv->parent_hwaddr_id = g_signal_connect(new_parent, + "notify::" NM_DEVICE_HW_ADDRESS, + G_CALLBACK(parent_hwaddr_maybe_changed), + device); + parent_hwaddr_maybe_changed(new_parent, NULL, self); + + priv->parent_mtu_id = g_signal_connect(new_parent, + "notify::" NM_DEVICE_MTU, + G_CALLBACK(parent_mtu_maybe_changed), + device); + parent_mtu_maybe_changed(new_parent, NULL, self); + + /* Set parent-dependent unmanaged flag */ + nm_device_set_unmanaged_by_flags(device, + NM_UNMANAGED_PARENT, + !nm_device_get_managed(new_parent, FALSE), + NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); + } + + /* Recheck availability now that the parent has changed */ + if (new_ifindex > 0) { + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_PARENT_CHANGED, + NM_DEVICE_STATE_REASON_PARENT_CHANGED); + } } static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceVlanPrivate *priv; - const NMPlatformLink *plink = NULL; - const NMPlatformLnkVlan *plnk = NULL; - int ifindex; - int parent_ifindex = 0; - guint vlan_id; + NMDeviceVlanPrivate * priv; + const NMPlatformLink * plink = NULL; + const NMPlatformLnkVlan *plnk = NULL; + int ifindex; + int parent_ifindex = 0; + guint vlan_id; - g_return_if_fail (NM_IS_DEVICE_VLAN (device)); + g_return_if_fail(NM_IS_DEVICE_VLAN(device)); - priv = NM_DEVICE_VLAN_GET_PRIVATE (device); + priv = NM_DEVICE_VLAN_GET_PRIVATE(device); - ifindex = nm_device_get_ifindex (device); + ifindex = nm_device_get_ifindex(device); - if (ifindex > 0) - plnk = nm_platform_link_get_lnk_vlan (nm_device_get_platform (device), ifindex, &plink); + if (ifindex > 0) + plnk = nm_platform_link_get_lnk_vlan(nm_device_get_platform(device), ifindex, &plink); - if ( plnk - && plink->parent > 0) - parent_ifindex = plink->parent; + if (plnk && plink->parent > 0) + parent_ifindex = plink->parent; - g_object_freeze_notify ((GObject *) device); + g_object_freeze_notify((GObject *) device); - nm_device_parent_set_ifindex (device, parent_ifindex); + nm_device_parent_set_ifindex(device, parent_ifindex); - vlan_id = plnk ? plnk->id : 0; - if (vlan_id != priv->vlan_id) { - priv->vlan_id = vlan_id; - _notify ((NMDeviceVlan *) device, PROP_VLAN_ID); - } + vlan_id = plnk ? plnk->id : 0; + if (vlan_id != priv->vlan_id) { + priv->vlan_id = vlan_id; + _notify((NMDeviceVlan *) device, PROP_VLAN_ID); + } - g_object_thaw_notify ((GObject *) device); + g_object_thaw_notify((GObject *) device); } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_vlan_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_vlan_parent_class)->link_changed(device, pllink); + update_properties(device); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); - NMSettingVlan *s_vlan; - int parent_ifindex; - guint vlan_id; - int r; - - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); - - if (!parent) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "VLAN devices can not be created without a parent interface"); - return FALSE; - } - - parent_ifindex = nm_device_get_ifindex (parent); - if (parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "cannot retrieve ifindex of interface %s (%s)", - nm_device_get_iface (parent), - nm_device_get_type_desc (parent)); - return FALSE; - } - - if (!nm_device_supports_vlans (parent)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "no support for VLANs on interface %s of type %s", - nm_device_get_iface (parent), - nm_device_get_type_desc (parent)); - return FALSE; - } - - vlan_id = nm_setting_vlan_get_id (s_vlan); - - r = nm_platform_link_vlan_add (nm_device_get_platform (device), - iface, - parent_ifindex, - vlan_id, - nm_setting_vlan_get_flags (s_vlan), - out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create VLAN interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - nm_device_parent_set_ifindex (device, parent_ifindex); - if (vlan_id != priv->vlan_id) { - priv->vlan_id = vlan_id; - _notify ((NMDeviceVlan *) device, PROP_VLAN_ID); - } - - return TRUE; + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE(device); + const char * iface = nm_device_get_iface(device); + NMSettingVlan * s_vlan; + int parent_ifindex; + guint vlan_id; + int r; + + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); + + if (!parent) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "VLAN devices can not be created without a parent interface"); + return FALSE; + } + + parent_ifindex = nm_device_get_ifindex(parent); + if (parent_ifindex <= 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "cannot retrieve ifindex of interface %s (%s)", + nm_device_get_iface(parent), + nm_device_get_type_desc(parent)); + return FALSE; + } + + if (!nm_device_supports_vlans(parent)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "no support for VLANs on interface %s of type %s", + nm_device_get_iface(parent), + nm_device_get_type_desc(parent)); + return FALSE; + } + + vlan_id = nm_setting_vlan_get_id(s_vlan); + + r = nm_platform_link_vlan_add(nm_device_get_platform(device), + iface, + parent_ifindex, + vlan_id, + nm_setting_vlan_get_flags(s_vlan), + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create VLAN interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + nm_device_parent_set_ifindex(device, parent_ifindex); + if (vlan_id != priv->vlan_id) { + priv->vlan_id = vlan_id; + _notify((NMDeviceVlan *) device, PROP_VLAN_ID); + } + + return TRUE; } static void -unrealize_notify (NMDevice *device) +unrealize_notify(NMDevice *device) { - NMDeviceVlan *self = NM_DEVICE_VLAN (device); - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + NMDeviceVlan * self = NM_DEVICE_VLAN(device); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE(self); - NM_DEVICE_CLASS (nm_device_vlan_parent_class)->unrealize_notify (device); + NM_DEVICE_CLASS(nm_device_vlan_parent_class)->unrealize_notify(device); - if (priv->vlan_id != 0) { - priv->vlan_id = 0; - _notify (self, PROP_VLAN_ID); - } + if (priv->vlan_id != 0) { + priv->vlan_id = 0; + _notify(self, PROP_VLAN_ID); + } } /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - /* We assume VLAN interfaces always support carrier detect */ - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + /* We assume VLAN interfaces always support carrier detect */ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } /*****************************************************************************/ static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - if (!nm_device_parent_get_device (device)) - return FALSE; - return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->is_available (device, flags); + if (!nm_device_parent_get_device(device)) + return FALSE; + return NM_DEVICE_CLASS(nm_device_vlan_parent_class)->is_available(device, flags); } /*****************************************************************************/ static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); - NMSettingVlan *s_vlan; - const char *parent; - - if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (nm_device_is_real (device)) { - s_vlan = nm_connection_get_setting_vlan (connection); - - if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan id setting mismatches"); - return FALSE; - } - - /* Check parent interface; could be an interface name or a UUID */ - parent = nm_setting_vlan_get_parent (s_vlan); - if (parent) { - if (!nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan parent setting differs"); - return FALSE; - } - } else { - /* Parent could be a MAC address in an NMSettingWired */ - if (!nm_device_match_parent_hwaddr (device, connection, TRUE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan parent mac setting differs"); - return FALSE; - } - } - } - - return TRUE; + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE(device); + NMSettingVlan * s_vlan; + const char * parent; + + if (!NM_DEVICE_CLASS(nm_device_vlan_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_device_is_real(device)) { + s_vlan = nm_connection_get_setting_vlan(connection); + + if (nm_setting_vlan_get_id(s_vlan) != priv->vlan_id) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vlan id setting mismatches"); + return FALSE; + } + + /* Check parent interface; could be an interface name or a UUID */ + parent = nm_setting_vlan_get_parent(s_vlan); + if (parent) { + if (!nm_device_match_parent(device, parent)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vlan parent setting differs"); + return FALSE; + } + } else { + /* Parent could be a MAC address in an NMSettingWired */ + if (!nm_device_match_parent_hwaddr(device, connection, TRUE)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vlan parent mac setting differs"); + return FALSE; + } + } + } + + return TRUE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) { - if (!nm_device_is_real (device)) - return TRUE; + if (!nm_device_is_real(device)) + return TRUE; - return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_available (device, connection, flags, specific_object, error); + return NM_DEVICE_CLASS(nm_device_vlan_parent_class) + ->check_connection_available(device, connection, flags, specific_object, error); } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingVlan *s_vlan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_VLAN_SETTING_NAME, - existing_connections, - NULL, - _("VLAN connection"), - NULL, - NULL, - TRUE); - - s_vlan = nm_connection_get_setting_vlan (connection); - if (!s_vlan) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'vlan' setting is required."); - return FALSE; - } - - /* If there's no VLAN interface, no parent, and no hardware address in the - * settings, then there's not enough information to complete the setting. - */ - if ( !nm_setting_vlan_get_parent (s_vlan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "The 'vlan' setting had no interface name, parent, or hardware address."); - return FALSE; - } - - return TRUE; + NMSettingVlan *s_vlan; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_VLAN_SETTING_NAME, + existing_connections, + NULL, + _("VLAN connection"), + NULL, + NULL, + TRUE); + + s_vlan = nm_connection_get_setting_vlan(connection); + if (!s_vlan) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'vlan' setting is required."); + return FALSE; + } + + /* If there's no VLAN interface, no parent, and no hardware address in the + * settings, then there's not enough information to complete the setting. + */ + if (!nm_setting_vlan_get_parent(s_vlan) + && !nm_device_match_parent_hwaddr(device, connection, TRUE)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "The 'vlan' setting had no interface name, parent, or hardware address."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); - NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); - int ifindex = nm_device_get_ifindex (device); - const NMPlatformLink *plink; - const NMPObject *polnk; - guint vlan_id; - guint vlan_flags; - - if (!s_vlan) { - s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); - nm_connection_add_setting (connection, (NMSetting *) s_vlan); - } - - polnk = nm_platform_link_get_lnk (nm_device_get_platform (device), ifindex, NM_LINK_TYPE_VLAN, &plink); - - if (polnk) - vlan_id = polnk->lnk_vlan.id; - else - vlan_id = priv->vlan_id; - if (vlan_id != nm_setting_vlan_get_id (s_vlan)) - g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); - - g_object_set (s_vlan, - NM_SETTING_VLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_vlan_get_parent (s_vlan)), - NULL); - - if (polnk) - vlan_flags = polnk->lnk_vlan.flags; - else - vlan_flags = NM_VLAN_FLAG_REORDER_HEADERS; - if (vlan_flags != nm_setting_vlan_get_flags (s_vlan)) - g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, (NMVlanFlags) vlan_flags, NULL); - - if (polnk) { - _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_INGRESS_MAP, - polnk->_lnk_vlan.ingress_qos_map, - polnk->_lnk_vlan.n_ingress_qos_map); - _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_EGRESS_MAP, - polnk->_lnk_vlan.egress_qos_map, - polnk->_lnk_vlan.n_egress_qos_map); - } else { - _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_INGRESS_MAP, NULL, 0); - _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_EGRESS_MAP, NULL, 0); - } + NMDeviceVlanPrivate * priv = NM_DEVICE_VLAN_GET_PRIVATE(device); + NMSettingVlan * s_vlan = nm_connection_get_setting_vlan(connection); + int ifindex = nm_device_get_ifindex(device); + const NMPlatformLink *plink; + const NMPObject * polnk; + guint vlan_id; + guint vlan_flags; + + if (!s_vlan) { + s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); + nm_connection_add_setting(connection, (NMSetting *) s_vlan); + } + + polnk = nm_platform_link_get_lnk(nm_device_get_platform(device), + ifindex, + NM_LINK_TYPE_VLAN, + &plink); + + if (polnk) + vlan_id = polnk->lnk_vlan.id; + else + vlan_id = priv->vlan_id; + if (vlan_id != nm_setting_vlan_get_id(s_vlan)) + g_object_set(s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); + + g_object_set(s_vlan, + NM_SETTING_VLAN_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_vlan_get_parent(s_vlan)), + NULL); + + if (polnk) + vlan_flags = polnk->lnk_vlan.flags; + else + vlan_flags = NM_VLAN_FLAG_REORDER_HEADERS; + if (vlan_flags != nm_setting_vlan_get_flags(s_vlan)) + g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, (NMVlanFlags) vlan_flags, NULL); + + if (polnk) { + _nm_setting_vlan_set_priorities(s_vlan, + NM_VLAN_INGRESS_MAP, + polnk->_lnk_vlan.ingress_qos_map, + polnk->_lnk_vlan.n_ingress_qos_map); + _nm_setting_vlan_set_priorities(s_vlan, + NM_VLAN_EGRESS_MAP, + polnk->_lnk_vlan.egress_qos_map, + polnk->_lnk_vlan.n_egress_qos_map); + } else { + _nm_setting_vlan_set_priorities(s_vlan, NM_VLAN_INGRESS_MAP, NULL, 0); + _nm_setting_vlan_set_priorities(s_vlan, NM_VLAN_EGRESS_MAP, NULL, 0); + } } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDevice *parent_device; - NMSettingVlan *s_vlan; - - /* Change MAC address to parent's one if needed */ - parent_device = nm_device_parent_get_device (device); - if (parent_device) { - parent_hwaddr_maybe_changed (parent_device, NULL, device); - parent_mtu_maybe_changed (parent_device, NULL, device); - } - - s_vlan = nm_device_get_applied_setting (device, NM_TYPE_SETTING_VLAN); - if (s_vlan) { - gs_free NMVlanQosMapping *ingress_map = NULL; - gs_free NMVlanQosMapping *egress_map = NULL; - guint n_ingress_map = 0; - guint n_egress_map = 0; - - _nm_setting_vlan_get_priorities (s_vlan, - NM_VLAN_INGRESS_MAP, - &ingress_map, - &n_ingress_map); - _nm_setting_vlan_get_priorities (s_vlan, - NM_VLAN_EGRESS_MAP, - &egress_map, - &n_egress_map); - - nm_platform_link_vlan_change (nm_device_get_platform (device), - nm_device_get_ifindex (device), - NM_VLAN_FLAGS_ALL, - nm_setting_vlan_get_flags (s_vlan), - TRUE, - ingress_map, - n_ingress_map, - TRUE, - egress_map, - n_egress_map); - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDevice * parent_device; + NMSettingVlan *s_vlan; + + /* Change MAC address to parent's one if needed */ + parent_device = nm_device_parent_get_device(device); + if (parent_device) { + parent_hwaddr_maybe_changed(parent_device, NULL, device); + parent_mtu_maybe_changed(parent_device, NULL, device); + } + + s_vlan = nm_device_get_applied_setting(device, NM_TYPE_SETTING_VLAN); + if (s_vlan) { + gs_free NMVlanQosMapping *ingress_map = NULL; + gs_free NMVlanQosMapping *egress_map = NULL; + guint n_ingress_map = 0; + guint n_egress_map = 0; + + _nm_setting_vlan_get_priorities(s_vlan, NM_VLAN_INGRESS_MAP, &ingress_map, &n_ingress_map); + _nm_setting_vlan_get_priorities(s_vlan, NM_VLAN_EGRESS_MAP, &egress_map, &n_egress_map); + + nm_platform_link_vlan_change(nm_device_get_platform(device), + nm_device_get_ifindex(device), + NM_VLAN_FLAGS_ALL, + nm_setting_vlan_get_flags(s_vlan), + TRUE, + ingress_map, + n_ingress_map, + TRUE, + egress_map, + n_egress_map); + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_VLAN_ID: - g_value_set_uint (value, priv->vlan_id); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_VLAN_ID: + g_value_set_uint(value, priv->vlan_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_vlan_init (NMDeviceVlan * self) -{ -} +nm_device_vlan_init(NMDeviceVlan *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_vlan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_VLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VlanId", "u", NM_DEVICE_VLAN_ID), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_VLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("VlanId", + "u", + NM_DEVICE_VLAN_ID), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_vlan_class_init (NMDeviceVlanClass *klass) +nm_device_vlan_class_init(NMDeviceVlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vlan); - - device_class->connection_type_supported = NM_SETTING_VLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_VLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VLAN); - device_class->mtu_parent_delta = 0; /* VLANs can have the same MTU of parent */ - - device_class->create_and_realize = create_and_realize; - device_class->link_changed = link_changed; - device_class->unrealize_notify = unrealize_notify; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - - obj_properties[PROP_VLAN_ID] = - g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "", - 0, 4095, 0, - G_PARAM_READABLE - | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_vlan); + + device_class->connection_type_supported = NM_SETTING_VLAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_VLAN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_VLAN); + device_class->mtu_parent_delta = 0; /* VLANs can have the same MTU of parent */ + + device_class->create_and_realize = create_and_realize; + device_class->link_changed = link_changed; + device_class->unrealize_notify = unrealize_notify; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; + device_class->is_available = is_available; + device_class->parent_changed_notify = parent_changed_notify; + + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + device_class->update_connection = update_connection; + + obj_properties[PROP_VLAN_ID] = g_param_spec_uint(NM_DEVICE_VLAN_ID, + "", + "", + 0, + 4095, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_VLAN_DEVICE_FACTORY (nm_vlan_device_factory_get_type ()) -#define NM_VLAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VLAN_DEVICE_FACTORY, NMVlanDeviceFactory)) +#define NM_TYPE_VLAN_DEVICE_FACTORY (nm_vlan_device_factory_get_type()) +#define NM_VLAN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VLAN_DEVICE_FACTORY, NMVlanDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "8021q", - NM_DEVICE_TYPE_DESC, "VLAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VLAN, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_VLAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_DRIVER, + "8021q", + NM_DEVICE_TYPE_DESC, + "VLAN", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_VLAN, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_VLAN, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingVlan *s_vlan; - NMSettingWired *s_wired; - const char *parent = NULL; + NMSettingVlan * s_vlan; + NMSettingWired *s_wired; + const char * parent = NULL; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VLAN_SETTING_NAME), NULL); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - parent = nm_setting_vlan_get_parent (s_vlan); - if (parent) - return parent; + parent = nm_setting_vlan_get_parent(s_vlan); + if (parent) + return parent; - /* Try the hardware address from the VLAN connection's hardware setting */ - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) - return nm_setting_wired_get_mac_address (s_wired); + /* Try the hardware address from the VLAN connection's hardware setting */ + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + return nm_setting_wired_get_mac_address(s_wired); - return NULL; + return NULL; } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - const char *ifname; - NMSettingVlan *s_vlan; + const char * ifname; + NMSettingVlan *s_vlan; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VLAN_SETTING_NAME), NULL); - s_vlan = nm_connection_get_setting_vlan (connection); - g_assert (s_vlan); + s_vlan = nm_connection_get_setting_vlan(connection); + g_assert(s_vlan); - if (!parent_iface) - return NULL; + if (!parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); - if (ifname) - return g_strdup (ifname); + ifname = nm_connection_get_interface_name(connection); + if (ifname) + return g_strdup(ifname); - /* If the connection doesn't specify the interface name for the VLAN - * device, we create one for it using the VLAN ID and the parent - * interface's name. - */ - return nm_utils_new_vlan_name (parent_iface, nm_setting_vlan_get_id (s_vlan)); + /* If the connection doesn't specify the interface name for the VLAN + * device, we create one for it using the VLAN ID and the parent + * interface's name. + */ + return nm_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (VLAN, Vlan, vlan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VLAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VLAN_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + VLAN, + Vlan, + vlan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VLAN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_VLAN_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h index a5d50a4a..5bf11cd9 100644 --- a/src/devices/nm-device-vlan.h +++ b/src/devices/nm-device-vlan.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 Red Hat, Inc. */ @@ -8,24 +8,26 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type ()) -#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) -#define NM_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) -#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VLAN)) -#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VLAN)) -#define NM_DEVICE_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) +#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type()) +#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) +#define NM_DEVICE_VLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) +#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VLAN)) +#define NM_DEVICE_VLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) typedef enum { - NM_VLAN_ERROR_CONNECTION_NOT_VLAN = 0, /*< nick=ConnectionNotVlan >*/ - NM_VLAN_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_VLAN_ERROR_CONNECTION_NOT_VLAN = 0, /*< nick=ConnectionNotVlan >*/ + NM_VLAN_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ } NMVlanError; -#define NM_DEVICE_VLAN_ID "vlan-id" +#define NM_DEVICE_VLAN_ID "vlan-id" -typedef struct _NMDeviceVlan NMDeviceVlan; +typedef struct _NMDeviceVlan NMDeviceVlan; typedef struct _NMDeviceVlanClass NMDeviceVlanClass; -GType nm_device_vlan_get_type (void); +GType nm_device_vlan_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_VLAN_H__ */ diff --git a/src/devices/nm-device-vrf.c b/src/devices/nm-device-vrf.c index 05ee7a8c..ae0ecc60 100644 --- a/src/devices/nm-device-vrf.c +++ b/src/devices/nm-device-vrf.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ #include "nm-default.h" @@ -17,355 +17,359 @@ _LOG_DECLARE_SELF(NMDeviceVrf); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVrf, - PROP_TABLE, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceVrf, PROP_TABLE, ); typedef struct { - NMPlatformLnkVrf props; + NMPlatformLnkVrf props; } NMDeviceVrfPrivate; struct _NMDeviceVrf { - NMDevice parent; - NMDeviceVrfPrivate _priv; + NMDevice parent; + NMDeviceVrfPrivate _priv; }; struct _NMDeviceVrfClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceVrf, nm_device_vrf, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceVrf, nm_device_vrf, NM_TYPE_DEVICE) -#define NM_DEVICE_VRF_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceVrf, NM_IS_DEVICE_VRF, NMDevice) +#define NM_DEVICE_VRF_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVrf, NM_IS_DEVICE_VRF, NMDevice) /*****************************************************************************/ static void -do_update_properties (NMDeviceVrf *self, const NMPlatformLnkVrf *props) +do_update_properties(NMDeviceVrf *self, const NMPlatformLnkVrf *props) { - NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE (self); - GObject *object = G_OBJECT (self); - NMPlatformLnkVrf props_null; - - if (!props) { - props_null = (NMPlatformLnkVrf) { }; - props = &props_null; - } - - g_object_freeze_notify (object); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->props.field != props->field) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED (table, PROP_TABLE); - - g_object_thaw_notify (object); + NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE(self); + GObject * object = G_OBJECT(self); + NMPlatformLnkVrf props_null; + + if (!props) { + props_null = (NMPlatformLnkVrf){}; + props = &props_null; + } + + g_object_freeze_notify(object); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED(table, PROP_TABLE); + + g_object_thaw_notify(object); } static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceVrf *self = NM_DEVICE_VRF (device); - const NMPlatformLnkVrf *props; - - props = nm_platform_link_get_lnk_vrf (nm_device_get_platform (device), nm_device_get_ifindex (device), NULL); - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get vrf properties"); - return; - } - - do_update_properties (self, props); + NMDeviceVrf * self = NM_DEVICE_VRF(device); + const NMPlatformLnkVrf *props; + + props = nm_platform_link_get_lnk_vrf(nm_device_get_platform(device), + nm_device_get_ifindex(device), + NULL); + if (!props) { + _LOGW(LOGD_PLATFORM, "could not get vrf properties"); + return; + } + + do_update_properties(self, props); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_vrf_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_vrf_parent_class)->link_changed(device, pllink); + update_properties(device); } static void -unrealize_notify (NMDevice *device) +unrealize_notify(NMDevice *device) { - NMDeviceVrf *self = NM_DEVICE_VRF (device); + NMDeviceVrf *self = NM_DEVICE_VRF(device); - NM_DEVICE_CLASS (nm_device_vrf_parent_class)->unrealize_notify (device); + NM_DEVICE_CLASS(nm_device_vrf_parent_class)->unrealize_notify(device); - do_update_properties (self, NULL); + do_update_properties(self, NULL); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMPlatformLnkVrf props = { }; - NMSettingVrf *s_vrf; - int r; - - s_vrf = _nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF); - nm_assert (s_vrf); - - props.table = nm_setting_vrf_get_table (s_vrf); - - r = nm_platform_link_vrf_add (nm_device_get_platform (device), iface, &props, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create VRF interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMPlatformLnkVrf props = {}; + NMSettingVrf * s_vrf; + int r; + + s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); + nm_assert(s_vrf); + + props.table = nm_setting_vrf_get_table(s_vrf); + + r = nm_platform_link_vrf_add(nm_device_get_platform(device), iface, &props, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create VRF interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE (device); - NMSettingVrf *s_vrf; + NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE(device); + NMSettingVrf * s_vrf; - if (!NM_DEVICE_CLASS (nm_device_vrf_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_vrf_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - if (nm_device_is_real (device)) { - s_vrf = _nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF); + if (nm_device_is_real(device)) { + s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); - if (priv->props.table != nm_setting_vrf_get_table (s_vrf)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vrf table mismatches"); - return FALSE; - } - } + if (priv->props.table != nm_setting_vrf_get_table(s_vrf)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vrf table mismatches"); + return FALSE; + } + } - return TRUE; + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingVrf *s_vrf; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_VRF_SETTING_NAME, - existing_connections, - NULL, - _("VRF connection"), - NULL, - NULL, - TRUE); - - s_vrf = _nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF); - if (!s_vrf) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'vrf' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingVrf *s_vrf; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_VRF_SETTING_NAME, + existing_connections, + NULL, + _("VRF connection"), + NULL, + NULL, + TRUE); + + s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); + if (!s_vrf) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'vrf' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE (device); - NMSettingVrf *s_vrf = _nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF); + NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE(device); + NMSettingVrf * s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); - if (!s_vrf) { - s_vrf = (NMSettingVrf *) nm_setting_vrf_new (); - nm_connection_add_setting (connection, (NMSetting *) s_vrf); - } + if (!s_vrf) { + s_vrf = (NMSettingVrf *) nm_setting_vrf_new(); + nm_connection_add_setting(connection, (NMSetting *) s_vrf); + } - if (priv->props.table != nm_setting_vrf_get_table (s_vrf)) - g_object_set (G_OBJECT (s_vrf), NM_SETTING_VRF_TABLE, priv->props.table, NULL); + if (priv->props.table != nm_setting_vrf_get_table(s_vrf)) + g_object_set(G_OBJECT(s_vrf), NM_SETTING_VRF_TABLE, priv->props.table, NULL); } static gboolean -enslave_slave (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - NMDeviceVrf *self = NM_DEVICE_VRF (device); - gboolean success = TRUE; - const char *slave_iface = nm_device_get_ip_iface (slave); + NMDeviceVrf *self = NM_DEVICE_VRF(device); + gboolean success = TRUE; + const char * slave_iface = nm_device_get_ip_iface(slave); - nm_device_master_check_slave_physical_port (device, slave, LOGD_DEVICE); + nm_device_master_check_slave_physical_port(device, slave, LOGD_DEVICE); - if (configure) { - nm_device_take_down (slave, TRUE); - success = nm_platform_link_enslave (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - nm_device_get_ip_ifindex (slave)); - nm_device_bring_up (slave, TRUE, NULL); + if (configure) { + nm_device_take_down(slave, TRUE); + success = nm_platform_link_enslave(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + nm_device_get_ip_ifindex(slave)); + nm_device_bring_up(slave, TRUE, NULL); - if (!success) - return FALSE; + if (!success) + return FALSE; - _LOGI (LOGD_DEVICE, "enslaved VRF slave %s", slave_iface); - } else - _LOGI (LOGD_BOND, "VRF slave %s was enslaved", slave_iface); + _LOGI(LOGD_DEVICE, "enslaved VRF slave %s", slave_iface); + } else + _LOGI(LOGD_BOND, "VRF slave %s was enslaved", slave_iface); - return TRUE; + return TRUE; } static void -release_slave (NMDevice *device, - NMDevice *slave, - gboolean configure) +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - NMDeviceVrf *self = NM_DEVICE_VRF (device); - gboolean success; - int ifindex_slave; - int ifindex; - - if (configure) { - ifindex = nm_device_get_ifindex (device); - if ( ifindex <= 0 - || !nm_platform_link_get (nm_device_get_platform (device), ifindex)) - configure = FALSE; - } - - ifindex_slave = nm_device_get_ip_ifindex (slave); - - if (ifindex_slave <= 0) - _LOGD (LOGD_DEVICE, "VRF slave %s is already released", nm_device_get_ip_iface (slave)); - - if (configure) { - if (ifindex_slave > 0) { - success = nm_platform_link_release (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - ifindex_slave); - - if (success) { - _LOGI (LOGD_DEVICE, "released VRF slave %s", - nm_device_get_ip_iface (slave)); - } else { - _LOGW (LOGD_DEVICE, "failed to release VRF slave %s", - nm_device_get_ip_iface (slave)); - } - } - } else { - if (ifindex_slave > 0) { - _LOGI (LOGD_DEVICE, "VRF slave %s was released", - nm_device_get_ip_iface (slave)); - } - } + NMDeviceVrf *self = NM_DEVICE_VRF(device); + gboolean success; + int ifindex_slave; + int ifindex; + + if (configure) { + ifindex = nm_device_get_ifindex(device); + if (ifindex <= 0 || !nm_platform_link_get(nm_device_get_platform(device), ifindex)) + configure = FALSE; + } + + ifindex_slave = nm_device_get_ip_ifindex(slave); + + if (ifindex_slave <= 0) + _LOGD(LOGD_DEVICE, "VRF slave %s is already released", nm_device_get_ip_iface(slave)); + + if (configure) { + if (ifindex_slave > 0) { + success = nm_platform_link_release(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + ifindex_slave); + + if (success) { + _LOGI(LOGD_DEVICE, "released VRF slave %s", nm_device_get_ip_iface(slave)); + } else { + _LOGW(LOGD_DEVICE, "failed to release VRF slave %s", nm_device_get_ip_iface(slave)); + } + } + } else { + if (ifindex_slave > 0) { + _LOGI(LOGD_DEVICE, "VRF slave %s was released", nm_device_get_ip_iface(slave)); + } + } } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_TABLE: - g_value_set_uint (value, priv->props.table); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_TABLE: + g_value_set_uint(value, priv->props.table); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_vrf_init (NMDeviceVrf *self) -{ -} +nm_device_vrf_init(NMDeviceVrf *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_vrf = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_VRF, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Table", "u", NM_DEVICE_VRF_TABLE), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_VRF, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Table", "u", NM_DEVICE_VRF_TABLE), ), ), }; static void -nm_device_vrf_class_init (NMDeviceVrfClass *klass) +nm_device_vrf_class_init(NMDeviceVrfClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vrf); - - device_class->connection_type_supported = NM_SETTING_VRF_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_VRF_SETTING_NAME; - device_class->is_master = TRUE; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VRF); - - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - device_class->link_changed = link_changed; - device_class->unrealize_notify = unrealize_notify; - device_class->create_and_realize = create_and_realize; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->update_connection = update_connection; - - obj_properties[PROP_TABLE] = - g_param_spec_uint (NM_DEVICE_VRF_TABLE, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_vrf); + + device_class->connection_type_supported = NM_SETTING_VRF_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_VRF_SETTING_NAME; + device_class->is_master = TRUE; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_VRF); + + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; + device_class->link_changed = link_changed; + device_class->unrealize_notify = unrealize_notify; + device_class->create_and_realize = create_and_realize; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->update_connection = update_connection; + + obj_properties[PROP_TABLE] = g_param_spec_uint(NM_DEVICE_VRF_TABLE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_VRF_DEVICE_FACTORY (nm_vrf_device_factory_get_type ()) -#define NM_VRF_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VRF_DEVICE_FACTORY, NMVrfDeviceFactory)) +#define NM_TYPE_VRF_DEVICE_FACTORY (nm_vrf_device_factory_get_type()) +#define NM_VRF_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VRF_DEVICE_FACTORY, NMVrfDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return g_object_new (NM_TYPE_DEVICE_VRF, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Vrf", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VRF, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VRF, - NULL); + return g_object_new(NM_TYPE_DEVICE_VRF, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Vrf", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_VRF, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_VRF, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (VRF, Vrf, vrf, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VRF) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VRF_SETTING_NAME), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + VRF, + Vrf, + vrf, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VRF) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_VRF_SETTING_NAME), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-vrf.h b/src/devices/nm-device-vrf.h index 89ab0f13..eb09bd95 100644 --- a/src/devices/nm-device-vrf.h +++ b/src/devices/nm-device-vrf.h @@ -1,22 +1,24 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ #ifndef __NETWORKMANAGER_DEVICE_VRF_H__ #define __NETWORKMANAGER_DEVICE_VRF_H__ #include "nm-device-generic.h" -#define NM_TYPE_DEVICE_VRF (nm_device_vrf_get_type ()) -#define NM_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrf)) -#define NM_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) -#define NM_IS_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VRF)) -#define NM_IS_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VRF)) -#define NM_DEVICE_VRF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) +#define NM_TYPE_DEVICE_VRF (nm_device_vrf_get_type()) +#define NM_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrf)) +#define NM_DEVICE_VRF_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) +#define NM_IS_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VRF)) +#define NM_IS_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VRF)) +#define NM_DEVICE_VRF_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) -#define NM_DEVICE_VRF_TABLE "table" +#define NM_DEVICE_VRF_TABLE "table" -typedef struct _NMDeviceVrf NMDeviceVrf; +typedef struct _NMDeviceVrf NMDeviceVrf; typedef struct _NMDeviceVrfClass NMDeviceVrfClass; -GType nm_device_vrf_get_type (void); +GType nm_device_vrf_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_VRF_H__ */ diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index b49e7c3e..083f29c6 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - 2015 Red Hat, Inc. */ @@ -24,726 +24,788 @@ _LOG_DECLARE_SELF(NMDeviceVxlan); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVxlan, - PROP_ID, - PROP_LOCAL, - PROP_GROUP, - PROP_TOS, - PROP_TTL, - PROP_LEARNING, - PROP_AGEING, - PROP_LIMIT, - PROP_SRC_PORT_MIN, - PROP_SRC_PORT_MAX, - PROP_DST_PORT, - PROP_PROXY, - PROP_RSC, - PROP_L2MISS, - PROP_L3MISS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceVxlan, + PROP_ID, + PROP_LOCAL, + PROP_GROUP, + PROP_TOS, + PROP_TTL, + PROP_LEARNING, + PROP_AGEING, + PROP_LIMIT, + PROP_SRC_PORT_MIN, + PROP_SRC_PORT_MAX, + PROP_DST_PORT, + PROP_PROXY, + PROP_RSC, + PROP_L2MISS, + PROP_L3MISS, ); typedef struct { - NMPlatformLnkVxlan props; + NMPlatformLnkVxlan props; } NMDeviceVxlanPrivate; struct _NMDeviceVxlan { - NMDevice parent; - NMDeviceVxlanPrivate _priv; + NMDevice parent; + NMDeviceVxlanPrivate _priv; }; struct _NMDeviceVxlanClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE) -#define NM_DEVICE_VXLAN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceVxlan, NM_IS_DEVICE_VXLAN, NMDevice) +#define NM_DEVICE_VXLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVxlan, NM_IS_DEVICE_VXLAN, NMDevice) /*****************************************************************************/ static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self); - GObject *object = G_OBJECT (device); - const NMPlatformLnkVxlan *props; - - props = nm_platform_link_get_lnk_vxlan (nm_device_get_platform (device), nm_device_get_ifindex (device), NULL); - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get vxlan properties"); - return; - } - - g_object_freeze_notify (object); - - if (priv->props.parent_ifindex != props->parent_ifindex) - nm_device_parent_set_ifindex (device, props->parent_ifindex); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->props.field != props->field) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - -#define CHECK_PROPERTY_CHANGED_IN6ADDR(field, prop) \ - G_STMT_START { \ - if (memcmp (&priv->props.field, &props->field, sizeof (props->field)) != 0) { \ - priv->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED (id, PROP_ID); - CHECK_PROPERTY_CHANGED (local, PROP_LOCAL); - CHECK_PROPERTY_CHANGED_IN6ADDR (local6, PROP_LOCAL); - CHECK_PROPERTY_CHANGED (group, PROP_GROUP); - CHECK_PROPERTY_CHANGED_IN6ADDR (group6, PROP_GROUP); - CHECK_PROPERTY_CHANGED (tos, PROP_TOS); - CHECK_PROPERTY_CHANGED (ttl, PROP_TTL); - CHECK_PROPERTY_CHANGED (learning, PROP_LEARNING); - CHECK_PROPERTY_CHANGED (ageing, PROP_AGEING); - CHECK_PROPERTY_CHANGED (limit, PROP_LIMIT); - CHECK_PROPERTY_CHANGED (src_port_min, PROP_SRC_PORT_MIN); - CHECK_PROPERTY_CHANGED (src_port_max, PROP_SRC_PORT_MAX); - CHECK_PROPERTY_CHANGED (dst_port, PROP_DST_PORT); - CHECK_PROPERTY_CHANGED (proxy, PROP_PROXY); - CHECK_PROPERTY_CHANGED (rsc, PROP_RSC); - CHECK_PROPERTY_CHANGED (l2miss, PROP_L2MISS); - CHECK_PROPERTY_CHANGED (l3miss, PROP_L3MISS); - - g_object_thaw_notify (object); + NMDeviceVxlan * self = NM_DEVICE_VXLAN(device); + NMDeviceVxlanPrivate * priv = NM_DEVICE_VXLAN_GET_PRIVATE(self); + GObject * object = G_OBJECT(device); + const NMPlatformLnkVxlan *props; + + props = nm_platform_link_get_lnk_vxlan(nm_device_get_platform(device), + nm_device_get_ifindex(device), + NULL); + if (!props) { + _LOGW(LOGD_PLATFORM, "could not get vxlan properties"); + return; + } + + g_object_freeze_notify(object); + + if (priv->props.parent_ifindex != props->parent_ifindex) + nm_device_parent_set_ifindex(device, props->parent_ifindex); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + +#define CHECK_PROPERTY_CHANGED_IN6ADDR(field, prop) \ + G_STMT_START \ + { \ + if (memcmp(&priv->props.field, &props->field, sizeof(props->field)) != 0) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED(id, PROP_ID); + CHECK_PROPERTY_CHANGED(local, PROP_LOCAL); + CHECK_PROPERTY_CHANGED_IN6ADDR(local6, PROP_LOCAL); + CHECK_PROPERTY_CHANGED(group, PROP_GROUP); + CHECK_PROPERTY_CHANGED_IN6ADDR(group6, PROP_GROUP); + CHECK_PROPERTY_CHANGED(tos, PROP_TOS); + CHECK_PROPERTY_CHANGED(ttl, PROP_TTL); + CHECK_PROPERTY_CHANGED(learning, PROP_LEARNING); + CHECK_PROPERTY_CHANGED(ageing, PROP_AGEING); + CHECK_PROPERTY_CHANGED(limit, PROP_LIMIT); + CHECK_PROPERTY_CHANGED(src_port_min, PROP_SRC_PORT_MIN); + CHECK_PROPERTY_CHANGED(src_port_max, PROP_SRC_PORT_MAX); + CHECK_PROPERTY_CHANGED(dst_port, PROP_DST_PORT); + CHECK_PROPERTY_CHANGED(proxy, PROP_PROXY); + CHECK_PROPERTY_CHANGED(rsc, PROP_RSC); + CHECK_PROPERTY_CHANGED(l2miss, PROP_L2MISS); + CHECK_PROPERTY_CHANGED(l3miss, PROP_L3MISS); + + g_object_thaw_notify(object); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_vxlan_parent_class)->link_changed(device, pllink); + update_properties(device); } static void -unrealize_notify (NMDevice *device) +unrealize_notify(NMDevice *device) { - NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self); - guint i; + NMDeviceVxlan * self = NM_DEVICE_VXLAN(device); + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(self); + guint i; - NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->unrealize_notify (device); + NM_DEVICE_CLASS(nm_device_vxlan_parent_class)->unrealize_notify(device); - memset (&priv->props, 0, sizeof (NMPlatformLnkVxlan)); + memset(&priv->props, 0, sizeof(NMPlatformLnkVxlan)); - for (i = 1; i < _PROPERTY_ENUMS_LAST; i++) - g_object_notify_by_pspec (G_OBJECT (self), obj_properties[i]); + for (i = 1; i < _PROPERTY_ENUMS_LAST; i++) + g_object_notify_by_pspec(G_OBJECT(self), obj_properties[i]); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - NMPlatformLnkVxlan props = { }; - NMSettingVxlan *s_vxlan; - const char *str; - int ret; - int r; - - s_vxlan = nm_connection_get_setting_vxlan (connection); - g_assert (s_vxlan); - - if (parent) - props.parent_ifindex = nm_device_get_ifindex (parent); - - props.id = nm_setting_vxlan_get_id (s_vxlan); - - str = nm_setting_vxlan_get_local (s_vxlan); - if (str) { - ret = inet_pton (AF_INET, str, &props.local); - if (ret != 1) - ret = inet_pton (AF_INET6, str, &props.local6); - if (ret != 1) - return FALSE; - } - - str = nm_setting_vxlan_get_remote (s_vxlan); - ret = inet_pton (AF_INET, str, &props.group); - if (ret != 1) - ret = inet_pton (AF_INET6, str, &props.group6); - if (ret != 1) - return FALSE; - - props.tos = nm_setting_vxlan_get_tos (s_vxlan); - props.ttl = nm_setting_vxlan_get_ttl (s_vxlan); - props.learning = nm_setting_vxlan_get_learning (s_vxlan); - props.ageing = nm_setting_vxlan_get_ageing (s_vxlan); - props.limit = nm_setting_vxlan_get_limit (s_vxlan); - props.src_port_min = nm_setting_vxlan_get_source_port_min (s_vxlan); - props.src_port_max = nm_setting_vxlan_get_source_port_max (s_vxlan); - props.dst_port = nm_setting_vxlan_get_destination_port (s_vxlan); - props.proxy = nm_setting_vxlan_get_proxy (s_vxlan); - props.rsc = nm_setting_vxlan_get_rsc (s_vxlan); - props.l2miss = nm_setting_vxlan_get_l2_miss (s_vxlan); - props.l3miss = nm_setting_vxlan_get_l3_miss (s_vxlan); - - r = nm_platform_link_vxlan_add (nm_device_get_platform (device), iface, &props, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create VXLAN interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char * iface = nm_device_get_iface(device); + NMPlatformLnkVxlan props = {}; + NMSettingVxlan * s_vxlan; + const char * str; + int ret; + int r; + + s_vxlan = nm_connection_get_setting_vxlan(connection); + g_assert(s_vxlan); + + if (parent) + props.parent_ifindex = nm_device_get_ifindex(parent); + + props.id = nm_setting_vxlan_get_id(s_vxlan); + + str = nm_setting_vxlan_get_local(s_vxlan); + if (str) { + ret = inet_pton(AF_INET, str, &props.local); + if (ret != 1) + ret = inet_pton(AF_INET6, str, &props.local6); + if (ret != 1) + return FALSE; + } + + str = nm_setting_vxlan_get_remote(s_vxlan); + ret = inet_pton(AF_INET, str, &props.group); + if (ret != 1) + ret = inet_pton(AF_INET6, str, &props.group6); + if (ret != 1) + return FALSE; + + props.tos = nm_setting_vxlan_get_tos(s_vxlan); + props.ttl = nm_setting_vxlan_get_ttl(s_vxlan); + props.learning = nm_setting_vxlan_get_learning(s_vxlan); + props.ageing = nm_setting_vxlan_get_ageing(s_vxlan); + props.limit = nm_setting_vxlan_get_limit(s_vxlan); + props.src_port_min = nm_setting_vxlan_get_source_port_min(s_vxlan); + props.src_port_max = nm_setting_vxlan_get_source_port_max(s_vxlan); + props.dst_port = nm_setting_vxlan_get_destination_port(s_vxlan); + props.proxy = nm_setting_vxlan_get_proxy(s_vxlan); + props.rsc = nm_setting_vxlan_get_rsc(s_vxlan); + props.l2miss = nm_setting_vxlan_get_l2_miss(s_vxlan); + props.l3miss = nm_setting_vxlan_get_l3_miss(s_vxlan); + + r = nm_platform_link_vxlan_add(nm_device_get_platform(device), iface, &props, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create VXLAN interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } static gboolean -address_matches (const char *str, in_addr_t addr4, struct in6_addr *addr6) +address_matches(const char *str, in_addr_t addr4, struct in6_addr *addr6) { - in_addr_t new_addr4 = 0; - struct in6_addr new_addr6 = { }; - - if (!str) { - return addr4 == 0 - && !memcmp (addr6, &in6addr_any, sizeof (in6addr_any)); - } - - if (inet_pton (AF_INET, str, &new_addr4) == 1) - return new_addr4 == addr4; - else if (inet_pton (AF_INET6, str, &new_addr6) == 1) - return !memcmp (&new_addr6, addr6, sizeof (new_addr6)); - else - return FALSE; + in_addr_t new_addr4 = 0; + struct in6_addr new_addr6 = {}; + + if (!str) { + return addr4 == 0 && !memcmp(addr6, &in6addr_any, sizeof(in6addr_any)); + } + + if (inet_pton(AF_INET, str, &new_addr4) == 1) + return new_addr4 == addr4; + else if (inet_pton(AF_INET6, str, &new_addr6) == 1) + return !memcmp(&new_addr6, addr6, sizeof(new_addr6)); + else + return FALSE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device); - NMSettingVxlan *s_vxlan; - const char *parent; - - if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (nm_device_is_real (device)) { - s_vxlan = nm_connection_get_setting_vxlan (connection); - - parent = nm_setting_vxlan_get_parent (s_vxlan); - if (parent && !nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan parent mismatches"); - return FALSE; - } - - if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan id mismatches"); - return FALSE; - } - - if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan local address mismatches"); - return FALSE; - } - - if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan remote address mismatches"); - return FALSE; - } - - if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan source port min mismatches"); - return FALSE; - } - - if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan source port max mismatches"); - return FALSE; - } - - if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan destination port mismatches"); - return FALSE; - } - - if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan TOS mismatches"); - return FALSE; - } - - if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan TTL mismatches"); - return FALSE; - } - - if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan learning mismatches"); - return FALSE; - } - - if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan ageing mismatches"); - return FALSE; - } - - if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan proxy mismatches"); - return FALSE; - } - - if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan rsc mismatches"); - return FALSE; - } - - if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan l2miss mismatches"); - return FALSE; - } - - if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan l3miss mismatches"); - return FALSE; - } - } - - return TRUE; + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(device); + NMSettingVxlan * s_vxlan; + const char * parent; + + if (!NM_DEVICE_CLASS(nm_device_vxlan_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (nm_device_is_real(device)) { + s_vxlan = nm_connection_get_setting_vxlan(connection); + + parent = nm_setting_vxlan_get_parent(s_vxlan); + if (parent && !nm_device_match_parent(device, parent)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan parent mismatches"); + return FALSE; + } + + if (priv->props.id != nm_setting_vxlan_get_id(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan id mismatches"); + return FALSE; + } + + if (!address_matches(nm_setting_vxlan_get_local(s_vxlan), + priv->props.local, + &priv->props.local6)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan local address mismatches"); + return FALSE; + } + + if (!address_matches(nm_setting_vxlan_get_remote(s_vxlan), + priv->props.group, + &priv->props.group6)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan remote address mismatches"); + return FALSE; + } + + if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan source port min mismatches"); + return FALSE; + } + + if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan source port max mismatches"); + return FALSE; + } + + if (priv->props.dst_port != nm_setting_vxlan_get_destination_port(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan destination port mismatches"); + return FALSE; + } + + if (priv->props.tos != nm_setting_vxlan_get_tos(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan TOS mismatches"); + return FALSE; + } + + if (priv->props.ttl != nm_setting_vxlan_get_ttl(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan TTL mismatches"); + return FALSE; + } + + if (priv->props.learning != nm_setting_vxlan_get_learning(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan learning mismatches"); + return FALSE; + } + + if (priv->props.ageing != nm_setting_vxlan_get_ageing(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan ageing mismatches"); + return FALSE; + } + + if (priv->props.proxy != nm_setting_vxlan_get_proxy(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan proxy mismatches"); + return FALSE; + } + + if (priv->props.rsc != nm_setting_vxlan_get_rsc(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan rsc mismatches"); + return FALSE; + } + + if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan l2miss mismatches"); + return FALSE; + } + + if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss(s_vxlan)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "vxlan l3miss mismatches"); + return FALSE; + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingVxlan *s_vxlan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_VXLAN_SETTING_NAME, - existing_connections, - NULL, - _("VXLAN connection"), - NULL, - NULL, - TRUE); - - s_vxlan = nm_connection_get_setting_vxlan (connection); - if (!s_vxlan) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'vxlan' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingVxlan *s_vxlan; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_VXLAN_SETTING_NAME, + existing_connections, + NULL, + _("VXLAN connection"), + NULL, + NULL, + TRUE); + + s_vxlan = nm_connection_get_setting_vxlan(connection); + if (!s_vxlan) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'vxlan' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device); - NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection); - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - if (!s_vxlan) { - s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new (); - nm_connection_add_setting (connection, (NMSetting *) s_vxlan); - } - - if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan)) - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL); - - g_object_set (s_vxlan, - NM_SETTING_VXLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_vxlan_get_parent (s_vxlan)), - NULL); - - if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) { - if (priv->props.group) { - g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE, - _nm_utils_inet4_ntop (priv->props.group, sbuf), - NULL); - } else { - g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE, - _nm_utils_inet6_ntop (&priv->props.group6, sbuf), - NULL); - } - } - - if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) { - if (priv->props.local) { - g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL, - _nm_utils_inet4_ntop (priv->props.local, sbuf), - NULL); - } else if (memcmp (&priv->props.local6, &in6addr_any, sizeof (in6addr_any))) { - g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL, - _nm_utils_inet6_ntop (&priv->props.local6, sbuf), - NULL); - } - } - - if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MIN, - priv->props.src_port_min, NULL); - } - - if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MAX, - priv->props.src_port_max, NULL); - } - - if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_DESTINATION_PORT, - priv->props.dst_port, NULL); - } - - if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TOS, - priv->props.tos, NULL); - } - - if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TTL, - priv->props.ttl, NULL); - } - - if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_LEARNING, - priv->props.learning, NULL); - } - - if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_AGEING, - priv->props.ageing, NULL); - } - - if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_PROXY, - priv->props.proxy, NULL); - } - - if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_RSC, - priv->props.rsc, NULL); - } - - if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L2_MISS, - priv->props.l2miss, NULL); - } - - if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) { - g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L3_MISS, - priv->props.l3miss, NULL); - } + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(device); + NMSettingVxlan * s_vxlan = nm_connection_get_setting_vxlan(connection); + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + if (!s_vxlan) { + s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new(); + nm_connection_add_setting(connection, (NMSetting *) s_vxlan); + } + + if (priv->props.id != nm_setting_vxlan_get_id(s_vxlan)) + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL); + + g_object_set(s_vxlan, + NM_SETTING_VXLAN_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_vxlan_get_parent(s_vxlan)), + NULL); + + if (!address_matches(nm_setting_vxlan_get_remote(s_vxlan), + priv->props.group, + &priv->props.group6)) { + if (priv->props.group) { + g_object_set(s_vxlan, + NM_SETTING_VXLAN_REMOTE, + _nm_utils_inet4_ntop(priv->props.group, sbuf), + NULL); + } else { + g_object_set(s_vxlan, + NM_SETTING_VXLAN_REMOTE, + _nm_utils_inet6_ntop(&priv->props.group6, sbuf), + NULL); + } + } + + if (!address_matches(nm_setting_vxlan_get_local(s_vxlan), + priv->props.local, + &priv->props.local6)) { + if (priv->props.local) { + g_object_set(s_vxlan, + NM_SETTING_VXLAN_LOCAL, + _nm_utils_inet4_ntop(priv->props.local, sbuf), + NULL); + } else if (memcmp(&priv->props.local6, &in6addr_any, sizeof(in6addr_any))) { + g_object_set(s_vxlan, + NM_SETTING_VXLAN_LOCAL, + _nm_utils_inet6_ntop(&priv->props.local6, sbuf), + NULL); + } + } + + if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), + NM_SETTING_VXLAN_SOURCE_PORT_MIN, + priv->props.src_port_min, + NULL); + } + + if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), + NM_SETTING_VXLAN_SOURCE_PORT_MAX, + priv->props.src_port_max, + NULL); + } + + if (priv->props.dst_port != nm_setting_vxlan_get_destination_port(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), + NM_SETTING_VXLAN_DESTINATION_PORT, + priv->props.dst_port, + NULL); + } + + if (priv->props.tos != nm_setting_vxlan_get_tos(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_TOS, priv->props.tos, NULL); + } + + if (priv->props.ttl != nm_setting_vxlan_get_ttl(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_TTL, priv->props.ttl, NULL); + } + + if (priv->props.learning != nm_setting_vxlan_get_learning(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_LEARNING, priv->props.learning, NULL); + } + + if (priv->props.ageing != nm_setting_vxlan_get_ageing(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_AGEING, priv->props.ageing, NULL); + } + + if (priv->props.proxy != nm_setting_vxlan_get_proxy(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_PROXY, priv->props.proxy, NULL); + } + + if (priv->props.rsc != nm_setting_vxlan_get_rsc(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_RSC, priv->props.rsc, NULL); + } + + if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_L2_MISS, priv->props.l2miss, NULL); + } + + if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss(s_vxlan)) { + g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_L3_MISS, priv->props.l3miss, NULL); + } } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_ID: - g_value_set_uint (value, priv->props.id); - break; - case PROP_GROUP: - if (priv->props.group) - g_value_take_string (value, nm_utils_inet4_ntop_dup (priv->props.group)); - else if (!IN6_IS_ADDR_UNSPECIFIED (&priv->props.group6)) - g_value_take_string (value, nm_utils_inet6_ntop_dup (&priv->props.group6)); - break; - case PROP_LOCAL: - if (priv->props.local) - g_value_take_string (value, nm_utils_inet4_ntop_dup (priv->props.local)); - else if (!IN6_IS_ADDR_UNSPECIFIED (&priv->props.local6)) - g_value_take_string (value, nm_utils_inet6_ntop_dup (&priv->props.local6)); - break; - case PROP_TOS: - g_value_set_uchar (value, priv->props.tos); - break; - case PROP_TTL: - g_value_set_uchar (value, priv->props.ttl); - break; - case PROP_LEARNING: - g_value_set_boolean (value, priv->props.learning); - break; - case PROP_AGEING: - g_value_set_uint (value, priv->props.ageing); - break; - case PROP_LIMIT: - g_value_set_uint (value, priv->props.limit); - break; - case PROP_DST_PORT: - g_value_set_uint (value, priv->props.dst_port); - break; - case PROP_SRC_PORT_MIN: - g_value_set_uint (value, priv->props.src_port_min); - break; - case PROP_SRC_PORT_MAX: - g_value_set_uint (value, priv->props.src_port_max); - break; - case PROP_PROXY: - g_value_set_boolean (value, priv->props.proxy); - break; - case PROP_RSC: - g_value_set_boolean (value, priv->props.rsc); - break; - case PROP_L2MISS: - g_value_set_boolean (value, priv->props.l2miss); - break; - case PROP_L3MISS: - g_value_set_boolean (value, priv->props.l3miss); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_ID: + g_value_set_uint(value, priv->props.id); + break; + case PROP_GROUP: + if (priv->props.group) + g_value_take_string(value, nm_utils_inet4_ntop_dup(priv->props.group)); + else if (!IN6_IS_ADDR_UNSPECIFIED(&priv->props.group6)) + g_value_take_string(value, nm_utils_inet6_ntop_dup(&priv->props.group6)); + break; + case PROP_LOCAL: + if (priv->props.local) + g_value_take_string(value, nm_utils_inet4_ntop_dup(priv->props.local)); + else if (!IN6_IS_ADDR_UNSPECIFIED(&priv->props.local6)) + g_value_take_string(value, nm_utils_inet6_ntop_dup(&priv->props.local6)); + break; + case PROP_TOS: + g_value_set_uchar(value, priv->props.tos); + break; + case PROP_TTL: + g_value_set_uchar(value, priv->props.ttl); + break; + case PROP_LEARNING: + g_value_set_boolean(value, priv->props.learning); + break; + case PROP_AGEING: + g_value_set_uint(value, priv->props.ageing); + break; + case PROP_LIMIT: + g_value_set_uint(value, priv->props.limit); + break; + case PROP_DST_PORT: + g_value_set_uint(value, priv->props.dst_port); + break; + case PROP_SRC_PORT_MIN: + g_value_set_uint(value, priv->props.src_port_min); + break; + case PROP_SRC_PORT_MAX: + g_value_set_uint(value, priv->props.src_port_max); + break; + case PROP_PROXY: + g_value_set_boolean(value, priv->props.proxy); + break; + case PROP_RSC: + g_value_set_boolean(value, priv->props.rsc); + break; + case PROP_L2MISS: + g_value_set_boolean(value, priv->props.l2miss); + break; + case PROP_L3MISS: + g_value_set_boolean(value, priv->props.l3miss); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_vxlan_init (NMDeviceVxlan *self) -{ -} +nm_device_vxlan_init(NMDeviceVxlan *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_vxlan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_VXLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Id", "u", NM_DEVICE_VXLAN_ID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Group", "s", NM_DEVICE_VXLAN_GROUP), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Local", "s", NM_DEVICE_VXLAN_LOCAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tos", "y", NM_DEVICE_VXLAN_TOS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ttl", "y", NM_DEVICE_VXLAN_TTL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Learning", "b", NM_DEVICE_VXLAN_LEARNING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ageing", "u", NM_DEVICE_VXLAN_AGEING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Limit", "u", NM_DEVICE_VXLAN_LIMIT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DstPort", "q", NM_DEVICE_VXLAN_DST_PORT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("SrcPortMin", "q", NM_DEVICE_VXLAN_SRC_PORT_MIN), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("SrcPortMax", "q", NM_DEVICE_VXLAN_SRC_PORT_MAX), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Proxy", "b", NM_DEVICE_VXLAN_PROXY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Rsc", "b", NM_DEVICE_VXLAN_RSC), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("L3miss", "b", NM_DEVICE_VXLAN_L3MISS), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_VXLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Id", "u", NM_DEVICE_VXLAN_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Group", "s", NM_DEVICE_VXLAN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Local", "s", NM_DEVICE_VXLAN_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tos", "y", NM_DEVICE_VXLAN_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ttl", "y", NM_DEVICE_VXLAN_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Learning", + "b", + NM_DEVICE_VXLAN_LEARNING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ageing", "u", NM_DEVICE_VXLAN_AGEING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Limit", "u", NM_DEVICE_VXLAN_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DstPort", + "q", + NM_DEVICE_VXLAN_DST_PORT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("SrcPortMin", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MIN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("SrcPortMax", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MAX), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Proxy", "b", NM_DEVICE_VXLAN_PROXY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Rsc", "b", NM_DEVICE_VXLAN_RSC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("L3miss", + "b", + NM_DEVICE_VXLAN_L3MISS), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) +nm_device_vxlan_class_init(NMDeviceVxlanClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vxlan); - - device_class->connection_type_supported = NM_SETTING_VXLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_VXLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VXLAN); - - device_class->link_changed = link_changed; - device_class->unrealize_notify = unrealize_notify; - device_class->create_and_realize = create_and_realize; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->update_connection = update_connection; - device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - - obj_properties[PROP_ID] = - g_param_spec_uint (NM_DEVICE_VXLAN_ID, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LOCAL] = - g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_GROUP] = - g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_TOS] = - g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, "", "", - 0, 255, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_TTL] = - g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, "", "", - 0, 255, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LEARNING] = - g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_AGEING] = - g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LIMIT] = - g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SRC_PORT_MIN] = - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "", - 0, 65535, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SRC_PORT_MAX] = - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "", - 0, 65535, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_DST_PORT] = - g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", - 0, 65535, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_PROXY] = - g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_RSC] = - g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_L2MISS] = - g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_L3MISS] = - g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_vxlan); + + device_class->connection_type_supported = NM_SETTING_VXLAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_VXLAN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_VXLAN); + + device_class->link_changed = link_changed; + device_class->unrealize_notify = unrealize_notify; + device_class->create_and_realize = create_and_realize; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->update_connection = update_connection; + device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + + obj_properties[PROP_ID] = g_param_spec_uint(NM_DEVICE_VXLAN_ID, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LOCAL] = g_param_spec_string(NM_DEVICE_VXLAN_LOCAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_GROUP] = g_param_spec_string(NM_DEVICE_VXLAN_GROUP, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_VXLAN_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_TTL] = g_param_spec_uchar(NM_DEVICE_VXLAN_TTL, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LEARNING] = g_param_spec_boolean(NM_DEVICE_VXLAN_LEARNING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_AGEING] = g_param_spec_uint(NM_DEVICE_VXLAN_AGEING, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LIMIT] = g_param_spec_uint(NM_DEVICE_VXLAN_LIMIT, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SRC_PORT_MIN] = + g_param_spec_uint(NM_DEVICE_VXLAN_SRC_PORT_MIN, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SRC_PORT_MAX] = + g_param_spec_uint(NM_DEVICE_VXLAN_SRC_PORT_MAX, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_DST_PORT] = g_param_spec_uint(NM_DEVICE_VXLAN_DST_PORT, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_PROXY] = g_param_spec_boolean(NM_DEVICE_VXLAN_PROXY, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_RSC] = g_param_spec_boolean(NM_DEVICE_VXLAN_RSC, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_L2MISS] = g_param_spec_boolean(NM_DEVICE_VXLAN_L2MISS, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_L3MISS] = g_param_spec_boolean(NM_DEVICE_VXLAN_L3MISS, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ -#define NM_TYPE_VXLAN_DEVICE_FACTORY (nm_vxlan_device_factory_get_type ()) -#define NM_VXLAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VXLAN_DEVICE_FACTORY, NMVxlanDeviceFactory)) +#define NM_TYPE_VXLAN_DEVICE_FACTORY (nm_vxlan_device_factory_get_type()) +#define NM_VXLAN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_VXLAN_DEVICE_FACTORY, NMVxlanDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "Vxlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VXLAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_VXLAN, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_VXLAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Vxlan", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_VXLAN, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_VXLAN, + NULL); } static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) { - NMSettingVxlan *s_vxlan; + NMSettingVxlan *s_vxlan; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); - s_vxlan = nm_connection_get_setting_vxlan (connection); - g_assert (s_vxlan); + s_vxlan = nm_connection_get_setting_vxlan(connection); + g_assert(s_vxlan); - return nm_setting_vxlan_get_parent (s_vxlan); + return nm_setting_vxlan_get_parent(s_vxlan); } static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) +get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - const char *ifname; - NMSettingVxlan *s_vxlan; + const char * ifname; + NMSettingVxlan *s_vxlan; - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); - s_vxlan = nm_connection_get_setting_vxlan (connection); - g_assert (s_vxlan); + s_vxlan = nm_connection_get_setting_vxlan(connection); + g_assert(s_vxlan); - if (nm_setting_vxlan_get_parent (s_vxlan) && !parent_iface) - return NULL; + if (nm_setting_vxlan_get_parent(s_vxlan) && !parent_iface) + return NULL; - ifname = nm_connection_get_interface_name (connection); - return g_strdup (ifname); + ifname = nm_connection_get_interface_name(connection); + return g_strdup(ifname); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (VXLAN, Vxlan, vxlan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_VXLAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_VXLAN_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + VXLAN, + Vxlan, + vxlan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VXLAN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_VXLAN_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent; + factory_class->get_connection_iface = get_connection_iface;); diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index a36bdf49..89683b02 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013, 2014 Red Hat, Inc. */ @@ -8,12 +8,15 @@ #include "nm-device-generic.h" -#define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type ()) -#define NM_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) -#define NM_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) -#define NM_IS_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VXLAN)) -#define NM_IS_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VXLAN)) -#define NM_DEVICE_VXLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) +#define NM_TYPE_DEVICE_VXLAN (nm_device_vxlan_get_type()) +#define NM_DEVICE_VXLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlan)) +#define NM_DEVICE_VXLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) +#define NM_IS_DEVICE_VXLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VXLAN)) +#define NM_IS_DEVICE_VXLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VXLAN)) +#define NM_DEVICE_VXLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanClass)) #define NM_DEVICE_VXLAN_ID "id" #define NM_DEVICE_VXLAN_GROUP "group" @@ -31,9 +34,9 @@ #define NM_DEVICE_VXLAN_L2MISS "l2miss" #define NM_DEVICE_VXLAN_L3MISS "l3miss" -typedef struct _NMDeviceVxlan NMDeviceVxlan; +typedef struct _NMDeviceVxlan NMDeviceVxlan; typedef struct _NMDeviceVxlanClass NMDeviceVxlanClass; -GType nm_device_vxlan_get_type (void); +GType nm_device_vxlan_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_VXLAN_H__ */ diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c index 9f01a763..9bd23e65 100644 --- a/src/devices/nm-device-wireguard.c +++ b/src/devices/nm-device-wireguard.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Javier Arteaga */ @@ -32,9 +32,9 @@ _LOG_DECLARE_SELF(NMDeviceWireGuard); * prompt, as the secret is cached (good??). */ /* TODO: unlike for other VPNs, we don't inject a direct route to the peers. That means, - * you might get a routing sceneraio where the peer (VPN server) is reachable via the VPN. + * you might get a routing scenario where the peer (VPN server) is reachable via the VPN. * How we handle adding routes to external gateway for other peers, has severe issues - * as well. We may use policy-routing like wg-quick does. See also disussions at + * as well. We may use policy-routing like wg-quick does. See also discussions at * https://www.wireguard.com/netns/#improving-the-classic-solutions */ /* TODO: honor the TTL of DNS to determine when to retry resolving endpoints. */ @@ -46,8 +46,8 @@ _LOG_DECLARE_SELF(NMDeviceWireGuard); /*****************************************************************************/ -G_STATIC_ASSERT (NM_WIREGUARD_PUBLIC_KEY_LEN == NMP_WIREGUARD_PUBLIC_KEY_LEN); -G_STATIC_ASSERT (NM_WIREGUARD_SYMMETRIC_KEY_LEN == NMP_WIREGUARD_SYMMETRIC_KEY_LEN); +G_STATIC_ASSERT(NM_WIREGUARD_PUBLIC_KEY_LEN == NMP_WIREGUARD_PUBLIC_KEY_LEN); +G_STATIC_ASSERT(NM_WIREGUARD_SYMMETRIC_KEY_LEN == NMP_WIREGUARD_SYMMETRIC_KEY_LEN); /*****************************************************************************/ @@ -62,1962 +62,1965 @@ G_STATIC_ASSERT (NM_WIREGUARD_SYMMETRIC_KEY_LEN == NMP_WIREGUARD_SYMMETRIC_KEY_L #define NEXT_TRY_AT_NSEC_PAST ((gint64) 1) /* like %NEXT_TRY_AT_NSEC_ASAP, but used for indicating to retry ASAP for a @retry_in_msec value. - * That is a relative time duraction, contrary to @next_try_at_nsec which is an absolute + * That is a relative time duration, contrary to @next_try_at_nsec which is an absolute * timestamp. */ #define RETRY_IN_MSEC_ASAP ((gint64) G_MAXINT64) -#define RETRY_IN_MSEC_MAX ((gint64) (30 * 60 * 1000)) +#define RETRY_IN_MSEC_MAX ((gint64)(30 * 60 * 1000)) typedef enum { - LINK_CONFIG_MODE_FULL, - LINK_CONFIG_MODE_REAPPLY, - LINK_CONFIG_MODE_ASSUME, - LINK_CONFIG_MODE_ENDPOINTS, + LINK_CONFIG_MODE_FULL, + LINK_CONFIG_MODE_REAPPLY, + LINK_CONFIG_MODE_ASSUME, + LINK_CONFIG_MODE_ENDPOINTS, } LinkConfigMode; typedef struct { - GCancellable *cancellable; - - NMSockAddrUnion sockaddr; - - /* the timestamp (in nm_utils_get_monotonic_timestamp_nsec() scale) when we want - * to retry resolving the endpoint (again). - * - * It may be set to %NEXT_TRY_AT_NSEC_ASAP to indicate to re-resolve as soon as possible. - * - * A @sockaddr is either fixed or it has - * - @cancellable set to indicate an ongoing request - * - @next_try_at_nsec set to a positive value, indicating when - * we ought to retry. */ - gint64 next_try_at_nsec; - - guint resolv_fail_count; + GCancellable *cancellable; + + NMSockAddrUnion sockaddr; + + /* the timestamp (in nm_utils_get_monotonic_timestamp_nsec() scale) when we want + * to retry resolving the endpoint (again). + * + * It may be set to %NEXT_TRY_AT_NSEC_ASAP to indicate to re-resolve as soon as possible. + * + * A @sockaddr is either fixed or it has + * - @cancellable set to indicate an ongoing request + * - @next_try_at_nsec set to a positive value, indicating when + * we ought to retry. */ + gint64 next_try_at_nsec; + + guint resolv_fail_count; } PeerEndpointResolveData; typedef struct { - NMWireGuardPeer *peer; + NMWireGuardPeer *peer; - NMDeviceWireGuard *self; + NMDeviceWireGuard *self; - CList lst_peers; + CList lst_peers; - PeerEndpointResolveData ep_resolv; + PeerEndpointResolveData ep_resolv; - /* dirty flag used during _peers_update_all(). */ - bool dirty_update_all:1; + /* dirty flag used during _peers_update_all(). */ + bool dirty_update_all : 1; } PeerData; -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWireGuard, - PROP_PUBLIC_KEY, - PROP_LISTEN_PORT, - PROP_FWMARK, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceWireGuard, PROP_PUBLIC_KEY, PROP_LISTEN_PORT, PROP_FWMARK, ); typedef struct { + NMDnsManager *dns_manager; - NMDnsManager *dns_manager; + NMPlatformLnkWireGuard lnk_curr; + NMActRequestGetSecretsCallId *secrets_call_id; - NMPlatformLnkWireGuard lnk_curr; - NMActRequestGetSecretsCallId *secrets_call_id; + CList lst_peers_head; + GHashTable *peers; - CList lst_peers_head; - GHashTable *peers; + gint64 resolve_next_try_at; + gint64 link_config_last_at; - gint64 resolve_next_try_at; - gint64 link_config_last_at; + guint resolve_next_try_id; + guint link_config_delayed_id; - guint resolve_next_try_id; - guint link_config_delayed_id; + guint32 auto_default_route_fwmark; - guint32 auto_default_route_fwmark; + guint32 auto_default_route_priority; - guint32 auto_default_route_priority; - - bool auto_default_route_enabled_4:1; - bool auto_default_route_enabled_6:1; - bool auto_default_route_initialized:1; - bool auto_default_route_refresh:1; - bool auto_default_route_priority_initialized:1; + bool auto_default_route_enabled_4 : 1; + bool auto_default_route_enabled_6 : 1; + bool auto_default_route_initialized : 1; + bool auto_default_route_refresh : 1; + bool auto_default_route_priority_initialized : 1; } NMDeviceWireGuardPrivate; struct _NMDeviceWireGuard { - NMDevice parent; - NMDeviceWireGuardPrivate _priv; + NMDevice parent; + NMDeviceWireGuardPrivate _priv; }; struct _NMDeviceWireGuardClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE) -#define NM_DEVICE_WIREGUARD_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceWireGuard, NM_IS_DEVICE_WIREGUARD, NMDevice) +#define NM_DEVICE_WIREGUARD_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWireGuard, NM_IS_DEVICE_WIREGUARD, NMDevice) /*****************************************************************************/ -static void _peers_resolve_start (NMDeviceWireGuard *self, - PeerData *peer_data); +static void _peers_resolve_start(NMDeviceWireGuard *self, PeerData *peer_data); -static void _peers_resolve_retry_reschedule (NMDeviceWireGuard *self, - gint64 new_next_try_at_nsec); +static void _peers_resolve_retry_reschedule(NMDeviceWireGuard *self, gint64 new_next_try_at_nsec); -static gboolean link_config_delayed_resolver_cb (gpointer user_data); +static gboolean link_config_delayed_resolver_cb(gpointer user_data); -static gboolean link_config_delayed_ratelimit_cb (gpointer user_data); +static gboolean link_config_delayed_ratelimit_cb(gpointer user_data); /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (_link_config_mode_to_string, LinkConfigMode, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT (NULL), - NM_UTILS_LOOKUP_ITEM (LINK_CONFIG_MODE_FULL, "full"), - NM_UTILS_LOOKUP_ITEM (LINK_CONFIG_MODE_REAPPLY, "reapply"), - NM_UTILS_LOOKUP_ITEM (LINK_CONFIG_MODE_ASSUME, "assume"), - NM_UTILS_LOOKUP_ITEM (LINK_CONFIG_MODE_ENDPOINTS, "endpoints"), -); +static NM_UTILS_LOOKUP_STR_DEFINE(_link_config_mode_to_string, + LinkConfigMode, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(NULL), + NM_UTILS_LOOKUP_ITEM(LINK_CONFIG_MODE_FULL, "full"), + NM_UTILS_LOOKUP_ITEM(LINK_CONFIG_MODE_REAPPLY, "reapply"), + NM_UTILS_LOOKUP_ITEM(LINK_CONFIG_MODE_ASSUME, "assume"), + NM_UTILS_LOOKUP_ITEM(LINK_CONFIG_MODE_ENDPOINTS, "endpoints"), ); /*****************************************************************************/ static void -_auto_default_route_get_enabled (NMSettingWireGuard *s_wg, - NMConnection *connection, - gboolean *out_enabled_v4, - gboolean *out_enabled_v6) +_auto_default_route_get_enabled(NMSettingWireGuard *s_wg, + NMConnection * connection, + gboolean * out_enabled_v4, + gboolean * out_enabled_v6) { - NMTernary enabled_v4; - NMTernary enabled_v6; - - enabled_v4 = nm_setting_wireguard_get_ip4_auto_default_route (s_wg); - enabled_v6 = nm_setting_wireguard_get_ip6_auto_default_route (s_wg); - - if (enabled_v4 == NM_TERNARY_DEFAULT) { - if (nm_setting_ip_config_get_never_default (nm_connection_get_setting_ip_config (connection, AF_INET))) - enabled_v4 = FALSE; - } - if (enabled_v6 == NM_TERNARY_DEFAULT) { - if (nm_setting_ip_config_get_never_default (nm_connection_get_setting_ip_config (connection, AF_INET6))) - enabled_v6 = FALSE; - } - - if ( enabled_v4 == NM_TERNARY_DEFAULT - || enabled_v6 == NM_TERNARY_DEFAULT) { - guint i, n_peers; - - n_peers = nm_setting_wireguard_get_peers_len (s_wg); - for (i = 0; i < n_peers; i++) { - NMWireGuardPeer *peer = nm_setting_wireguard_get_peer (s_wg, i); - guint n_aips; - guint j; - - n_aips = nm_wireguard_peer_get_allowed_ips_len (peer); - for (j = 0; j < n_aips; j++) { - const char *aip; - gboolean valid; - int prefix; - int addr_family; - - aip = nm_wireguard_peer_get_allowed_ip (peer, j, &valid); - if (!valid) - continue; - if (!nm_utils_parse_inaddr_prefix_bin (AF_UNSPEC, - aip, - &addr_family, - NULL, - &prefix)) - continue; - if (prefix != 0) - continue; - - if (addr_family == AF_INET) { - if (enabled_v4 == NM_TERNARY_DEFAULT) { - enabled_v4 = TRUE; - if (enabled_v6 != NM_TERNARY_DEFAULT) - goto done; - } - } else { - if (enabled_v6 == NM_TERNARY_DEFAULT) { - enabled_v6 = TRUE; - if (enabled_v4 != NM_TERNARY_DEFAULT) - goto done; - } - } - } - } -done: - ; - } - - *out_enabled_v4 = (enabled_v4 == TRUE); - *out_enabled_v6 = (enabled_v6 == TRUE); + NMTernary enabled_v4; + NMTernary enabled_v6; + + enabled_v4 = nm_setting_wireguard_get_ip4_auto_default_route(s_wg); + enabled_v6 = nm_setting_wireguard_get_ip6_auto_default_route(s_wg); + + if (enabled_v4 == NM_TERNARY_DEFAULT) { + if (nm_setting_ip_config_get_never_default( + nm_connection_get_setting_ip_config(connection, AF_INET))) + enabled_v4 = FALSE; + } + if (enabled_v6 == NM_TERNARY_DEFAULT) { + if (nm_setting_ip_config_get_never_default( + nm_connection_get_setting_ip_config(connection, AF_INET6))) + enabled_v6 = FALSE; + } + + if (enabled_v4 == NM_TERNARY_DEFAULT || enabled_v6 == NM_TERNARY_DEFAULT) { + guint i, n_peers; + + n_peers = nm_setting_wireguard_get_peers_len(s_wg); + for (i = 0; i < n_peers; i++) { + NMWireGuardPeer *peer = nm_setting_wireguard_get_peer(s_wg, i); + guint n_aips; + guint j; + + n_aips = nm_wireguard_peer_get_allowed_ips_len(peer); + for (j = 0; j < n_aips; j++) { + const char *aip; + gboolean valid; + int prefix; + int addr_family; + + aip = nm_wireguard_peer_get_allowed_ip(peer, j, &valid); + if (!valid) + continue; + if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, aip, &addr_family, NULL, &prefix)) + continue; + if (prefix != 0) + continue; + + if (addr_family == AF_INET) { + if (enabled_v4 == NM_TERNARY_DEFAULT) { + enabled_v4 = TRUE; + if (enabled_v6 != NM_TERNARY_DEFAULT) + goto done; + } + } else { + if (enabled_v6 == NM_TERNARY_DEFAULT) { + enabled_v6 = TRUE; + if (enabled_v4 != NM_TERNARY_DEFAULT) + goto done; + } + } + } + } +done:; + } + + *out_enabled_v4 = (enabled_v4 == TRUE); + *out_enabled_v6 = (enabled_v6 == TRUE); } #define AUTO_RANDOM_RANGE 500u static guint32 -_auto_default_route_get_auto_fwmark (const char *uuid) +_auto_default_route_get_auto_fwmark(const char *uuid) { - guint64 rnd_seed; - - /* we use the generated number as fwmark but also as routing table for - * the default-route. - * - * We pick a number - * - * - based on the connection's UUID (as stable seed). - * - larger than 51820u (arbitrarily) - * - one out of AUTO_RANDOM_RANGE - */ - - rnd_seed = c_siphash_hash (NM_HASH_SEED_16 (0xb9, 0x39, 0x8e, 0xed, 0x15, 0xb3, 0xd1, 0xc4, 0x5f, 0x45, 0x00, 0x4f, 0xec, 0xc2, 0x2b, 0x7e), - (const guint8 *) uuid, - uuid ? strlen (uuid) + 1u : 0u); - - return 51820u + (rnd_seed % AUTO_RANDOM_RANGE); + guint64 rnd_seed; + + /* we use the generated number as fwmark but also as routing table for + * the default-route. + * + * We pick a number + * + * - based on the connection's UUID (as stable seed). + * - larger than 51820u (arbitrarily) + * - one out of AUTO_RANDOM_RANGE + */ + + rnd_seed = c_siphash_hash(NM_HASH_SEED_16(0xb9, + 0x39, + 0x8e, + 0xed, + 0x15, + 0xb3, + 0xd1, + 0xc4, + 0x5f, + 0x45, + 0x00, + 0x4f, + 0xec, + 0xc2, + 0x2b, + 0x7e), + (const guint8 *) uuid, + uuid ? strlen(uuid) + 1u : 0u); + + return 51820u + (rnd_seed % AUTO_RANDOM_RANGE); } #define PRIO_WIDTH 2u static guint32 -_auto_default_route_get_auto_priority (const char *uuid) +_auto_default_route_get_auto_priority(const char *uuid) { - const guint32 RANGE_TOP = 32766u - 1000u; - guint64 rnd_seed; - - /* we pick a priority for the routing rules as follows: - * - * - use the connection's UUID as stable seed for the "random" number. - * - have it smaller than RANGE_TOP (32766u - 1000u), where 32766u is the priority of the default - * rules - * - we add 2 rules (PRIO_WIDTH). Hence only pick even priorites. - * - pick one out of AUTO_RANDOM_RANGE. */ - - rnd_seed = c_siphash_hash (NM_HASH_SEED_16 (0x99, 0x22, 0x4d, 0x7c, 0x37, 0xda, 0x8e, 0x7b, 0x2f, 0x55, 0x16, 0x7b, 0x75, 0xda, 0x42, 0xdc), - (const guint8 *) uuid, - uuid ? strlen (uuid) + 1u : 0u); - - return RANGE_TOP - (((rnd_seed % (PRIO_WIDTH * AUTO_RANDOM_RANGE)) / PRIO_WIDTH) * PRIO_WIDTH); + const guint32 RANGE_TOP = 32766u - 1000u; + guint64 rnd_seed; + + /* we pick a priority for the routing rules as follows: + * + * - use the connection's UUID as stable seed for the "random" number. + * - have it smaller than RANGE_TOP (32766u - 1000u), where 32766u is the priority of the default + * rules + * - we add 2 rules (PRIO_WIDTH). Hence only pick even priorities. + * - pick one out of AUTO_RANDOM_RANGE. */ + + rnd_seed = c_siphash_hash(NM_HASH_SEED_16(0x99, + 0x22, + 0x4d, + 0x7c, + 0x37, + 0xda, + 0x8e, + 0x7b, + 0x2f, + 0x55, + 0x16, + 0x7b, + 0x75, + 0xda, + 0x42, + 0xdc), + (const guint8 *) uuid, + uuid ? strlen(uuid) + 1u : 0u); + + return RANGE_TOP - (((rnd_seed % (PRIO_WIDTH * AUTO_RANDOM_RANGE)) / PRIO_WIDTH) * PRIO_WIDTH); } static void -_auto_default_route_init (NMDeviceWireGuard *self) +_auto_default_route_init(NMDeviceWireGuard *self) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - NMConnection *connection; - gboolean enabled_v4 = FALSE; - gboolean enabled_v6 = FALSE; - gboolean refreshing_only; - guint32 new_fwmark = 0; - guint32 old_fwmark; - char sbuf1[100]; - - if (G_LIKELY ( priv->auto_default_route_initialized - && !priv->auto_default_route_refresh)) - return; - - refreshing_only = priv->auto_default_route_initialized - && priv->auto_default_route_refresh; - - old_fwmark = priv->auto_default_route_fwmark; - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - if (connection) { - NMSettingWireGuard *s_wg; - - s_wg = _nm_connection_get_setting (connection, NM_TYPE_SETTING_WIREGUARD); - - new_fwmark = nm_setting_wireguard_get_fwmark (s_wg); - - _auto_default_route_get_enabled (s_wg, - connection, - &enabled_v4, - &enabled_v6); - } - - if ( ( enabled_v4 - || enabled_v6) - && new_fwmark == 0u) { - if (refreshing_only) - new_fwmark = old_fwmark; - else - new_fwmark = _auto_default_route_get_auto_fwmark (nm_connection_get_uuid (connection)); - } - - priv->auto_default_route_refresh = FALSE; - priv->auto_default_route_fwmark = new_fwmark; - priv->auto_default_route_enabled_4 = enabled_v4; - priv->auto_default_route_enabled_6 = enabled_v6; - priv->auto_default_route_initialized = TRUE; - - if (connection) { - _LOGT (LOGD_DEVICE, - "auto-default-route is %s for IPv4 and %s for IPv6%s", - priv->auto_default_route_enabled_4 ? "enabled" : "disabled", - priv->auto_default_route_enabled_6 ? "enabled" : "disabled", - priv->auto_default_route_enabled_4 || priv->auto_default_route_enabled_6 - ? nm_sprintf_buf (sbuf1, " (fwmark 0x%x)", priv->auto_default_route_fwmark) - : ""); - } + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + NMConnection * connection; + gboolean enabled_v4 = FALSE; + gboolean enabled_v6 = FALSE; + gboolean refreshing_only; + guint32 new_fwmark = 0; + guint32 old_fwmark; + char sbuf1[100]; + + if (G_LIKELY(priv->auto_default_route_initialized && !priv->auto_default_route_refresh)) + return; + + refreshing_only = priv->auto_default_route_initialized && priv->auto_default_route_refresh; + + old_fwmark = priv->auto_default_route_fwmark; + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + if (connection) { + NMSettingWireGuard *s_wg; + + s_wg = _nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD); + + new_fwmark = nm_setting_wireguard_get_fwmark(s_wg); + + _auto_default_route_get_enabled(s_wg, connection, &enabled_v4, &enabled_v6); + } + + if ((enabled_v4 || enabled_v6) && new_fwmark == 0u) { + if (refreshing_only) + new_fwmark = old_fwmark; + else + new_fwmark = _auto_default_route_get_auto_fwmark(nm_connection_get_uuid(connection)); + } + + priv->auto_default_route_refresh = FALSE; + priv->auto_default_route_fwmark = new_fwmark; + priv->auto_default_route_enabled_4 = enabled_v4; + priv->auto_default_route_enabled_6 = enabled_v6; + priv->auto_default_route_initialized = TRUE; + + if (connection) { + _LOGT(LOGD_DEVICE, + "auto-default-route is %s for IPv4 and %s for IPv6%s", + priv->auto_default_route_enabled_4 ? "enabled" : "disabled", + priv->auto_default_route_enabled_6 ? "enabled" : "disabled", + priv->auto_default_route_enabled_4 || priv->auto_default_route_enabled_6 + ? nm_sprintf_buf(sbuf1, " (fwmark 0x%x)", priv->auto_default_route_fwmark) + : ""); + } } static GPtrArray * -get_extra_rules (NMDevice *device) +get_extra_rules(NMDevice *device) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (device); - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *extra_rules = NULL; - guint32 priority = 0; - int is_ipv4; - NMConnection *connection; - - _auto_default_route_init (self); - - connection = nm_device_get_applied_connection (device); - if (!connection) - return NULL; - - for (is_ipv4 = 0; is_ipv4 < 2; is_ipv4++) { - NMSettingIPConfig *s_ip; - int addr_family = is_ipv4 ? AF_INET : AF_INET6; - guint32 table_main; - guint32 fwmark; - - if (is_ipv4) { - if (!priv->auto_default_route_enabled_4) - continue; - } else { - if (!priv->auto_default_route_enabled_6) - continue; - } - - if (!extra_rules) { - if (priv->auto_default_route_priority_initialized) - priority = priv->auto_default_route_priority; - else { - priority = _auto_default_route_get_auto_priority (nm_connection_get_uuid (connection)); - priv->auto_default_route_priority = priority; - priv->auto_default_route_priority_initialized = TRUE; - } - extra_rules = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - } - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - table_main = nm_setting_ip_config_get_route_table (s_ip); - if (table_main == 0) - table_main = RT_TABLE_MAIN; - - fwmark = priv->auto_default_route_fwmark; - - G_STATIC_ASSERT_EXPR (PRIO_WIDTH == 2); - - g_ptr_array_add (extra_rules, - nmp_object_new (NMP_OBJECT_TYPE_ROUTING_RULE, - &((const NMPlatformRoutingRule) { - .priority = priority, - .addr_family = addr_family, - .action = FR_ACT_TO_TBL, - .table = table_main, - .suppress_prefixlen_inverse = ~((guint32) 0u), - }))); - - g_ptr_array_add (extra_rules, - nmp_object_new (NMP_OBJECT_TYPE_ROUTING_RULE, - &((const NMPlatformRoutingRule) { - .priority = priority + 1u, - .addr_family = addr_family, - .action = FR_ACT_TO_TBL, - .table = fwmark, - .flags = FIB_RULE_INVERT, - .fwmark = fwmark, - .fwmask = 0xFFFFFFFFu, - }))); - } - - return g_steal_pointer (&extra_rules); + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(device); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *extra_rules = NULL; + guint32 priority = 0; + int is_ipv4; + NMConnection * connection; + + _auto_default_route_init(self); + + connection = nm_device_get_applied_connection(device); + if (!connection) + return NULL; + + for (is_ipv4 = 0; is_ipv4 < 2; is_ipv4++) { + NMSettingIPConfig *s_ip; + int addr_family = is_ipv4 ? AF_INET : AF_INET6; + guint32 table_main; + guint32 fwmark; + + if (is_ipv4) { + if (!priv->auto_default_route_enabled_4) + continue; + } else { + if (!priv->auto_default_route_enabled_6) + continue; + } + + if (!extra_rules) { + if (priv->auto_default_route_priority_initialized) + priority = priv->auto_default_route_priority; + else { + priority = + _auto_default_route_get_auto_priority(nm_connection_get_uuid(connection)); + priv->auto_default_route_priority = priority; + priv->auto_default_route_priority_initialized = TRUE; + } + extra_rules = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + } + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + table_main = nm_setting_ip_config_get_route_table(s_ip); + if (table_main == 0) + table_main = RT_TABLE_MAIN; + + fwmark = priv->auto_default_route_fwmark; + + G_STATIC_ASSERT_EXPR(PRIO_WIDTH == 2); + + g_ptr_array_add(extra_rules, + nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, + &((const NMPlatformRoutingRule){ + .priority = priority, + .addr_family = addr_family, + .action = FR_ACT_TO_TBL, + .table = table_main, + .suppress_prefixlen_inverse = ~((guint32) 0u), + }))); + + g_ptr_array_add(extra_rules, + nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, + &((const NMPlatformRoutingRule){ + .priority = priority + 1u, + .addr_family = addr_family, + .action = FR_ACT_TO_TBL, + .table = fwmark, + .flags = FIB_RULE_INVERT, + .fwmark = fwmark, + .fwmask = 0xFFFFFFFFu, + }))); + } + + return g_steal_pointer(&extra_rules); } static guint32 -coerce_route_table (NMDevice *device, - int addr_family, - guint32 route_table, - gboolean is_user_config) +coerce_route_table(NMDevice *device, int addr_family, guint32 route_table, gboolean is_user_config) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (device); - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - gboolean auto_default_route_enabled; + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(device); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + gboolean auto_default_route_enabled; - if (route_table != 0u) - return route_table; + if (route_table != 0u) + return route_table; - _auto_default_route_init (self); + _auto_default_route_init(self); - auto_default_route_enabled = (addr_family == AF_INET) - ? priv->auto_default_route_enabled_4 - : priv->auto_default_route_enabled_6; + auto_default_route_enabled = (addr_family == AF_INET) ? priv->auto_default_route_enabled_4 + : priv->auto_default_route_enabled_6; - if (auto_default_route_enabled) { - /* we need to enable full-sync mode of all routing tables. */ - _LOGT (LOGD_DEVICE, "coerce ipv%c.route-table setting to \"main\" (table 254) as we enable auto-default-route handling", - nm_utils_addr_family_to_char (addr_family)); - return RT_TABLE_MAIN; - } + if (auto_default_route_enabled) { + /* we need to enable full-sync mode of all routing tables. */ + _LOGT(LOGD_DEVICE, + "coerce ipv%c.route-table setting to \"main\" (table 254) as we enable " + "auto-default-route handling", + nm_utils_addr_family_to_char(addr_family)); + return RT_TABLE_MAIN; + } - return 0; + return 0; } /*****************************************************************************/ static gboolean -_peer_data_equal (gconstpointer ptr_a, gconstpointer ptr_b) +_peer_data_equal(gconstpointer ptr_a, gconstpointer ptr_b) { - const PeerData *peer_data_a = ptr_a; - const PeerData *peer_data_b = ptr_b; + const PeerData *peer_data_a = ptr_a; + const PeerData *peer_data_b = ptr_b; - return nm_streq (nm_wireguard_peer_get_public_key (peer_data_a->peer), - nm_wireguard_peer_get_public_key (peer_data_b->peer)); + return nm_streq(nm_wireguard_peer_get_public_key(peer_data_a->peer), + nm_wireguard_peer_get_public_key(peer_data_b->peer)); } static guint -_peer_data_hash (gconstpointer ptr) +_peer_data_hash(gconstpointer ptr) { - const PeerData *peer_data = ptr; + const PeerData *peer_data = ptr; - return nm_hash_str (nm_wireguard_peer_get_public_key (peer_data->peer)); + return nm_hash_str(nm_wireguard_peer_get_public_key(peer_data->peer)); } static PeerData * -_peers_find (NMDeviceWireGuardPrivate *priv, - NMWireGuardPeer *peer) +_peers_find(NMDeviceWireGuardPrivate *priv, NMWireGuardPeer *peer) { - nm_assert (peer); + nm_assert(peer); - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (PeerData, peer) == 0); + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(PeerData, peer) == 0); - return g_hash_table_lookup (priv->peers, &peer); + return g_hash_table_lookup(priv->peers, &peer); } static void -_peers_remove (NMDeviceWireGuardPrivate *priv, - PeerData *peer_data) +_peers_remove(NMDeviceWireGuardPrivate *priv, PeerData *peer_data) { - nm_assert (peer_data); - nm_assert (g_hash_table_lookup (priv->peers, peer_data) == peer_data); + nm_assert(peer_data); + nm_assert(g_hash_table_lookup(priv->peers, peer_data) == peer_data); - if (!g_hash_table_remove (priv->peers, peer_data)) - nm_assert_not_reached (); + if (!g_hash_table_remove(priv->peers, peer_data)) + nm_assert_not_reached(); - c_list_unlink_stale (&peer_data->lst_peers); - nm_wireguard_peer_unref (peer_data->peer); - nm_clear_g_cancellable (&peer_data->ep_resolv.cancellable); - g_slice_free (PeerData, peer_data); + c_list_unlink_stale(&peer_data->lst_peers); + nm_wireguard_peer_unref(peer_data->peer); + nm_clear_g_cancellable(&peer_data->ep_resolv.cancellable); + g_slice_free(PeerData, peer_data); - if (c_list_is_empty (&priv->lst_peers_head)) { - nm_clear_g_source (&priv->resolve_next_try_id); - nm_clear_g_source (&priv->link_config_delayed_id); - } + if (c_list_is_empty(&priv->lst_peers_head)) { + nm_clear_g_source(&priv->resolve_next_try_id); + nm_clear_g_source(&priv->link_config_delayed_id); + } } static PeerData * -_peers_add (NMDeviceWireGuard *self, - NMWireGuardPeer *peer) +_peers_add(NMDeviceWireGuard *self, NMWireGuardPeer *peer) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - PeerData *peer_data; - - nm_assert (peer); - nm_assert (nm_wireguard_peer_is_sealed (peer)); - nm_assert (!_peers_find (priv, peer)); - - peer_data = g_slice_new (PeerData); - *peer_data = (PeerData) { - .self = self, - .peer = nm_wireguard_peer_ref (peer), - .ep_resolv = { - .sockaddr = NM_SOCK_ADDR_UNION_INIT_UNSPEC, - }, - }; - - c_list_link_tail (&priv->lst_peers_head, &peer_data->lst_peers); - if (!nm_g_hash_table_add (priv->peers, peer_data)) - nm_assert_not_reached (); - return peer_data; + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + PeerData * peer_data; + + nm_assert(peer); + nm_assert(nm_wireguard_peer_is_sealed(peer)); + nm_assert(!_peers_find(priv, peer)); + + peer_data = g_slice_new(PeerData); + *peer_data = (PeerData){ + .self = self, + .peer = nm_wireguard_peer_ref(peer), + .ep_resolv = + { + .sockaddr = NM_SOCK_ADDR_UNION_INIT_UNSPEC, + }, + }; + + c_list_link_tail(&priv->lst_peers_head, &peer_data->lst_peers); + if (!nm_g_hash_table_add(priv->peers, peer_data)) + nm_assert_not_reached(); + return peer_data; } static gboolean -_peers_resolve_retry_timeout (gpointer user_data) +_peers_resolve_retry_timeout(gpointer user_data) { - NMDeviceWireGuard *self = user_data; - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - PeerData *peer_data; - gint64 now; - gint64 next; - - priv->resolve_next_try_id = 0; - - _LOGT (LOGD_DEVICE, "wireguard-peers: rechecking peer endpoints..."); - - now = nm_utils_get_monotonic_timestamp_nsec (); - next = G_MAXINT64; - c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { - if (peer_data->ep_resolv.next_try_at_nsec <= 0) - continue; - - if (peer_data->ep_resolv.cancellable) { - /* we are currently resolving a name. We don't need the global - * watchdog to guard this peer. No need to adjust @next for - * this one, when the currently ongoing resolving completes, we - * may reschedule. Skip. */ - continue; - } - - if ( peer_data->ep_resolv.next_try_at_nsec == NEXT_TRY_AT_NSEC_ASAP - || now >= peer_data->ep_resolv.next_try_at_nsec) { - _peers_resolve_start (self, peer_data); - /* same here. Now we are resolving. We don't need the global - * watchdog. Skip w.r.t. finding @next. */ - continue; - } - - if (next > peer_data->ep_resolv.next_try_at_nsec) - next = peer_data->ep_resolv.next_try_at_nsec; - } - if (next < G_MAXINT64) - _peers_resolve_retry_reschedule (self, next); - - return G_SOURCE_REMOVE; + NMDeviceWireGuard * self = user_data; + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + PeerData * peer_data; + gint64 now; + gint64 next; + + priv->resolve_next_try_id = 0; + + _LOGT(LOGD_DEVICE, "wireguard-peers: rechecking peer endpoints..."); + + now = nm_utils_get_monotonic_timestamp_nsec(); + next = G_MAXINT64; + c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { + if (peer_data->ep_resolv.next_try_at_nsec <= 0) + continue; + + if (peer_data->ep_resolv.cancellable) { + /* we are currently resolving a name. We don't need the global + * watchdog to guard this peer. No need to adjust @next for + * this one, when the currently ongoing resolving completes, we + * may reschedule. Skip. */ + continue; + } + + if (peer_data->ep_resolv.next_try_at_nsec == NEXT_TRY_AT_NSEC_ASAP + || now >= peer_data->ep_resolv.next_try_at_nsec) { + _peers_resolve_start(self, peer_data); + /* same here. Now we are resolving. We don't need the global + * watchdog. Skip w.r.t. finding @next. */ + continue; + } + + if (next > peer_data->ep_resolv.next_try_at_nsec) + next = peer_data->ep_resolv.next_try_at_nsec; + } + if (next < G_MAXINT64) + _peers_resolve_retry_reschedule(self, next); + + return G_SOURCE_REMOVE; } static void -_peers_resolve_retry_reschedule (NMDeviceWireGuard *self, - gint64 new_next_try_at_nsec) +_peers_resolve_retry_reschedule(NMDeviceWireGuard *self, gint64 new_next_try_at_nsec) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - guint32 interval_ms; - gint64 now; - - nm_assert (new_next_try_at_nsec > 0); - nm_assert (new_next_try_at_nsec != NEXT_TRY_AT_NSEC_ASAP); - - if ( priv->resolve_next_try_id - && priv->resolve_next_try_at <= new_next_try_at_nsec) { - /* we already have an earlier timeout scheduled (possibly for - * another peer that expires sooner). Don't reschedule now. - * Even if the scheduled timeout expires too early, we will - * compute the right next-timeout and reschedule then. */ - return; - } - - now = nm_utils_get_monotonic_timestamp_nsec (); - - /* schedule at most one day ahead. No problem if we expire earlier - * than expected. Also, rate-limit to 500 msec. */ - interval_ms = NM_CLAMP ((new_next_try_at_nsec - now) / NM_UTILS_NSEC_PER_MSEC, - (gint64) 500, - (gint64) (24*60*60*1000)); - - _LOGT (LOGD_DEVICE, "wireguard-peers: schedule rechecking peer endpoints in %u msec", - interval_ms); - - nm_clear_g_source (&priv->resolve_next_try_id); - priv->resolve_next_try_at = new_next_try_at_nsec; - priv->resolve_next_try_id = g_timeout_add (interval_ms, - _peers_resolve_retry_timeout, - self); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + guint32 interval_ms; + gint64 now; + + nm_assert(new_next_try_at_nsec > 0); + nm_assert(new_next_try_at_nsec != NEXT_TRY_AT_NSEC_ASAP); + + if (priv->resolve_next_try_id && priv->resolve_next_try_at <= new_next_try_at_nsec) { + /* we already have an earlier timeout scheduled (possibly for + * another peer that expires sooner). Don't reschedule now. + * Even if the scheduled timeout expires too early, we will + * compute the right next-timeout and reschedule then. */ + return; + } + + now = nm_utils_get_monotonic_timestamp_nsec(); + + /* schedule at most one day ahead. No problem if we expire earlier + * than expected. Also, rate-limit to 500 msec. */ + interval_ms = NM_CLAMP((new_next_try_at_nsec - now) / NM_UTILS_NSEC_PER_MSEC, + (gint64) 500, + (gint64)(24 * 60 * 60 * 1000)); + + _LOGT(LOGD_DEVICE, + "wireguard-peers: schedule rechecking peer endpoints in %u msec", + interval_ms); + + nm_clear_g_source(&priv->resolve_next_try_id); + priv->resolve_next_try_at = new_next_try_at_nsec; + priv->resolve_next_try_id = g_timeout_add(interval_ms, _peers_resolve_retry_timeout, self); } static void -_peers_resolve_retry_reschedule_for_peer (NMDeviceWireGuard *self, - PeerData *peer_data, - gint64 retry_in_msec) +_peers_resolve_retry_reschedule_for_peer(NMDeviceWireGuard *self, + PeerData * peer_data, + gint64 retry_in_msec) { - nm_assert (retry_in_msec >= 0); + nm_assert(retry_in_msec >= 0); - if (retry_in_msec == RETRY_IN_MSEC_ASAP) { - _peers_resolve_start (self, peer_data); - return; - } + if (retry_in_msec == RETRY_IN_MSEC_ASAP) { + _peers_resolve_start(self, peer_data); + return; + } - peer_data->ep_resolv.next_try_at_nsec = nm_utils_get_monotonic_timestamp_nsec () - + (retry_in_msec * NM_UTILS_NSEC_PER_MSEC); - _peers_resolve_retry_reschedule (self, peer_data->ep_resolv.next_try_at_nsec); + peer_data->ep_resolv.next_try_at_nsec = + nm_utils_get_monotonic_timestamp_nsec() + (retry_in_msec * NM_UTILS_NSEC_PER_MSEC); + _peers_resolve_retry_reschedule(self, peer_data->ep_resolv.next_try_at_nsec); } static gint64 -_peers_retry_in_msec (PeerData *peer_data, - gboolean after_failure) +_peers_retry_in_msec(PeerData *peer_data, gboolean after_failure) { - if (peer_data->ep_resolv.next_try_at_nsec == NEXT_TRY_AT_NSEC_ASAP) { - peer_data->ep_resolv.resolv_fail_count = 0; - return RETRY_IN_MSEC_ASAP; - } - - if (after_failure) { - if (peer_data->ep_resolv.resolv_fail_count < G_MAXUINT) - peer_data->ep_resolv.resolv_fail_count++; - } else - peer_data->ep_resolv.resolv_fail_count = 0; - - if (!after_failure) - return RETRY_IN_MSEC_MAX; - - if (peer_data->ep_resolv.resolv_fail_count > 20) - return RETRY_IN_MSEC_MAX; - - /* double the retry-time, starting with one second. */ - return NM_MIN (RETRY_IN_MSEC_MAX, - (1u << peer_data->ep_resolv.resolv_fail_count) * 500); + if (peer_data->ep_resolv.next_try_at_nsec == NEXT_TRY_AT_NSEC_ASAP) { + peer_data->ep_resolv.resolv_fail_count = 0; + return RETRY_IN_MSEC_ASAP; + } + + if (after_failure) { + if (peer_data->ep_resolv.resolv_fail_count < G_MAXUINT) + peer_data->ep_resolv.resolv_fail_count++; + } else + peer_data->ep_resolv.resolv_fail_count = 0; + + if (!after_failure) + return RETRY_IN_MSEC_MAX; + + if (peer_data->ep_resolv.resolv_fail_count > 20) + return RETRY_IN_MSEC_MAX; + + /* double the retry-time, starting with one second. */ + return NM_MIN(RETRY_IN_MSEC_MAX, (1u << peer_data->ep_resolv.resolv_fail_count) * 500); } static void -_peers_resolve_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_peers_resolve_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMDeviceWireGuard *self; - PeerData *peer_data; - gs_free_error GError *resolv_error = NULL; - GList *list; - gboolean changed = FALSE; - NMSockAddrUnion sockaddr; - gint64 retry_in_msec; - char s_sockaddr[100]; - char s_retry[100]; - - list = g_resolver_lookup_by_name_finish (G_RESOLVER (source_object), res, &resolv_error); - - if (nm_utils_error_is_cancelled (resolv_error)) - return; - - peer_data = user_data; - self = peer_data->self; - - g_clear_object (&peer_data->ep_resolv.cancellable); - - nm_assert ((!resolv_error) != (!list)); - -#define _retry_in_msec_to_string(retry_in_msec, s_retry) \ - ({ \ - gint64 _retry_in_msec = (retry_in_msec); \ - \ - _retry_in_msec == RETRY_IN_MSEC_ASAP \ - ? "right away" \ - : nm_sprintf_buf (s_retry, "in %"G_GINT64_FORMAT" msec", _retry_in_msec); \ - }) - - if ( resolv_error - && !g_error_matches (resolv_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND)) { - retry_in_msec = _peers_retry_in_msec (peer_data, TRUE); - - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: failure to resolve endpoint \"%s\": %s (retry %s)", - nm_wireguard_peer_get_public_key (peer_data->peer), - nm_wireguard_peer_get_endpoint (peer_data->peer), - resolv_error->message, - _retry_in_msec_to_string (retry_in_msec, s_retry)); - - _peers_resolve_retry_reschedule_for_peer (self, peer_data, retry_in_msec); - return; - } - - sockaddr = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; - - if (!resolv_error) { - GList *iter; - - for (iter = list; iter; iter = iter->next) { - GInetAddress *a = iter->data; - GSocketFamily f = g_inet_address_get_family (a); - - if (f == G_SOCKET_FAMILY_IPV4) { - nm_assert (g_inet_address_get_native_size (a) == sizeof (struct in_addr)); - sockaddr.in = (struct sockaddr_in) { - .sin_family = AF_INET, - .sin_port = htons (nm_sock_addr_endpoint_get_port (_nm_wireguard_peer_get_endpoint (peer_data->peer))), - }; - memcpy (&sockaddr.in.sin_addr, g_inet_address_to_bytes (a), sizeof (struct in_addr)); - break; - } - if (f == G_SOCKET_FAMILY_IPV6) { - nm_assert (g_inet_address_get_native_size (a) == sizeof (struct in6_addr)); - sockaddr.in6 = (struct sockaddr_in6) { - .sin6_family = AF_INET6, - .sin6_port = htons (nm_sock_addr_endpoint_get_port (_nm_wireguard_peer_get_endpoint (peer_data->peer))), - .sin6_scope_id = 0, - .sin6_flowinfo = 0, - }; - memcpy (&sockaddr.in6.sin6_addr, g_inet_address_to_bytes (a), sizeof (struct in6_addr)); - break; - } - } - - g_list_free_full (list, g_object_unref); - } - - if (sockaddr.sa.sa_family == AF_UNSPEC) { - /* we failed to resolve the name. There is no need to reset the previous - * sockaddr. Either it was already AF_UNSPEC, or we had a good name - * from resolving before. In that case, we don't want to throw away - * a possibly good IP address, since WireGuard supports automatic roaming - * anyway. Either the IP address is still good (and we would wrongly - * reject it), or it isn't -- in which case it does not hurt much. */ - } else { - if (nm_sock_addr_union_cmp (&peer_data->ep_resolv.sockaddr, &sockaddr) != 0) - changed = TRUE; - peer_data->ep_resolv.sockaddr = sockaddr; - } - - if ( resolv_error - || peer_data->ep_resolv.sockaddr.sa.sa_family == AF_UNSPEC) { - /* while it technically did not fail, something is probably odd. Retry frequently to - * resolve the name, like we would do for normal failures. */ - retry_in_msec = _peers_retry_in_msec (peer_data, TRUE); - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: no %sresults for endpoint \"%s\" (retry %s)", - nm_wireguard_peer_get_public_key (peer_data->peer), - resolv_error ? "" : "suitable ", - nm_wireguard_peer_get_endpoint (peer_data->peer), - _retry_in_msec_to_string (retry_in_msec, s_retry)); - } else { - retry_in_msec = _peers_retry_in_msec (peer_data, FALSE); - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: endpoint \"%s\" resolved to %s (retry %s)", - nm_wireguard_peer_get_public_key (peer_data->peer), - nm_wireguard_peer_get_endpoint (peer_data->peer), - nm_sock_addr_union_to_string (&peer_data->ep_resolv.sockaddr, s_sockaddr, sizeof (s_sockaddr)), - _retry_in_msec_to_string (retry_in_msec, s_retry)); - } - - _peers_resolve_retry_reschedule_for_peer (self, peer_data, retry_in_msec); - - if (changed) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - - /* schedule the job in the background, to give multiple resolve events time - * to complete. */ - nm_clear_g_source (&priv->link_config_delayed_id); - priv->link_config_delayed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, - link_config_delayed_resolver_cb, - self, - NULL); - } + NMDeviceWireGuard *self; + PeerData * peer_data; + gs_free_error GError *resolv_error = NULL; + GList * list; + gboolean changed = FALSE; + NMSockAddrUnion sockaddr; + gint64 retry_in_msec; + char s_sockaddr[100]; + char s_retry[100]; + + list = g_resolver_lookup_by_name_finish(G_RESOLVER(source_object), res, &resolv_error); + + if (nm_utils_error_is_cancelled(resolv_error)) + return; + + peer_data = user_data; + self = peer_data->self; + + g_clear_object(&peer_data->ep_resolv.cancellable); + + nm_assert((!resolv_error) != (!list)); + +#define _retry_in_msec_to_string(retry_in_msec, s_retry) \ + ({ \ + gint64 _retry_in_msec = (retry_in_msec); \ + \ + _retry_in_msec == RETRY_IN_MSEC_ASAP \ + ? "right away" \ + : nm_sprintf_buf(s_retry, "in %" G_GINT64_FORMAT " msec", _retry_in_msec); \ + }) + + if (resolv_error + && !g_error_matches(resolv_error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND)) { + retry_in_msec = _peers_retry_in_msec(peer_data, TRUE); + + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: failure to resolve endpoint \"%s\": %s (retry %s)", + nm_wireguard_peer_get_public_key(peer_data->peer), + nm_wireguard_peer_get_endpoint(peer_data->peer), + resolv_error->message, + _retry_in_msec_to_string(retry_in_msec, s_retry)); + + _peers_resolve_retry_reschedule_for_peer(self, peer_data, retry_in_msec); + return; + } + + sockaddr = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + + if (!resolv_error) { + GList *iter; + + for (iter = list; iter; iter = iter->next) { + GInetAddress *a = iter->data; + GSocketFamily f = g_inet_address_get_family(a); + + if (f == G_SOCKET_FAMILY_IPV4) { + nm_assert(g_inet_address_get_native_size(a) == sizeof(struct in_addr)); + sockaddr.in = (struct sockaddr_in){ + .sin_family = AF_INET, + .sin_port = htons(nm_sock_addr_endpoint_get_port( + _nm_wireguard_peer_get_endpoint(peer_data->peer))), + }; + memcpy(&sockaddr.in.sin_addr, g_inet_address_to_bytes(a), sizeof(struct in_addr)); + break; + } + if (f == G_SOCKET_FAMILY_IPV6) { + nm_assert(g_inet_address_get_native_size(a) == sizeof(struct in6_addr)); + sockaddr.in6 = (struct sockaddr_in6){ + .sin6_family = AF_INET6, + .sin6_port = htons(nm_sock_addr_endpoint_get_port( + _nm_wireguard_peer_get_endpoint(peer_data->peer))), + .sin6_scope_id = 0, + .sin6_flowinfo = 0, + }; + memcpy(&sockaddr.in6.sin6_addr, + g_inet_address_to_bytes(a), + sizeof(struct in6_addr)); + break; + } + } + + g_list_free_full(list, g_object_unref); + } + + if (sockaddr.sa.sa_family == AF_UNSPEC) { + /* we failed to resolve the name. There is no need to reset the previous + * sockaddr. Either it was already AF_UNSPEC, or we had a good name + * from resolving before. In that case, we don't want to throw away + * a possibly good IP address, since WireGuard supports automatic roaming + * anyway. Either the IP address is still good (and we would wrongly + * reject it), or it isn't -- in which case it does not hurt much. */ + } else { + if (nm_sock_addr_union_cmp(&peer_data->ep_resolv.sockaddr, &sockaddr) != 0) + changed = TRUE; + peer_data->ep_resolv.sockaddr = sockaddr; + } + + if (resolv_error || peer_data->ep_resolv.sockaddr.sa.sa_family == AF_UNSPEC) { + /* while it technically did not fail, something is probably odd. Retry frequently to + * resolve the name, like we would do for normal failures. */ + retry_in_msec = _peers_retry_in_msec(peer_data, TRUE); + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: no %sresults for endpoint \"%s\" (retry %s)", + nm_wireguard_peer_get_public_key(peer_data->peer), + resolv_error ? "" : "suitable ", + nm_wireguard_peer_get_endpoint(peer_data->peer), + _retry_in_msec_to_string(retry_in_msec, s_retry)); + } else { + retry_in_msec = _peers_retry_in_msec(peer_data, FALSE); + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: endpoint \"%s\" resolved to %s (retry %s)", + nm_wireguard_peer_get_public_key(peer_data->peer), + nm_wireguard_peer_get_endpoint(peer_data->peer), + nm_sock_addr_union_to_string(&peer_data->ep_resolv.sockaddr, + s_sockaddr, + sizeof(s_sockaddr)), + _retry_in_msec_to_string(retry_in_msec, s_retry)); + } + + _peers_resolve_retry_reschedule_for_peer(self, peer_data, retry_in_msec); + + if (changed) { + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + + /* schedule the job in the background, to give multiple resolve events time + * to complete. */ + nm_clear_g_source(&priv->link_config_delayed_id); + priv->link_config_delayed_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE + 1, + link_config_delayed_resolver_cb, + self, + NULL); + } } static void -_peers_resolve_start (NMDeviceWireGuard *self, - PeerData *peer_data) +_peers_resolve_start(NMDeviceWireGuard *self, PeerData *peer_data) { - gs_unref_object GResolver *resolver = NULL; - const char *host; + gs_unref_object GResolver *resolver = NULL; + const char * host; - resolver = g_resolver_get_default (); + resolver = g_resolver_get_default(); - nm_assert (!peer_data->ep_resolv.cancellable); + nm_assert(!peer_data->ep_resolv.cancellable); - peer_data->ep_resolv.cancellable = g_cancellable_new (); + peer_data->ep_resolv.cancellable = g_cancellable_new(); - /* set a special next-try timestamp. It is positive, and indicates - * that we are in the process of trying. - * This timestamp however already lies in the past, but that is correct, - * because we are currently in the process of trying. We will determine - * a next-try timestamp once the try completes. */ - peer_data->ep_resolv.next_try_at_nsec = NEXT_TRY_AT_NSEC_PAST; + /* set a special next-try timestamp. It is positive, and indicates + * that we are in the process of trying. + * This timestamp however already lies in the past, but that is correct, + * because we are currently in the process of trying. We will determine + * a next-try timestamp once the try completes. */ + peer_data->ep_resolv.next_try_at_nsec = NEXT_TRY_AT_NSEC_PAST; - host = nm_sock_addr_endpoint_get_host (_nm_wireguard_peer_get_endpoint (peer_data->peer)); + host = nm_sock_addr_endpoint_get_host(_nm_wireguard_peer_get_endpoint(peer_data->peer)); - g_resolver_lookup_by_name_async (resolver, - host, - peer_data->ep_resolv.cancellable, - _peers_resolve_cb, - peer_data); + g_resolver_lookup_by_name_async(resolver, + host, + peer_data->ep_resolv.cancellable, + _peers_resolve_cb, + peer_data); - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: resolving name \"%s\" for endpoint \"%s\"...", - nm_wireguard_peer_get_public_key (peer_data->peer), - host, - nm_wireguard_peer_get_endpoint (peer_data->peer)); + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: resolving name \"%s\" for endpoint \"%s\"...", + nm_wireguard_peer_get_public_key(peer_data->peer), + host, + nm_wireguard_peer_get_endpoint(peer_data->peer)); } static void -_peers_resolve_reresolve_all (NMDeviceWireGuard *self) +_peers_resolve_reresolve_all(NMDeviceWireGuard *self) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - PeerData *peer_data; - - c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { - if (peer_data->ep_resolv.cancellable) { - /* remember to retry when the currently ongoing request completes. */ - peer_data->ep_resolv.next_try_at_nsec = NEXT_TRY_AT_NSEC_ASAP; - } else if (peer_data->ep_resolv.next_try_at_nsec <= 0) { - /* this peer does not require resolving the name. Skip it. */ - } else { - /* we have a next-try scheduled. Restart right away. */ - peer_data->ep_resolv.resolv_fail_count = 0; - _peers_resolve_start (self, peer_data); - } - } + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + PeerData * peer_data; + + c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { + if (peer_data->ep_resolv.cancellable) { + /* remember to retry when the currently ongoing request completes. */ + peer_data->ep_resolv.next_try_at_nsec = NEXT_TRY_AT_NSEC_ASAP; + } else if (peer_data->ep_resolv.next_try_at_nsec <= 0) { + /* this peer does not require resolving the name. Skip it. */ + } else { + /* we have a next-try scheduled. Restart right away. */ + peer_data->ep_resolv.resolv_fail_count = 0; + _peers_resolve_start(self, peer_data); + } + } } static gboolean -_peers_update (NMDeviceWireGuard *self, - PeerData *peer_data, - NMWireGuardPeer *peer, - gboolean force_update) +_peers_update(NMDeviceWireGuard *self, + PeerData * peer_data, + NMWireGuardPeer * peer, + gboolean force_update) { - nm_auto_unref_wgpeer NMWireGuardPeer *old_peer = NULL; - NMSockAddrEndpoint *old_endpoint; - NMSockAddrEndpoint *endpoint; - gboolean endpoint_changed = FALSE; - gboolean changed; - NMSockAddrUnion sockaddr; - gboolean sockaddr_fixed; - char sockaddr_sbuf[100]; - - nm_assert (peer); - nm_assert (nm_wireguard_peer_is_sealed (peer)); - - if ( peer == peer_data->peer - && !force_update) - return FALSE; - - changed = (nm_wireguard_peer_cmp (peer, - peer_data->peer, - NM_SETTING_COMPARE_FLAG_EXACT) != 0); - - old_peer = peer_data->peer; - peer_data->peer = nm_wireguard_peer_ref (peer); - - old_endpoint = old_peer ? _nm_wireguard_peer_get_endpoint (old_peer) : NULL; - endpoint = peer ? _nm_wireguard_peer_get_endpoint (peer) : NULL; - - endpoint_changed = ( endpoint != old_endpoint - && ( !old_endpoint - || !endpoint - || !nm_streq (nm_sock_addr_endpoint_get_endpoint (old_endpoint), - nm_sock_addr_endpoint_get_endpoint (endpoint)))); - - if ( !force_update - && !endpoint_changed) { - /* nothing to do. */ - return changed; - } - - sockaddr = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; - sockaddr_fixed = TRUE; - if ( endpoint - && nm_sock_addr_endpoint_get_host (endpoint)) { - if (!nm_sock_addr_endpoint_get_fixed_sockaddr (endpoint, &sockaddr)) { - /* we have an endpoint, but it's not a static IP address. We need to resolve - * the names. */ - sockaddr_fixed = FALSE; - } - } - - if (nm_sock_addr_union_cmp (&peer_data->ep_resolv.sockaddr, &sockaddr) != 0) - changed = TRUE; - - nm_clear_g_cancellable (&peer_data->ep_resolv.cancellable); - - peer_data->ep_resolv = (PeerEndpointResolveData) { - .sockaddr = sockaddr, - .resolv_fail_count = 0, - .cancellable = NULL, - .next_try_at_nsec = 0, - }; - - if (!endpoint) { - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: no endpoint configured", - nm_wireguard_peer_get_public_key (peer_data->peer)); - } else if (!nm_sock_addr_endpoint_get_host (endpoint)) { - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: invalid endpoint \"%s\"", - nm_wireguard_peer_get_public_key (peer_data->peer), - nm_sock_addr_endpoint_get_endpoint (endpoint)); - } else if (sockaddr_fixed) { - _LOGT (LOGD_DEVICE, "wireguard-peer[%s]: fixed endpoint \"%s\" (%s)", - nm_wireguard_peer_get_public_key (peer_data->peer), - nm_sock_addr_endpoint_get_endpoint (endpoint), - nm_sock_addr_union_to_string (&peer_data->ep_resolv.sockaddr, sockaddr_sbuf, sizeof (sockaddr_sbuf))); - } else - _peers_resolve_start (self, peer_data); - - return changed; + nm_auto_unref_wgpeer NMWireGuardPeer *old_peer = NULL; + NMSockAddrEndpoint * old_endpoint; + NMSockAddrEndpoint * endpoint; + gboolean endpoint_changed = FALSE; + gboolean changed; + NMSockAddrUnion sockaddr; + gboolean sockaddr_fixed; + char sockaddr_sbuf[100]; + + nm_assert(peer); + nm_assert(nm_wireguard_peer_is_sealed(peer)); + + if (peer == peer_data->peer && !force_update) + return FALSE; + + changed = (nm_wireguard_peer_cmp(peer, peer_data->peer, NM_SETTING_COMPARE_FLAG_EXACT) != 0); + + old_peer = peer_data->peer; + peer_data->peer = nm_wireguard_peer_ref(peer); + + old_endpoint = old_peer ? _nm_wireguard_peer_get_endpoint(old_peer) : NULL; + endpoint = peer ? _nm_wireguard_peer_get_endpoint(peer) : NULL; + + endpoint_changed = (endpoint != old_endpoint + && (!old_endpoint || !endpoint + || !nm_streq(nm_sock_addr_endpoint_get_endpoint(old_endpoint), + nm_sock_addr_endpoint_get_endpoint(endpoint)))); + + if (!force_update && !endpoint_changed) { + /* nothing to do. */ + return changed; + } + + sockaddr = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + sockaddr_fixed = TRUE; + if (endpoint && nm_sock_addr_endpoint_get_host(endpoint)) { + if (!nm_sock_addr_endpoint_get_fixed_sockaddr(endpoint, &sockaddr)) { + /* we have an endpoint, but it's not a static IP address. We need to resolve + * the names. */ + sockaddr_fixed = FALSE; + } + } + + if (nm_sock_addr_union_cmp(&peer_data->ep_resolv.sockaddr, &sockaddr) != 0) + changed = TRUE; + + nm_clear_g_cancellable(&peer_data->ep_resolv.cancellable); + + peer_data->ep_resolv = (PeerEndpointResolveData){ + .sockaddr = sockaddr, + .resolv_fail_count = 0, + .cancellable = NULL, + .next_try_at_nsec = 0, + }; + + if (!endpoint) { + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: no endpoint configured", + nm_wireguard_peer_get_public_key(peer_data->peer)); + } else if (!nm_sock_addr_endpoint_get_host(endpoint)) { + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: invalid endpoint \"%s\"", + nm_wireguard_peer_get_public_key(peer_data->peer), + nm_sock_addr_endpoint_get_endpoint(endpoint)); + } else if (sockaddr_fixed) { + _LOGT(LOGD_DEVICE, + "wireguard-peer[%s]: fixed endpoint \"%s\" (%s)", + nm_wireguard_peer_get_public_key(peer_data->peer), + nm_sock_addr_endpoint_get_endpoint(endpoint), + nm_sock_addr_union_to_string(&peer_data->ep_resolv.sockaddr, + sockaddr_sbuf, + sizeof(sockaddr_sbuf))); + } else + _peers_resolve_start(self, peer_data); + + return changed; } static void -_peers_remove_all (NMDeviceWireGuardPrivate *priv) +_peers_remove_all(NMDeviceWireGuardPrivate *priv) { - PeerData *peer_data; + PeerData *peer_data; - while ((peer_data = c_list_first_entry (&priv->lst_peers_head, PeerData, lst_peers))) - _peers_remove (priv, peer_data); + while ((peer_data = c_list_first_entry(&priv->lst_peers_head, PeerData, lst_peers))) + _peers_remove(priv, peer_data); } static void -_peers_update_all (NMDeviceWireGuard *self, - NMSettingWireGuard *s_wg, - gboolean *out_peers_removed) +_peers_update_all(NMDeviceWireGuard *self, NMSettingWireGuard *s_wg, gboolean *out_peers_removed) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - PeerData *peer_data_safe; - PeerData *peer_data; - guint i, n; - gboolean peers_removed = FALSE; - - c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) - peer_data->dirty_update_all = TRUE; - - n = nm_setting_wireguard_get_peers_len (s_wg); - for (i = 0; i < n; i++) { - NMWireGuardPeer *peer = nm_setting_wireguard_get_peer (s_wg, i); - gboolean added = FALSE; - - peer_data = _peers_find (priv, peer); - if (!peer_data) { - peer_data = _peers_add (self, peer); - added = TRUE; - } - _peers_update (self, peer_data, peer, added); - peer_data->dirty_update_all = FALSE; - } - - c_list_for_each_entry_safe (peer_data, peer_data_safe, &priv->lst_peers_head, lst_peers) { - if (peer_data->dirty_update_all) { - _peers_remove (priv, peer_data); - peers_removed = TRUE; - } - } - - NM_SET_OUT (out_peers_removed, peers_removed); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + PeerData * peer_data_safe; + PeerData * peer_data; + guint i, n; + gboolean peers_removed = FALSE; + + c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) + peer_data->dirty_update_all = TRUE; + + n = nm_setting_wireguard_get_peers_len(s_wg); + for (i = 0; i < n; i++) { + NMWireGuardPeer *peer = nm_setting_wireguard_get_peer(s_wg, i); + gboolean added = FALSE; + + peer_data = _peers_find(priv, peer); + if (!peer_data) { + peer_data = _peers_add(self, peer); + added = TRUE; + } + _peers_update(self, peer_data, peer, added); + peer_data->dirty_update_all = FALSE; + } + + c_list_for_each_entry_safe (peer_data, peer_data_safe, &priv->lst_peers_head, lst_peers) { + if (peer_data->dirty_update_all) { + _peers_remove(priv, peer_data); + peers_removed = TRUE; + } + } + + NM_SET_OUT(out_peers_removed, peers_removed); } static void -_peers_get_platform_list (NMDeviceWireGuardPrivate *priv, - LinkConfigMode config_mode, - NMPWireGuardPeer **out_peers, - NMPlatformWireGuardChangePeerFlags **out_peer_flags, - guint *out_len, - GArray **out_allowed_ips_data) +_peers_get_platform_list(NMDeviceWireGuardPrivate * priv, + LinkConfigMode config_mode, + NMPWireGuardPeer ** out_peers, + NMPlatformWireGuardChangePeerFlags **out_peer_flags, + guint * out_len, + GArray ** out_allowed_ips_data) { - gs_free NMPWireGuardPeer *plpeers = NULL; - gs_free NMPlatformWireGuardChangePeerFlags *plpeer_flags = NULL; - gs_unref_array GArray *allowed_ips = NULL; - PeerData *peer_data; - guint i_good; - guint n_aip; - guint i_aip; - guint len; - guint i; - - nm_assert (out_peers && !*out_peers); - nm_assert (out_peer_flags && !*out_peer_flags); - nm_assert (out_len && *out_len == 0); - nm_assert (out_allowed_ips_data && !*out_allowed_ips_data); - - len = g_hash_table_size (priv->peers); - - nm_assert (len == c_list_length (&priv->lst_peers_head)); - - if (len == 0) - return; - - plpeers = g_new0 (NMPWireGuardPeer, len); - plpeer_flags = g_new0 (NMPlatformWireGuardChangePeerFlags, len); - - i_good = 0; - c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { - NMPlatformWireGuardChangePeerFlags *plf = &plpeer_flags[i_good]; - NMPWireGuardPeer *plp = &plpeers[i_good]; - NMSettingSecretFlags psk_secret_flags; - - if (!nm_utils_base64secret_decode (nm_wireguard_peer_get_public_key (peer_data->peer), - sizeof (plp->public_key), - plp->public_key)) - continue; - - *plf = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE; - - plp->persistent_keepalive_interval = nm_wireguard_peer_get_persistent_keepalive (peer_data->peer); - if (NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL, - LINK_CONFIG_MODE_REAPPLY)) - *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL; - - /* if the peer has an endpoint but it is not yet resolved (not ready), - * we still configure it and leave the endpoint unspecified. Later, - * when we can resolve the endpoint, we will update. */ - plp->endpoint = peer_data->ep_resolv.sockaddr; - if (plp->endpoint.sa.sa_family == AF_UNSPEC) { - /* we don't actually ever clear endpoints, if we don't have better information. */ - } else - *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT; - - if (NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL, - LINK_CONFIG_MODE_REAPPLY)) { - psk_secret_flags = nm_wireguard_peer_get_preshared_key_flags (peer_data->peer); - if (!NM_FLAGS_HAS (psk_secret_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { - if ( !nm_utils_base64secret_decode (nm_wireguard_peer_get_preshared_key (peer_data->peer), - sizeof (plp->preshared_key), - plp->preshared_key) - && config_mode == LINK_CONFIG_MODE_FULL) - goto skip; - } - *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY; - } - - if ( NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL, - LINK_CONFIG_MODE_REAPPLY) - && ((n_aip = nm_wireguard_peer_get_allowed_ips_len (peer_data->peer)) > 0)) { - if (!allowed_ips) - allowed_ips = g_array_new (FALSE, FALSE, sizeof (NMPWireGuardAllowedIP)); - - *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS - | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS; - - plp->_construct_idx_start = allowed_ips->len; - for (i_aip = 0; i_aip < n_aip; i_aip++) { - const char *aip; - NMIPAddr addrbin = { }; - int addr_family; - gboolean valid; - int prefix; - - aip = nm_wireguard_peer_get_allowed_ip (peer_data->peer, i_aip, &valid); - if ( !valid - || !nm_utils_parse_inaddr_prefix_bin (AF_UNSPEC, - aip, - &addr_family, - &addrbin, - &prefix)) { - /* the address is really not expected to be invalid, because then - * the connection would not verify. Anyway, silently skip it. */ - continue; - } - - if (prefix == -1) - prefix = addr_family == AF_INET ? 32 : 128; - - g_array_append_val (allowed_ips, - ((NMPWireGuardAllowedIP) { - .family = addr_family, - .mask = prefix, - .addr = addrbin, - })); - } - plp->_construct_idx_end = allowed_ips->len; - } - - i_good++; - continue; + gs_free NMPWireGuardPeer *plpeers = NULL; + gs_free NMPlatformWireGuardChangePeerFlags *plpeer_flags = NULL; + gs_unref_array GArray *allowed_ips = NULL; + PeerData * peer_data; + guint i_good; + guint n_aip; + guint i_aip; + guint len; + guint i; + + nm_assert(out_peers && !*out_peers); + nm_assert(out_peer_flags && !*out_peer_flags); + nm_assert(out_len && *out_len == 0); + nm_assert(out_allowed_ips_data && !*out_allowed_ips_data); + + len = g_hash_table_size(priv->peers); + + nm_assert(len == c_list_length(&priv->lst_peers_head)); + + if (len == 0) + return; + + plpeers = g_new0(NMPWireGuardPeer, len); + plpeer_flags = g_new0(NMPlatformWireGuardChangePeerFlags, len); + + i_good = 0; + c_list_for_each_entry (peer_data, &priv->lst_peers_head, lst_peers) { + NMPlatformWireGuardChangePeerFlags *plf = &plpeer_flags[i_good]; + NMPWireGuardPeer * plp = &plpeers[i_good]; + NMSettingSecretFlags psk_secret_flags; + + if (!nm_utils_base64secret_decode(nm_wireguard_peer_get_public_key(peer_data->peer), + sizeof(plp->public_key), + plp->public_key)) + continue; + + *plf = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE; + + plp->persistent_keepalive_interval = + nm_wireguard_peer_get_persistent_keepalive(peer_data->peer); + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL, LINK_CONFIG_MODE_REAPPLY)) + *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL; + + /* if the peer has an endpoint but it is not yet resolved (not ready), + * we still configure it and leave the endpoint unspecified. Later, + * when we can resolve the endpoint, we will update. */ + plp->endpoint = peer_data->ep_resolv.sockaddr; + if (plp->endpoint.sa.sa_family == AF_UNSPEC) { + /* we don't actually ever clear endpoints, if we don't have better information. */ + } else + *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT; + + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL, LINK_CONFIG_MODE_REAPPLY)) { + psk_secret_flags = nm_wireguard_peer_get_preshared_key_flags(peer_data->peer); + if (!NM_FLAGS_HAS(psk_secret_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + if (!nm_utils_base64secret_decode( + nm_wireguard_peer_get_preshared_key(peer_data->peer), + sizeof(plp->preshared_key), + plp->preshared_key) + && config_mode == LINK_CONFIG_MODE_FULL) + goto skip; + } + *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY; + } + + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL, LINK_CONFIG_MODE_REAPPLY) + && ((n_aip = nm_wireguard_peer_get_allowed_ips_len(peer_data->peer)) > 0)) { + if (!allowed_ips) + allowed_ips = g_array_new(FALSE, FALSE, sizeof(NMPWireGuardAllowedIP)); + + *plf |= NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS + | NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS; + + plp->_construct_idx_start = allowed_ips->len; + for (i_aip = 0; i_aip < n_aip; i_aip++) { + const char *aip; + NMIPAddr addrbin = {}; + int addr_family; + gboolean valid; + int prefix; + + aip = nm_wireguard_peer_get_allowed_ip(peer_data->peer, i_aip, &valid); + if (!valid + || !nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, + aip, + &addr_family, + &addrbin, + &prefix)) { + /* the address is really not expected to be invalid, because then + * the connection would not verify. Anyway, silently skip it. */ + continue; + } + + if (prefix == -1) + prefix = addr_family == AF_INET ? 32 : 128; + + g_array_append_val(allowed_ips, + ((NMPWireGuardAllowedIP){ + .family = addr_family, + .mask = prefix, + .addr = addrbin, + })); + } + plp->_construct_idx_end = allowed_ips->len; + } + + i_good++; + continue; skip: - memset (plp, 0, sizeof (*plp)); - } - - if (i_good == 0) - return; - - for (i = 0; i < i_good; i++) { - NMPWireGuardPeer *plp = &plpeers[i]; - guint l; - - if (plp->_construct_idx_end == 0) { - nm_assert (plp->_construct_idx_start == 0); - plp->allowed_ips = NULL; - plp->allowed_ips_len = 0; - } else { - nm_assert (plp->_construct_idx_start < plp->_construct_idx_end); - l = plp->_construct_idx_end - plp->_construct_idx_start; - plp->allowed_ips = &g_array_index (allowed_ips, NMPWireGuardAllowedIP, plp->_construct_idx_start); - plp->allowed_ips_len = l; - } - } - *out_peers = g_steal_pointer (&plpeers); - *out_peer_flags = g_steal_pointer (&plpeer_flags);; - *out_len = i_good; - *out_allowed_ips_data = g_steal_pointer (&allowed_ips); + memset(plp, 0, sizeof(*plp)); + } + + if (i_good == 0) + return; + + for (i = 0; i < i_good; i++) { + NMPWireGuardPeer *plp = &plpeers[i]; + guint l; + + if (plp->_construct_idx_end == 0) { + nm_assert(plp->_construct_idx_start == 0); + plp->allowed_ips = NULL; + plp->allowed_ips_len = 0; + } else { + nm_assert(plp->_construct_idx_start < plp->_construct_idx_end); + l = plp->_construct_idx_end - plp->_construct_idx_start; + plp->allowed_ips = + &g_array_index(allowed_ips, NMPWireGuardAllowedIP, plp->_construct_idx_start); + plp->allowed_ips_len = l; + } + } + *out_peers = g_steal_pointer(&plpeers); + *out_peer_flags = g_steal_pointer(&plpeer_flags); + *out_len = i_good; + *out_allowed_ips_data = g_steal_pointer(&allowed_ips); } /*****************************************************************************/ static void -update_properties (NMDevice *device) +update_properties(NMDevice *device) { - NMDeviceWireGuard *self; - NMDeviceWireGuardPrivate *priv; - const NMPlatformLink *plink; - const NMPlatformLnkWireGuard *props = NULL; - int ifindex; - - g_return_if_fail (NM_IS_DEVICE_WIREGUARD (device)); - self = NM_DEVICE_WIREGUARD (device); - priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - - ifindex = nm_device_get_ifindex (device); - props = nm_platform_link_get_lnk_wireguard (nm_device_get_platform (device), ifindex, &plink); - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get wireguard properties"); - return; - } - - g_object_freeze_notify (G_OBJECT (device)); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (priv->lnk_curr.field != props->field) { \ - priv->lnk_curr.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - -#define CHECK_PROPERTY_CHANGED_ARRAY(field, prop) \ - G_STMT_START { \ - if (memcmp (&priv->lnk_curr.field, &props->field, sizeof (priv->lnk_curr.field)) != 0) { \ - memcpy (&priv->lnk_curr.field, &props->field, sizeof (priv->lnk_curr.field)); \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED_ARRAY (public_key, PROP_PUBLIC_KEY); - CHECK_PROPERTY_CHANGED (listen_port, PROP_LISTEN_PORT); - CHECK_PROPERTY_CHANGED (fwmark, PROP_FWMARK); - - g_object_thaw_notify (G_OBJECT (device)); + NMDeviceWireGuard * self; + NMDeviceWireGuardPrivate * priv; + const NMPlatformLink * plink; + const NMPlatformLnkWireGuard *props = NULL; + int ifindex; + + g_return_if_fail(NM_IS_DEVICE_WIREGUARD(device)); + self = NM_DEVICE_WIREGUARD(device); + priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + + ifindex = nm_device_get_ifindex(device); + props = nm_platform_link_get_lnk_wireguard(nm_device_get_platform(device), ifindex, &plink); + if (!props) { + _LOGW(LOGD_PLATFORM, "could not get wireguard properties"); + return; + } + + g_object_freeze_notify(G_OBJECT(device)); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->lnk_curr.field != props->field) { \ + priv->lnk_curr.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + +#define CHECK_PROPERTY_CHANGED_ARRAY(field, prop) \ + G_STMT_START \ + { \ + if (memcmp(&priv->lnk_curr.field, &props->field, sizeof(priv->lnk_curr.field)) != 0) { \ + memcpy(&priv->lnk_curr.field, &props->field, sizeof(priv->lnk_curr.field)); \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED_ARRAY(public_key, PROP_PUBLIC_KEY); + CHECK_PROPERTY_CHANGED(listen_port, PROP_LISTEN_PORT); + CHECK_PROPERTY_CHANGED(fwmark, PROP_FWMARK); + + g_object_thaw_notify(G_OBJECT(device)); } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->link_changed (device, pllink); - update_properties (device); + NM_DEVICE_CLASS(nm_device_wireguard_parent_class)->link_changed(device, pllink); + update_properties(device); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities(NMDevice *dev) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } /*****************************************************************************/ static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - int r; - - g_return_val_if_fail (iface, FALSE); - - r = nm_platform_link_wireguard_add (nm_device_get_platform (device), iface, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create WireGuard interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char *iface = nm_device_get_iface(device); + int r; + + g_return_val_if_fail(iface, FALSE); + + r = nm_platform_link_wireguard_add(nm_device_get_platform(device), iface, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create WireGuard interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -_secrets_cancel (NMDeviceWireGuard *self) +_secrets_cancel(NMDeviceWireGuard *self) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); - if (priv->secrets_call_id) - nm_act_request_cancel_secrets (NULL, priv->secrets_call_id); - nm_assert (!priv->secrets_call_id); + if (priv->secrets_call_id) + nm_act_request_cancel_secrets(NULL, priv->secrets_call_id); + nm_assert(!priv->secrets_call_id); } static void -_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *connection, - GError *error, - gpointer user_data) +_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * connection, + GError * error, + gpointer user_data) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (user_data); - NMDevice *device = NM_DEVICE (self); - NMDeviceWireGuardPrivate *priv; + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(user_data); + NMDevice * device = NM_DEVICE(self); + NMDeviceWireGuardPrivate *priv; - g_return_if_fail (NM_IS_DEVICE_WIREGUARD (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + g_return_if_fail(NM_IS_DEVICE_WIREGUARD(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); - priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); + priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); - g_return_if_fail (priv->secrets_call_id == call_id); + g_return_if_fail(priv->secrets_call_id == call_id); - priv->secrets_call_id = NULL; + priv->secrets_call_id = NULL; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - 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); - g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); + 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); + g_return_if_fail(nm_act_request_get_settings_connection(req) == connection); - if (error) { - _LOGW (LOGD_ETHER, "%s", error->message); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } + if (error) { + _LOGW(LOGD_ETHER, "%s", error->message); + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -_secrets_get_secrets (NMDeviceWireGuard *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *const*hints) +_secrets_get_secrets(NMDeviceWireGuard * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char *const * hints) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - NMActRequest *req; - - _secrets_cancel (self); - - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv->secrets_call_id = nm_act_request_get_secrets (req, - TRUE, - setting_name, - flags, - hints, - _secrets_cb, - self); - g_return_if_fail (priv->secrets_call_id); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + NMActRequest * req; + + _secrets_cancel(self); + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + + priv->secrets_call_id = + nm_act_request_get_secrets(req, TRUE, setting_name, flags, hints, _secrets_cb, self); + g_return_if_fail(priv->secrets_call_id); } static NMActStageReturn -_secrets_handle_auth_or_fail (NMDeviceWireGuard *self, - NMActRequest *req, - gboolean new_secrets) +_secrets_handle_auth_or_fail(NMDeviceWireGuard *self, NMActRequest *req, gboolean new_secrets) { - NMConnection *applied_connection; - const char *setting_name; - gs_unref_ptrarray GPtrArray *hints = NULL; - - if (!nm_device_auth_retries_try_next (NM_DEVICE (self))) - return NM_ACT_STAGE_RETURN_FAILURE; - - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - - 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, &hints); - if (!setting_name) { - _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (hints) - g_ptr_array_add (hints, NULL); - - _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), - ( hints - ? (const char *const*) hints->pdata - : NULL)); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMConnection * applied_connection; + const char * setting_name; + gs_unref_ptrarray GPtrArray *hints = NULL; + + if (!nm_device_auth_retries_try_next(NM_DEVICE(self))) + return NM_ACT_STAGE_RETURN_FAILURE; + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); + + 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, &hints); + if (!setting_name) { + _LOGI(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (hints) + g_ptr_array_add(hints, NULL); + + _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), + (hints ? (const char *const *) hints->pdata : NULL)); + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ static void -_dns_config_changed (NMDnsManager *dns_manager, NMDeviceWireGuard *self) +_dns_config_changed(NMDnsManager *dns_manager, NMDeviceWireGuard *self) { - /* when the DNS configuration changes, we re-resolve the peer addresses. - * - * Possibly, we should also do that when the default-route changes, but it's - * hard to figure out when that happens. */ - _peers_resolve_reresolve_all (self); + /* when the DNS configuration changes, we re-resolve the peer addresses. + * + * Possibly, we should also do that when the default-route changes, but it's + * hard to figure out when that happens. */ + _peers_resolve_reresolve_all(self); } /*****************************************************************************/ static NMActStageReturn -link_config (NMDeviceWireGuard *self, - const char *reason, - LinkConfigMode config_mode, - NMDeviceStateReason *out_failure_reason) +link_config(NMDeviceWireGuard * self, + const char * reason, + LinkConfigMode config_mode, + NMDeviceStateReason *out_failure_reason) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - nm_auto_bzero_secret_ptr NMSecretPtr wg_lnk_clear_private_key = NM_SECRET_PTR_INIT (); - NMSettingWireGuard *s_wg; - NMConnection *connection; - NMActStageReturn ret; - gs_unref_array GArray *allowed_ips_data = NULL; - NMPlatformLnkWireGuard wg_lnk; - gs_free NMPWireGuardPeer *plpeers = NULL; - gs_free NMPlatformWireGuardChangePeerFlags *plpeer_flags = NULL; - guint plpeers_len = 0; - const char *setting_name; - gboolean peers_removed; - NMPlatformWireGuardChangeFlags wg_change_flags; - int ifindex; - int r; - - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NONE); - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - s_wg = NM_SETTING_WIREGUARD (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIREGUARD)); - g_return_val_if_fail (s_wg, NM_ACT_STAGE_RETURN_FAILURE); - - priv->link_config_last_at = nm_utils_get_monotonic_timestamp_nsec (); - - _LOGT (LOGD_DEVICE, "wireguard link config (%s, %s)...", - reason, _link_config_mode_to_string (config_mode)); - - _auto_default_route_init (self); - - if (!priv->dns_manager) { - priv->dns_manager = g_object_ref (nm_dns_manager_get ()); - g_signal_connect (priv->dns_manager, NM_DNS_MANAGER_CONFIG_CHANGED, G_CALLBACK (_dns_config_changed), self); - } - - if ( NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL) - && (setting_name = nm_connection_need_secrets (connection, NULL))) { - NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self)); - - _LOGD (LOGD_DEVICE, - "Activation: connection '%s' has security, but secrets are required.", - nm_connection_get_id (connection)); - - ret = _secrets_handle_auth_or_fail (self, req, FALSE); - if (ret != NM_ACT_STAGE_RETURN_SUCCESS) { - if (ret != NM_ACT_STAGE_RETURN_POSTPONE) { - nm_assert (ret == NM_ACT_STAGE_RETURN_FAILURE); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - } - return ret; - } - } - - ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self)); - if (ifindex <= 0) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - _peers_update_all (self, s_wg, &peers_removed); - - wg_lnk = (NMPlatformLnkWireGuard) { }; - - wg_change_flags = NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE; - - if ( NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL) - || ( NM_IN_SET (config_mode, LINK_CONFIG_MODE_REAPPLY) - && peers_removed)) - wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS; - - if (NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL, - LINK_CONFIG_MODE_REAPPLY)) { - - wg_lnk.listen_port = nm_setting_wireguard_get_listen_port (s_wg); - wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT; - - wg_lnk.fwmark = priv->auto_default_route_fwmark; - wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK; - - if (nm_utils_base64secret_decode (nm_setting_wireguard_get_private_key (s_wg), - sizeof (wg_lnk.private_key), - wg_lnk.private_key)) { - wg_lnk_clear_private_key = NM_SECRET_PTR_ARRAY (wg_lnk.private_key); - wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY; - } else { - if (NM_IN_SET (config_mode, LINK_CONFIG_MODE_FULL)) { - _LOGD (LOGD_DEVICE, "the provided private-key is invalid"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - } - - _peers_get_platform_list (priv, - config_mode, - &plpeers, - &plpeer_flags, - &plpeers_len, - &allowed_ips_data); - - r = nm_platform_link_wireguard_change (nm_device_get_platform (NM_DEVICE (self)), - ifindex, - &wg_lnk, - plpeers, - plpeer_flags, - plpeers_len, - wg_change_flags); - - nm_explicit_bzero (plpeers, sizeof (plpeers[0]) * plpeers_len); - - if (r < 0) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceWireGuardPrivate * priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + nm_auto_bzero_secret_ptr NMSecretPtr wg_lnk_clear_private_key = NM_SECRET_PTR_INIT(); + NMSettingWireGuard * s_wg; + NMConnection * connection; + NMActStageReturn ret; + gs_unref_array GArray *allowed_ips_data = NULL; + NMPlatformLnkWireGuard wg_lnk; + gs_free NMPWireGuardPeer *plpeers = NULL; + gs_free NMPlatformWireGuardChangePeerFlags *plpeer_flags = NULL; + guint plpeers_len = 0; + const char * setting_name; + gboolean peers_removed; + NMPlatformWireGuardChangeFlags wg_change_flags; + int ifindex; + int r; + + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NONE); + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + s_wg = NM_SETTING_WIREGUARD(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD)); + g_return_val_if_fail(s_wg, NM_ACT_STAGE_RETURN_FAILURE); + + priv->link_config_last_at = nm_utils_get_monotonic_timestamp_nsec(); + + _LOGT(LOGD_DEVICE, + "wireguard link config (%s, %s)...", + reason, + _link_config_mode_to_string(config_mode)); + + _auto_default_route_init(self); + + if (!priv->dns_manager) { + priv->dns_manager = g_object_ref(nm_dns_manager_get()); + g_signal_connect(priv->dns_manager, + NM_DNS_MANAGER_CONFIG_CHANGED, + G_CALLBACK(_dns_config_changed), + self); + } + + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL) + && (setting_name = nm_connection_need_secrets(connection, NULL))) { + NMActRequest *req = nm_device_get_act_request(NM_DEVICE(self)); + + _LOGD(LOGD_DEVICE, + "Activation: connection '%s' has security, but secrets are required.", + nm_connection_get_id(connection)); + + ret = _secrets_handle_auth_or_fail(self, req, FALSE); + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) { + if (ret != NM_ACT_STAGE_RETURN_POSTPONE) { + nm_assert(ret == NM_ACT_STAGE_RETURN_FAILURE); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + } + return ret; + } + } + + ifindex = nm_device_get_ip_ifindex(NM_DEVICE(self)); + if (ifindex <= 0) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + _peers_update_all(self, s_wg, &peers_removed); + + wg_lnk = (NMPlatformLnkWireGuard){}; + + wg_change_flags = NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE; + + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL) + || (NM_IN_SET(config_mode, LINK_CONFIG_MODE_REAPPLY) && peers_removed)) + wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS; + + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL, LINK_CONFIG_MODE_REAPPLY)) { + wg_lnk.listen_port = nm_setting_wireguard_get_listen_port(s_wg); + wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT; + + wg_lnk.fwmark = priv->auto_default_route_fwmark; + wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK; + + if (nm_utils_base64secret_decode(nm_setting_wireguard_get_private_key(s_wg), + sizeof(wg_lnk.private_key), + wg_lnk.private_key)) { + wg_lnk_clear_private_key = NM_SECRET_PTR_ARRAY(wg_lnk.private_key); + wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY; + } else { + if (NM_IN_SET(config_mode, LINK_CONFIG_MODE_FULL)) { + _LOGD(LOGD_DEVICE, "the provided private-key is invalid"); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + } + + _peers_get_platform_list(priv, + config_mode, + &plpeers, + &plpeer_flags, + &plpeers_len, + &allowed_ips_data); + + r = nm_platform_link_wireguard_change(nm_device_get_platform(NM_DEVICE(self)), + ifindex, + &wg_lnk, + plpeers, + plpeer_flags, + plpeers_len, + wg_change_flags); + + nm_explicit_bzero(plpeers, sizeof(plpeers[0]) * plpeers_len); + + if (r < 0) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -link_config_delayed (NMDeviceWireGuard *self, - const char *reason) +link_config_delayed(NMDeviceWireGuard *self, const char *reason) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - gint64 now; - - priv->link_config_delayed_id = 0; - - if (priv->link_config_last_at != 0) { - now = nm_utils_get_monotonic_timestamp_nsec (); - if (now < priv->link_config_last_at + LINK_CONFIG_RATE_LIMIT_NSEC) { - /* we ratelimit calls to link_config(), because we call this whenever a resolver - * completes. */ - _LOGT (LOGD_DEVICE, "wireguard link config (%s) (postponed)", reason); - priv->link_config_delayed_id = g_timeout_add (NM_MAX ((priv->link_config_last_at + LINK_CONFIG_RATE_LIMIT_NSEC - now) / NM_UTILS_NSEC_PER_MSEC, - (gint64) 1), - link_config_delayed_ratelimit_cb, - self); - return; - } - } - - link_config (self, reason, LINK_CONFIG_MODE_ENDPOINTS, NULL); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + gint64 now; + + priv->link_config_delayed_id = 0; + + if (priv->link_config_last_at != 0) { + now = nm_utils_get_monotonic_timestamp_nsec(); + if (now < priv->link_config_last_at + LINK_CONFIG_RATE_LIMIT_NSEC) { + /* we ratelimit calls to link_config(), because we call this whenever a resolver + * completes. */ + _LOGT(LOGD_DEVICE, "wireguard link config (%s) (postponed)", reason); + priv->link_config_delayed_id = + g_timeout_add(NM_MAX((priv->link_config_last_at + LINK_CONFIG_RATE_LIMIT_NSEC - now) + / NM_UTILS_NSEC_PER_MSEC, + (gint64) 1), + link_config_delayed_ratelimit_cb, + self); + return; + } + } + + link_config(self, reason, LINK_CONFIG_MODE_ENDPOINTS, NULL); } static gboolean -link_config_delayed_ratelimit_cb (gpointer user_data) +link_config_delayed_ratelimit_cb(gpointer user_data) { - link_config_delayed (user_data, "after-ratelimiting"); - return G_SOURCE_REMOVE; + link_config_delayed(user_data, "after-ratelimiting"); + return G_SOURCE_REMOVE; } static gboolean -link_config_delayed_resolver_cb (gpointer user_data) +link_config_delayed_resolver_cb(gpointer user_data) { - link_config_delayed (user_data, "resolver-update"); - return G_SOURCE_REMOVE; + link_config_delayed(user_data, "resolver-update"); + return G_SOURCE_REMOVE; } static NMActStageReturn -act_stage2_config (NMDevice *device, - NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceSysIfaceState sys_iface_state; - NMDeviceStateReason failure_reason; - NMActStageReturn ret; - - sys_iface_state = nm_device_sys_iface_state_get (device); - - if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NONE); - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - ret = link_config (NM_DEVICE_WIREGUARD (device), - "configure", - (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) - ? LINK_CONFIG_MODE_ASSUME - : LINK_CONFIG_MODE_FULL, - &failure_reason); - - if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) { - /* this never fails. */ - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - failure_reason); - NM_SET_OUT (out_failure_reason, failure_reason); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return ret; + NMDeviceSysIfaceState sys_iface_state; + NMDeviceStateReason failure_reason; + NMActStageReturn ret; + + sys_iface_state = nm_device_sys_iface_state_get(device); + + if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NONE); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + ret = + link_config(NM_DEVICE_WIREGUARD(device), + "configure", + (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) ? LINK_CONFIG_MODE_ASSUME + : LINK_CONFIG_MODE_FULL, + &failure_reason); + + if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) { + /* this never fails. */ + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, failure_reason); + NM_SET_OUT(out_failure_reason, failure_reason); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return ret; } static NMIPConfig * -_get_dev2_ip_config (NMDeviceWireGuard *self, - int addr_family) +_get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - gs_unref_object NMIPConfig *ip_config = NULL; - NMConnection *connection; - NMSettingWireGuard *s_wg; - guint n_peers; - guint i; - int ip_ifindex; - guint32 route_metric; - guint32 route_table_coerced; - gboolean auto_default_route_enabled; - - _auto_default_route_init (self); - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - - s_wg = NM_SETTING_WIREGUARD (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIREGUARD)); - - /* Differences to `wg-quick`. - * - * `wg-quick` supports the "Table" setting with 3 modes: - * - * a1) "off": this is what we do with "peer-routes" disabled. - * - * a2) an explicit routing table. This is our behavior with "peer-routes" on. In this case - * we honor the "ipv4.route-table" and "ipv6.route-table" settings. One difference is that - * `wg-quick` would resolve table names from /etc/iproute2/rt_tables. Our connection profiles - * only contain table numbers, so that conversion from name to table must have happened - * before already. - * - * a3) "auto" (the default). In this case, `wg-quick` would only add the route to the - * main table, if the AllowedIP range is not yet reachable on the link. With "peer-routes" - * enabled, we don't check for that and always add the routes to the main-table - * (with 'ipv4.route-table' and 'ipv6.route-table' set to zero or RT_TABLE_MAIN (254)). - * - * Also, in "auto" mode, `wg-quick` would add special handling for /0 routes and pick - * an empty table to configure policy routing to avoid routing loops. This handling - * of routing-loops via policy routing is not yet done, and requires a separate solution - * from constructing the peer-routes here. - */ - if (!nm_setting_wireguard_get_peer_routes (s_wg)) - return NULL; - - ip_ifindex = nm_device_get_ip_ifindex (NM_DEVICE (self)); - - if (ip_ifindex <= 0) - return NULL; - - route_metric = nm_device_get_route_metric (NM_DEVICE (self), addr_family); - - route_table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (NM_DEVICE (self), addr_family)); - - auto_default_route_enabled = (addr_family == AF_INET) - ? priv->auto_default_route_enabled_4 - : priv->auto_default_route_enabled_6; - - n_peers = nm_setting_wireguard_get_peers_len (s_wg); - for (i = 0; i < n_peers; i++) { - NMWireGuardPeer *peer = nm_setting_wireguard_get_peer (s_wg, i); - guint n_aips; - guint j; - - n_aips = nm_wireguard_peer_get_allowed_ips_len (peer); - for (j = 0; j < n_aips; j++) { - NMPlatformIPXRoute rt; - NMIPAddr addrbin; - const char *aip; - gboolean valid; - int prefix; - guint32 rtable_coerced; - - aip = nm_wireguard_peer_get_allowed_ip (peer, j, &valid); - - if ( !valid - || !nm_utils_parse_inaddr_prefix_bin (addr_family, - aip, - NULL, - &addrbin, - &prefix)) - continue; - - if (prefix < 0) - prefix = (addr_family == AF_INET) ? 32 : 128; - - if (prefix == 0) { - NMSettingIPConfig *s_ip; - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - if (nm_setting_ip_config_get_never_default (s_ip)) - continue; - } - - if (!ip_config) { - ip_config = nm_device_ip_config_new (NM_DEVICE (self), addr_family); - nm_ip_config_set_config_flags (ip_config, - NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES, - 0); - } - - nm_utils_ipx_address_clear_host_address (addr_family, &addrbin, NULL, prefix); - - rtable_coerced = route_table_coerced; - - if ( prefix == 0 - && auto_default_route_enabled) { - /* In auto-default-route mode, we place the default route in a table that - * has the same number as the fwmark. wg-quick does that too. If you don't - * like that, configure the rules and the default-route explicitly in the - * connection profile. */ - rtable_coerced = nm_platform_route_table_coerce (priv->auto_default_route_fwmark); - } - - if (addr_family == AF_INET) { - rt.r4 = (NMPlatformIP4Route) { - .network = addrbin.addr4, - .plen = prefix, - .ifindex = ip_ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .table_coerced = rtable_coerced, - .metric = route_metric, - }; - } else { - rt.r6 = (NMPlatformIP6Route) { - .network = addrbin.addr6, - .plen = prefix, - .ifindex = ip_ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .table_coerced = rtable_coerced, - .metric = route_metric, - }; - } - - nm_ip_config_add_route (ip_config, &rt.rx, NULL); - } - } - - return g_steal_pointer (&ip_config); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + gs_unref_object NMIPConfig *ip_config = NULL; + NMConnection * connection; + NMSettingWireGuard * s_wg; + guint n_peers; + guint i; + int ip_ifindex; + guint32 route_metric; + guint32 route_table_coerced; + gboolean auto_default_route_enabled; + + _auto_default_route_init(self); + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + + s_wg = NM_SETTING_WIREGUARD(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD)); + + /* Differences to `wg-quick`. + * + * `wg-quick` supports the "Table" setting with 3 modes: + * + * a1) "off": this is what we do with "peer-routes" disabled. + * + * a2) an explicit routing table. This is our behavior with "peer-routes" on. In this case + * we honor the "ipv4.route-table" and "ipv6.route-table" settings. One difference is that + * `wg-quick` would resolve table names from /etc/iproute2/rt_tables. Our connection profiles + * only contain table numbers, so that conversion from name to table must have happened + * before already. + * + * a3) "auto" (the default). In this case, `wg-quick` would only add the route to the + * main table, if the AllowedIP range is not yet reachable on the link. With "peer-routes" + * enabled, we don't check for that and always add the routes to the main-table + * (with 'ipv4.route-table' and 'ipv6.route-table' set to zero or RT_TABLE_MAIN (254)). + * + * Also, in "auto" mode, `wg-quick` would add special handling for /0 routes and pick + * an empty table to configure policy routing to avoid routing loops. This handling + * of routing-loops via policy routing is not yet done, and requires a separate solution + * from constructing the peer-routes here. + */ + if (!nm_setting_wireguard_get_peer_routes(s_wg)) + return NULL; + + ip_ifindex = nm_device_get_ip_ifindex(NM_DEVICE(self)); + + if (ip_ifindex <= 0) + return NULL; + + route_metric = nm_device_get_route_metric(NM_DEVICE(self), addr_family); + + route_table_coerced = + nm_platform_route_table_coerce(nm_device_get_route_table(NM_DEVICE(self), addr_family)); + + auto_default_route_enabled = (addr_family == AF_INET) ? priv->auto_default_route_enabled_4 + : priv->auto_default_route_enabled_6; + + n_peers = nm_setting_wireguard_get_peers_len(s_wg); + for (i = 0; i < n_peers; i++) { + NMWireGuardPeer *peer = nm_setting_wireguard_get_peer(s_wg, i); + guint n_aips; + guint j; + + n_aips = nm_wireguard_peer_get_allowed_ips_len(peer); + for (j = 0; j < n_aips; j++) { + NMPlatformIPXRoute rt; + NMIPAddr addrbin; + const char * aip; + gboolean valid; + int prefix; + guint32 rtable_coerced; + + aip = nm_wireguard_peer_get_allowed_ip(peer, j, &valid); + + if (!valid + || !nm_utils_parse_inaddr_prefix_bin(addr_family, aip, NULL, &addrbin, &prefix)) + continue; + + if (prefix < 0) + prefix = (addr_family == AF_INET) ? 32 : 128; + + if (prefix == 0) { + NMSettingIPConfig *s_ip; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (nm_setting_ip_config_get_never_default(s_ip)) + continue; + } + + if (!ip_config) { + ip_config = nm_device_ip_config_new(NM_DEVICE(self), addr_family); + nm_ip_config_set_config_flags(ip_config, + NM_IP_CONFIG_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES, + 0); + } + + nm_utils_ipx_address_clear_host_address(addr_family, &addrbin, NULL, prefix); + + rtable_coerced = route_table_coerced; + + if (prefix == 0 && auto_default_route_enabled) { + /* In auto-default-route mode, we place the default route in a table that + * has the same number as the fwmark. wg-quick does that too. If you don't + * like that, configure the rules and the default-route explicitly in the + * connection profile. */ + rtable_coerced = nm_platform_route_table_coerce(priv->auto_default_route_fwmark); + } + + if (addr_family == AF_INET) { + rt.r4 = (NMPlatformIP4Route){ + .network = addrbin.addr4, + .plen = prefix, + .ifindex = ip_ifindex, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .table_coerced = rtable_coerced, + .metric = route_metric, + }; + } else { + rt.r6 = (NMPlatformIP6Route){ + .network = addrbin.addr6, + .plen = prefix, + .ifindex = ip_ifindex, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .table_coerced = rtable_coerced, + .metric = route_metric, + }; + } + + nm_ip_config_add_route(ip_config, &rt.rx, NULL); + } + } + + return g_steal_pointer(&ip_config); } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - gs_unref_object NMIPConfig *ip_config = NULL; + gs_unref_object NMIPConfig *ip_config = NULL; - ip_config = _get_dev2_ip_config (NM_DEVICE_WIREGUARD (device), addr_family); + ip_config = _get_dev2_ip_config(NM_DEVICE_WIREGUARD(device), addr_family); - nm_device_set_dev2_ip_config (device, addr_family, ip_config); + nm_device_set_dev2_ip_config(device, addr_family, ip_config); - return NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_wireguard_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - /* When "MTU" for `wg-quick up` is unset, it calls `ip route get` for - * each configured endpoint, to determine the suitable MTU how to reach - * each endpoint. - * For `wg-quick` this works very well, because whenever the script runs it - * determines the best setting at that point in time. It's simply not concerned - * with what happens later (and it's not around anyway). - * - * NetworkManager sticks around, so the right MTU would need to be re-determined - * whenever anything relevant changes. Which basically means, to re-evaluate whenever - * something related to addresses or routing changes (which happens all the time). - * - * The correct MTU indeed depends on the MTU setting of other interfaces (or routes). - * But it's still odd, that activating/deactivating a seemingly unrelated interface - * would trigger an MTU change. It's odd to explain/document and odd to implemented - * -- despite this being the reality. - * - * For now, only support configuring an explicit MTU, or leave the setting untouched. - * The same limitation also applies to other "ip-tunnel" types, where we could use - * similar smarts for autodetecting the MTU. - */ - return nm_device_get_configured_mtu_from_connection (device, - NM_TYPE_SETTING_WIREGUARD, - out_source); + /* When "MTU" for `wg-quick up` is unset, it calls `ip route get` for + * each configured endpoint, to determine the suitable MTU how to reach + * each endpoint. + * For `wg-quick` this works very well, because whenever the script runs it + * determines the best setting at that point in time. It's simply not concerned + * with what happens later (and it's not around anyway). + * + * NetworkManager sticks around, so the right MTU would need to be re-determined + * whenever anything relevant changes. Which basically means, to re-evaluate whenever + * something related to addresses or routing changes (which happens all the time). + * + * The correct MTU indeed depends on the MTU setting of other interfaces (or routes). + * But it's still odd, that activating/deactivating a seemingly unrelated interface + * would trigger an MTU change. It's odd to explain/document and odd to implemented + * -- despite this being the reality. + * + * For now, only support configuring an explicit MTU, or leave the setting untouched. + * The same limitation also applies to other "ip-tunnel" types, where we could use + * similar smarts for autodetecting the MTU. + */ + return nm_device_get_configured_mtu_from_connection(device, + NM_TYPE_SETTING_WIREGUARD, + out_source); } static void -_device_cleanup (NMDeviceWireGuard *self) +_device_cleanup(NMDeviceWireGuard *self) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); - _peers_remove_all (priv); + _peers_remove_all(priv); - _secrets_cancel (self); + _secrets_cancel(self); - priv->auto_default_route_initialized = FALSE; - priv->auto_default_route_priority_initialized = FALSE; + priv->auto_default_route_initialized = FALSE; + priv->auto_default_route_priority_initialized = FALSE; } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - if (new_state <= NM_DEVICE_STATE_ACTIVATED) - return; + if (new_state <= NM_DEVICE_STATE_ACTIVATED) + return; - _device_cleanup (NM_DEVICE_WIREGUARD (device)); + _device_cleanup(NM_DEVICE_WIREGUARD(device)); } /*****************************************************************************/ static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) { - if (nm_streq (setting_name, NM_SETTING_WIREGUARD_SETTING_NAME)) { - /* Most, but not all WireGuard settings can be reapplied. Whitelist. - * - * MTU cannot be reapplied. */ - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_WIREGUARD_SETTING_NAME, - error, - NM_SETTING_WIREGUARD_FWMARK, - NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE, - NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE, - NM_SETTING_WIREGUARD_LISTEN_PORT, - NM_SETTING_WIREGUARD_PEERS, - NM_SETTING_WIREGUARD_PEER_ROUTES, - NM_SETTING_WIREGUARD_PRIVATE_KEY, - NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS); - } - - return NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); + if (nm_streq(setting_name, NM_SETTING_WIREGUARD_SETTING_NAME)) { + /* Most, but not all WireGuard settings can be reapplied. Whitelist. + * + * MTU cannot be reapplied. */ + return nm_device_hash_check_invalid_keys(diffs, + NM_SETTING_WIREGUARD_SETTING_NAME, + error, + NM_SETTING_WIREGUARD_FWMARK, + NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE, + NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE, + NM_SETTING_WIREGUARD_LISTEN_PORT, + NM_SETTING_WIREGUARD_PEERS, + NM_SETTING_WIREGUARD_PEER_ROUTES, + NM_SETTING_WIREGUARD_PRIVATE_KEY, + NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS); + } + + return NM_DEVICE_CLASS(nm_device_wireguard_parent_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) +reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (device); - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - gs_unref_object NMIPConfig *ip4_config = NULL; - gs_unref_object NMIPConfig *ip6_config = NULL; - NMDeviceState state = nm_device_get_state (device); - - NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->reapply_connection (device, - con_old, - con_new); - - if (state >= NM_DEVICE_STATE_CONFIG) { - priv->auto_default_route_refresh = TRUE; - link_config (NM_DEVICE_WIREGUARD (device), - "reapply", - LINK_CONFIG_MODE_REAPPLY, - NULL); - } - - if (state >= NM_DEVICE_STATE_IP_CONFIG) { - ip4_config = _get_dev2_ip_config (self, AF_INET); - ip6_config = _get_dev2_ip_config (self, AF_INET6); - - nm_device_set_dev2_ip_config (device, AF_INET, ip4_config); - nm_device_set_dev2_ip_config (device, AF_INET6, ip6_config); - } + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(device); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + gs_unref_object NMIPConfig *ip4_config = NULL; + gs_unref_object NMIPConfig *ip6_config = NULL; + NMDeviceState state = nm_device_get_state(device); + + NM_DEVICE_CLASS(nm_device_wireguard_parent_class)->reapply_connection(device, con_old, con_new); + + if (state >= NM_DEVICE_STATE_CONFIG) { + priv->auto_default_route_refresh = TRUE; + link_config(NM_DEVICE_WIREGUARD(device), "reapply", LINK_CONFIG_MODE_REAPPLY, NULL); + } + + if (state >= NM_DEVICE_STATE_IP_CONFIG) { + ip4_config = _get_dev2_ip_config(self, AF_INET); + ip6_config = _get_dev2_ip_config(self, AF_INET6); + + nm_device_set_dev2_ip_config(device, AF_INET, ip4_config); + nm_device_set_dev2_ip_config(device, AF_INET6, ip6_config); + } } /*****************************************************************************/ static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (device); - NMSettingWireGuard *s_wg = NM_SETTING_WIREGUARD (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIREGUARD)); - const NMPObject *obj_wg; - const NMPObjectLnkWireGuard *olnk_wg; - guint i; - - if (!s_wg) { - s_wg = NM_SETTING_WIREGUARD (nm_setting_wireguard_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wg)); - } - - g_object_set (s_wg, - NM_SETTING_WIREGUARD_FWMARK, - (guint) priv->lnk_curr.fwmark, - NM_SETTING_WIREGUARD_LISTEN_PORT, - (guint) priv->lnk_curr.listen_port, - NULL); - - obj_wg = NMP_OBJECT_UP_CAST (nm_platform_link_get_lnk_wireguard (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - NULL)); - if (!obj_wg) - return; - - olnk_wg = &obj_wg->_lnk_wireguard; - - for (i = 0; i < olnk_wg->peers_len; i++) { - nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; - const NMPWireGuardPeer *ppeer = &olnk_wg->peers[i]; - - peer = nm_wireguard_peer_new (); - - _nm_wireguard_peer_set_public_key_bin (peer, ppeer->public_key); - - nm_setting_wireguard_append_peer (s_wg, peer); - } + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(device); + NMSettingWireGuard * s_wg = + NM_SETTING_WIREGUARD(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD)); + const NMPObject * obj_wg; + const NMPObjectLnkWireGuard *olnk_wg; + guint i; + + if (!s_wg) { + s_wg = NM_SETTING_WIREGUARD(nm_setting_wireguard_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wg)); + } + + g_object_set(s_wg, + NM_SETTING_WIREGUARD_FWMARK, + (guint) priv->lnk_curr.fwmark, + NM_SETTING_WIREGUARD_LISTEN_PORT, + (guint) priv->lnk_curr.listen_port, + NULL); + + obj_wg = NMP_OBJECT_UP_CAST(nm_platform_link_get_lnk_wireguard(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + NULL)); + if (!obj_wg) + return; + + olnk_wg = &obj_wg->_lnk_wireguard; + + for (i = 0; i < olnk_wg->peers_len; i++) { + nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL; + const NMPWireGuardPeer * ppeer = &olnk_wg->peers[i]; + + peer = nm_wireguard_peer_new(); + + _nm_wireguard_peer_set_public_key_bin(peer, ppeer->public_key); + + nm_setting_wireguard_append_peer(s_wg, peer); + } } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (object); - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_PUBLIC_KEY: - g_value_take_variant (value, - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - priv->lnk_curr.public_key, - sizeof (priv->lnk_curr.public_key), - 1)); - break; - case PROP_LISTEN_PORT: - g_value_set_uint (value, priv->lnk_curr.listen_port); - break; - case PROP_FWMARK: - g_value_set_uint (value, priv->lnk_curr.fwmark); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(object); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_PUBLIC_KEY: + g_value_take_variant(value, + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, + priv->lnk_curr.public_key, + sizeof(priv->lnk_curr.public_key), + 1)); + break; + case PROP_LISTEN_PORT: + g_value_set_uint(value, priv->lnk_curr.listen_port); + break; + case PROP_FWMARK: + g_value_set_uint(value, priv->lnk_curr.fwmark); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_wireguard_init (NMDeviceWireGuard *self) +nm_device_wireguard_init(NMDeviceWireGuard *self) { - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); - c_list_init (&priv->lst_peers_head); - priv->peers = g_hash_table_new (_peer_data_hash, _peer_data_equal); + c_list_init(&priv->lst_peers_head); + priv->peers = g_hash_table_new(_peer_data_hash, _peer_data_equal); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (object); + NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD(object); - _device_cleanup (self); + _device_cleanup(self); - G_OBJECT_CLASS (nm_device_wireguard_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_wireguard_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (object); - NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (self); + NMDeviceWireGuard * self = NM_DEVICE_WIREGUARD(object); + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self); - nm_explicit_bzero (priv->lnk_curr.private_key, sizeof (priv->lnk_curr.private_key)); + nm_explicit_bzero(priv->lnk_curr.private_key, sizeof(priv->lnk_curr.private_key)); - if (priv->dns_manager) { - g_signal_handlers_disconnect_by_func (priv->dns_manager, _dns_config_changed, self); - g_object_unref (priv->dns_manager); - } + if (priv->dns_manager) { + g_signal_handlers_disconnect_by_func(priv->dns_manager, _dns_config_changed, self); + g_object_unref(priv->dns_manager); + } - g_hash_table_destroy (priv->peers); + g_hash_table_destroy(priv->peers); - G_OBJECT_CLASS (nm_device_wireguard_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_device_wireguard_parent_class)->finalize(object); } static const NMDBusInterfaceInfoExtended interface_info_device_wireguard = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WIREGUARD, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("PublicKey", "ay", NM_DEVICE_WIREGUARD_PUBLIC_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("ListenPort", "q", NM_DEVICE_WIREGUARD_LISTEN_PORT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("FwMark", "u", NM_DEVICE_WIREGUARD_FWMARK), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_WIREGUARD, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PublicKey", + "ay", + NM_DEVICE_WIREGUARD_PUBLIC_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ListenPort", + "q", + NM_DEVICE_WIREGUARD_LISTEN_PORT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FwMark", + "u", + NM_DEVICE_WIREGUARD_FWMARK), ), ), }; static void -nm_device_wireguard_class_init (NMDeviceWireGuardClass *klass) +nm_device_wireguard_class_init(NMDeviceWireGuardClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wireguard); - - device_class->connection_type_supported = NM_SETTING_WIREGUARD_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIREGUARD_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIREGUARD); - - device_class->state_changed = device_state_changed; - device_class->create_and_realize = create_and_realize; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage2_config_also_for_external_or_assume = TRUE; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->link_changed = link_changed; - device_class->update_connection = update_connection; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; - device_class->get_configured_mtu = get_configured_mtu; - device_class->get_extra_rules = get_extra_rules; - device_class->coerce_route_table = coerce_route_table; - - obj_properties[PROP_PUBLIC_KEY] = - g_param_spec_variant (NM_DEVICE_WIREGUARD_PUBLIC_KEY, - "", "", - G_VARIANT_TYPE ("ay"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LISTEN_PORT] = - g_param_spec_uint (NM_DEVICE_WIREGUARD_LISTEN_PORT, - "", "", - 0, G_MAXUINT16, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FWMARK] = - g_param_spec_uint (NM_DEVICE_WIREGUARD_FWMARK, - "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_wireguard); + + device_class->connection_type_supported = NM_SETTING_WIREGUARD_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_WIREGUARD_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_WIREGUARD); + + device_class->state_changed = device_state_changed; + device_class->create_and_realize = create_and_realize; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage2_config_also_for_external_or_assume = TRUE; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->link_changed = link_changed; + device_class->update_connection = update_connection; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = reapply_connection; + device_class->get_configured_mtu = get_configured_mtu; + device_class->get_extra_rules = get_extra_rules; + device_class->coerce_route_table = coerce_route_table; + + obj_properties[PROP_PUBLIC_KEY] = + g_param_spec_variant(NM_DEVICE_WIREGUARD_PUBLIC_KEY, + "", + "", + G_VARIANT_TYPE("ay"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LISTEN_PORT] = g_param_spec_uint(NM_DEVICE_WIREGUARD_LISTEN_PORT, + "", + "", + 0, + G_MAXUINT16, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FWMARK] = g_param_spec_uint(NM_DEVICE_WIREGUARD_FWMARK, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*************************************************************/ -#define NM_TYPE_WIREGUARD_DEVICE_FACTORY (nm_wireguard_device_factory_get_type ()) -#define NM_WIREGUARD_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIREGUARD_DEVICE_FACTORY, NMWireGuardDeviceFactory)) +#define NM_TYPE_WIREGUARD_DEVICE_FACTORY (nm_wireguard_device_factory_get_type()) +#define NM_WIREGUARD_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIREGUARD_DEVICE_FACTORY, NMWireGuardDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIREGUARD, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "WireGuard", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIREGUARD, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIREGUARD, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_WIREGUARD, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "WireGuard", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_WIREGUARD, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_WIREGUARD, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (WIREGUARD, WireGuard, wireguard, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WIREGUARD) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WIREGUARD_SETTING_NAME), - factory_class->create_device = create_device; -) +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + WIREGUARD, + WireGuard, + wireguard, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_WIREGUARD) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_WIREGUARD_SETTING_NAME), + factory_class->create_device = create_device;) diff --git a/src/devices/nm-device-wireguard.h b/src/devices/nm-device-wireguard.h index 67318042..f562f356 100644 --- a/src/devices/nm-device-wireguard.h +++ b/src/devices/nm-device-wireguard.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Javier Arteaga */ @@ -8,20 +8,24 @@ #include "nm-device.h" -#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type ()) -#define NM_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard)) -#define NM_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) -#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIREGUARD)) -#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIREGUARD)) -#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) +#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type()) +#define NM_DEVICE_WIREGUARD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard)) +#define NM_DEVICE_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) +#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) -#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key" -#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port" -#define NM_DEVICE_WIREGUARD_FWMARK "fwmark" +#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key" +#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port" +#define NM_DEVICE_WIREGUARD_FWMARK "fwmark" -typedef struct _NMDeviceWireGuard NMDeviceWireGuard; +typedef struct _NMDeviceWireGuard NMDeviceWireGuard; typedef struct _NMDeviceWireGuardClass NMDeviceWireGuardClass; -GType nm_device_wireguard_get_type (void); +GType nm_device_wireguard_get_type(void); #endif /* __NM_DEVICE_WIREGUARD_H__ */ diff --git a/src/devices/nm-device-wpan.c b/src/devices/nm-device-wpan.c index b947aba6..195603dc 100644 --- a/src/devices/nm-device-wpan.c +++ b/src/devices/nm-device-wpan.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Lubomir Rintel */ @@ -26,225 +26,232 @@ _LOG_DECLARE_SELF(NMDeviceWpan); /*****************************************************************************/ struct _NMDeviceWpan { - NMDevice parent; + NMDevice parent; }; struct _NMDeviceWpanClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) /*****************************************************************************/ static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingWpan *s_wpan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_WPAN_SETTING_NAME, - existing_connections, - NULL, - _("WPAN connection"), - NULL, - NULL, - TRUE); - - s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); - if (!s_wpan) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wpan' setting is required."); - return FALSE; - } - - return TRUE; + NMSettingWpan *s_wpan; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_WPAN_SETTING_NAME, + existing_connections, + NULL, + _("WPAN connection"), + NULL, + NULL, + TRUE); + + s_wpan = NM_SETTING_WPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_WPAN)); + if (!s_wpan) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wpan' setting is required."); + return FALSE; + } + + return TRUE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMSettingWpan *s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); + NMSettingWpan *s_wpan = + NM_SETTING_WPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_WPAN)); - if (!s_wpan) { - s_wpan = (NMSettingWpan *) nm_setting_wpan_new (); - nm_connection_add_setting (connection, (NMSetting *) s_wpan); - } + if (!s_wpan) { + s_wpan = (NMSettingWpan *) nm_setting_wpan_new(); + nm_connection_add_setting(connection, (NMSetting *) s_wpan); + } } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingWpan *s_wpan; - const char *mac, *hw_addr; - - if (!NM_DEVICE_CLASS (nm_device_wpan_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); - - mac = nm_setting_wpan_get_mac_address (s_wpan); - if (mac) { - hw_addr = nm_device_get_hw_address (device); - if (!nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address mismatches"); - return FALSE; - } - } - - return TRUE; + NMSettingWpan *s_wpan; + const char * mac, *hw_addr; + + if (!NM_DEVICE_CLASS(nm_device_wpan_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + s_wpan = NM_SETTING_WPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_WPAN)); + + mac = nm_setting_wpan_get_mac_address(s_wpan); + if (mac) { + hw_addr = nm_device_get_hw_address(device); + if (!nm_utils_hwaddr_matches(mac, -1, hw_addr, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "MAC address mismatches"); + return FALSE; + } + } + + return TRUE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceWpan *self = NM_DEVICE_WPAN (device); - NMSettingWpan *s_wpan; - NMPlatform *platform; - guint16 pan_id; - guint16 short_address; - gint16 page, channel; - int ifindex; - const guint8 *hwaddr; - gsize hwaddr_len = 0; - const NMPlatformLink *lowpan_plink; - NMDevice *lowpan_device = NULL; - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - - platform = nm_device_get_platform (device); - nm_assert (NM_IS_PLATFORM (platform)); - - ifindex = nm_device_get_ifindex (device); - - g_return_val_if_fail (ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE); - - s_wpan = nm_device_get_applied_setting (device, NM_TYPE_SETTING_WPAN); - - g_return_val_if_fail (s_wpan, NM_ACT_STAGE_RETURN_FAILURE); - - hwaddr = nm_platform_link_get_address (platform, ifindex, &hwaddr_len); - - if (!hwaddr) { - *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - /* As of kernel 4.16, the 6LoWPAN devices layered on top of WPANs - * need to be DOWN as well as the WPAN device itself in order to - * modify the WPAN properties. */ - lowpan_plink = nm_platform_link_get_by_address (platform, - NM_LINK_TYPE_6LOWPAN, - hwaddr, - hwaddr_len); - if ( lowpan_plink - && NM_FLAGS_HAS (lowpan_plink->n_ifi_flags, IFF_UP)) { - lowpan_device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, - lowpan_plink->ifindex); - } - - if (lowpan_device) - nm_device_take_down (lowpan_device, TRUE); - - nm_device_take_down (device, TRUE); - - pan_id = nm_setting_wpan_get_pan_id (s_wpan); - if (pan_id != G_MAXUINT16) { - if (!nm_platform_wpan_set_pan_id (platform, ifindex, pan_id)) { - _LOGW (LOGD_DEVICE, "unable to set the PAN ID"); - goto out; - } - } - - short_address = nm_setting_wpan_get_short_address (s_wpan); - if (short_address != G_MAXUINT16) { - if (!nm_platform_wpan_set_short_addr (platform, ifindex, short_address)) { - _LOGW (LOGD_DEVICE, "unable to set the short address"); - goto out; - } - } - - channel = nm_setting_wpan_get_channel (s_wpan); - if (channel != NM_SETTING_WPAN_CHANNEL_DEFAULT) { - page = nm_setting_wpan_get_page (s_wpan); - if (!nm_platform_wpan_set_channel (platform, ifindex, page, channel)) { - _LOGW (LOGD_DEVICE, "unable to set the channel"); - goto out; - } - } - - ret = NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceWpan * self = NM_DEVICE_WPAN(device); + NMSettingWpan * s_wpan; + NMPlatform * platform; + guint16 pan_id; + guint16 short_address; + gint16 page, channel; + int ifindex; + const guint8 * hwaddr; + gsize hwaddr_len = 0; + const NMPlatformLink *lowpan_plink; + NMDevice * lowpan_device = NULL; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + + platform = nm_device_get_platform(device); + nm_assert(NM_IS_PLATFORM(platform)); + + ifindex = nm_device_get_ifindex(device); + + g_return_val_if_fail(ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE); + + s_wpan = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WPAN); + + g_return_val_if_fail(s_wpan, NM_ACT_STAGE_RETURN_FAILURE); + + hwaddr = nm_platform_link_get_address(platform, ifindex, &hwaddr_len); + + if (!hwaddr) { + *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + /* As of kernel 4.16, the 6LoWPAN devices layered on top of WPANs + * need to be DOWN as well as the WPAN device itself in order to + * modify the WPAN properties. */ + lowpan_plink = + nm_platform_link_get_by_address(platform, NM_LINK_TYPE_6LOWPAN, hwaddr, hwaddr_len); + if (lowpan_plink && NM_FLAGS_HAS(lowpan_plink->n_ifi_flags, IFF_UP)) { + lowpan_device = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, lowpan_plink->ifindex); + } + + if (lowpan_device) + nm_device_take_down(lowpan_device, TRUE); + + nm_device_take_down(device, TRUE); + + pan_id = nm_setting_wpan_get_pan_id(s_wpan); + if (pan_id != G_MAXUINT16) { + if (!nm_platform_wpan_set_pan_id(platform, ifindex, pan_id)) { + _LOGW(LOGD_DEVICE, "unable to set the PAN ID"); + goto out; + } + } + + short_address = nm_setting_wpan_get_short_address(s_wpan); + if (short_address != G_MAXUINT16) { + if (!nm_platform_wpan_set_short_addr(platform, ifindex, short_address)) { + _LOGW(LOGD_DEVICE, "unable to set the short address"); + goto out; + } + } + + channel = nm_setting_wpan_get_channel(s_wpan); + if (channel != NM_SETTING_WPAN_CHANNEL_DEFAULT) { + page = nm_setting_wpan_get_page(s_wpan); + if (!nm_platform_wpan_set_channel(platform, ifindex, page, channel)) { + _LOGW(LOGD_DEVICE, "unable to set the channel"); + goto out; + } + } + + ret = NM_ACT_STAGE_RETURN_SUCCESS; out: - nm_device_bring_up (device, TRUE, NULL); + nm_device_bring_up(device, TRUE, NULL); - if (lowpan_device) - nm_device_bring_up (lowpan_device, TRUE, NULL); + if (lowpan_device) + nm_device_bring_up(lowpan_device, TRUE, NULL); - return ret; + return ret; } /*****************************************************************************/ static void -nm_device_wpan_init (NMDeviceWpan *self) -{ -} +nm_device_wpan_init(NMDeviceWpan *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_wpan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WPAN, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_WPAN, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; static void -nm_device_wpan_class_init (NMDeviceWpanClass *klass) +nm_device_wpan_class_init(NMDeviceWpanClass *klass) { - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wpan); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_wpan); - device_class->connection_type_supported = NM_SETTING_WPAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WPAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WPAN); + device_class->connection_type_supported = NM_SETTING_WPAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_WPAN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_WPAN); - device_class->complete_connection = complete_connection; - device_class->check_connection_compatible = check_connection_compatible; - device_class->update_connection = update_connection; - device_class->act_stage1_prepare = act_stage1_prepare; + device_class->complete_connection = complete_connection; + device_class->check_connection_compatible = check_connection_compatible; + device_class->update_connection = update_connection; + device_class->act_stage1_prepare = act_stage1_prepare; } /*****************************************************************************/ -#define NM_TYPE_WPAN_DEVICE_FACTORY (nm_wpan_device_factory_get_type ()) -#define NM_WPAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WPAN_DEVICE_FACTORY, NMWpanDeviceFactory)) +#define NM_TYPE_WPAN_DEVICE_FACTORY (nm_wpan_device_factory_get_type()) +#define NM_WPAN_DEVICE_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WPAN_DEVICE_FACTORY, NMWpanDeviceFactory)) static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WPAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "WPAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WPAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WPAN, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_WPAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "WPAN", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_WPAN, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_WPAN, + NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL (WPAN, Wpan, wpan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WPAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WPAN_SETTING_NAME), - factory_class->create_device = create_device; -); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + WPAN, + Wpan, + wpan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_WPAN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_WPAN_SETTING_NAME), + factory_class->create_device = create_device;); diff --git a/src/devices/nm-device-wpan.h b/src/devices/nm-device-wpan.h index d86a9614..4bc4f243 100644 --- a/src/devices/nm-device-wpan.h +++ b/src/devices/nm-device-wpan.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2018 Lubomir Rintel */ @@ -6,16 +6,18 @@ #ifndef __NETWORKMANAGER_DEVICE_WPAN_H__ #define __NETWORKMANAGER_DEVICE_WPAN_H__ -#define NM_TYPE_DEVICE_WPAN (nm_device_wpan_get_type ()) -#define NM_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpan)) -#define NM_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) -#define NM_IS_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WPAN)) -#define NM_IS_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WPAN)) -#define NM_DEVICE_WPAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) +#define NM_TYPE_DEVICE_WPAN (nm_device_wpan_get_type()) +#define NM_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpan)) +#define NM_DEVICE_WPAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) +#define NM_IS_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WPAN)) +#define NM_IS_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WPAN)) +#define NM_DEVICE_WPAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) -typedef struct _NMDeviceWpan NMDeviceWpan; +typedef struct _NMDeviceWpan NMDeviceWpan; typedef struct _NMDeviceWpanClass NMDeviceWpanClass; -GType nm_device_wpan_get_type (void); +GType nm_device_wpan_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_WPAN_H__ */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index eb0d4d52..2dab5075 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2018 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -28,6 +28,8 @@ #include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "nm-libnm-core-intern/nm-common-macros.h" #include "nm-device-private.h" +#include "nm-l3cfg.h" +#include "nm-l3-config-data.h" #include "NetworkManagerUtils.h" #include "nm-manager.h" #include "platform/nm-platform.h" @@ -72,27 +74,27 @@ #include "nm-device-wireguard.h" #include "nm-device-logging.h" -_LOG_DECLARE_SELF (NMDevice); +_LOG_DECLARE_SELF(NMDevice); /*****************************************************************************/ -#define DEFAULT_AUTOCONNECT TRUE +#define DEFAULT_AUTOCONNECT TRUE static guint32 -dhcp_grace_period_from_timeout (guint32 timeout) +dhcp_grace_period_from_timeout(guint32 timeout) { #define DHCP_GRACE_PERIOD_MULTIPLIER 2U - nm_assert (timeout > 0); - nm_assert (timeout < G_MAXINT32); + nm_assert(timeout > 0); + nm_assert(timeout < G_MAXINT32); - if (timeout < G_MAXUINT32 / DHCP_GRACE_PERIOD_MULTIPLIER) - return timeout * DHCP_GRACE_PERIOD_MULTIPLIER; + if (timeout < G_MAXUINT32 / DHCP_GRACE_PERIOD_MULTIPLIER) + return timeout * DHCP_GRACE_PERIOD_MULTIPLIER; - return G_MAXUINT32; + return G_MAXUINT32; } -#define CARRIER_WAIT_TIME_MS 6000 +#define CARRIER_WAIT_TIME_MS 6000 #define CARRIER_WAIT_TIME_AFTER_MTU_MS 10000 #define NM_DEVICE_AUTH_RETRIES_UNSET -1 @@ -101,1651 +103,2722 @@ dhcp_grace_period_from_timeout (guint32 timeout) /*****************************************************************************/ -typedef void (*ActivationHandleFunc) (NMDevice *self); +typedef void (*ActivationHandleFunc)(NMDevice *self); typedef enum { - CLEANUP_TYPE_KEEP, - CLEANUP_TYPE_REMOVED, - CLEANUP_TYPE_DECONFIGURE, + CLEANUP_TYPE_KEEP, + CLEANUP_TYPE_REMOVED, + CLEANUP_TYPE_DECONFIGURE, } CleanupType; typedef struct { - CList lst_slave; - NMDevice *slave; - gulong watch_id; - bool slave_is_enslaved; - bool configure; + CList lst_slave; + NMDevice *slave; + gulong watch_id; + bool slave_is_enslaved; + bool configure; } SlaveInfo; typedef struct { - NMDevice *device; - guint idle_add_id; - int ifindex; + NMDevice *device; + guint idle_add_id; + int ifindex; } DeleteOnDeactivateData; typedef struct { - NMDevice *device; - GCancellable *cancellable; - NMPlatformAsyncCallback callback; - gpointer callback_data; - guint num_vfs; - NMTernary autoprobe; + NMDevice * device; + GCancellable * cancellable; + NMPlatformAsyncCallback callback; + gpointer callback_data; + guint num_vfs; + NMTernary autoprobe; } SriovOp; -typedef void (*AcdCallback) (NMDevice *, NMIP4Config **, gboolean); +typedef void (*AcdCallback)(NMDevice *, NMIP4Config **, gboolean); + +typedef enum { + /* The various NML3ConfigData types that we track explicitly. Note that + * their relative order matters: higher numbers in this enum means more + * important (and during merge overwrites other settings). */ + L3_CONFIG_DATA_TYPE_LL_4, + L3_CONFIG_DATA_TYPE_AC_6, + L3_CONFIG_DATA_TYPE_DHCP_4, + L3_CONFIG_DATA_TYPE_DHCP_6, + L3_CONFIG_DATA_TYPE_DEV_4, + L3_CONFIG_DATA_TYPE_DEV_6, + L3_CONFIG_DATA_TYPE_SETTING, + _L3_CONFIG_DATA_TYPE_NUM, + _L3_CONFIG_DATA_TYPE_NONE, +} L3ConfigDataType; typedef struct { - AcdCallback callback; - NMDevice *device; - NMIP4Config **configs; + AcdCallback callback; + NMDevice * device; + NMIP4Config **configs; } AcdData; typedef enum { - HW_ADDR_TYPE_UNSET = 0, - HW_ADDR_TYPE_PERMANENT, - HW_ADDR_TYPE_EXPLICIT, - HW_ADDR_TYPE_GENERATED, + HW_ADDR_TYPE_UNSET = 0, + HW_ADDR_TYPE_PERMANENT, + HW_ADDR_TYPE_EXPLICIT, + HW_ADDR_TYPE_GENERATED, } HwAddrType; typedef enum { - FIREWALL_STATE_UNMANAGED = 0, - FIREWALL_STATE_INITIALIZED, - FIREWALL_STATE_WAIT_STAGE_3, - FIREWALL_STATE_WAIT_IP_CONFIG, + FIREWALL_STATE_UNMANAGED = 0, + FIREWALL_STATE_INITIALIZED, + FIREWALL_STATE_WAIT_STAGE_3, + FIREWALL_STATE_WAIT_IP_CONFIG, } FirewallState; typedef struct { - NMIPConfig *orig; /* the original configuration applied to the device */ - NMIPConfig *current; /* configuration after external changes. NULL means - that the original configuration didn't change. */ + NMIPConfig *orig; /* the original configuration applied to the device */ + NMIPConfig *current; /* configuration after external changes. NULL means + * that the original configuration didn't change. */ } AppliedConfig; typedef struct { - NMDhcpClient *client; - NMDhcpConfig *config; - gulong state_sigid; - guint grace_id; - bool grace_pending:1; - bool was_active:1; + NMDhcpClient *client; + NMDhcpConfig *config; + gulong state_sigid; + guint grace_id; + bool grace_pending : 1; + bool was_active : 1; } DhcpData; struct _NMDeviceConnectivityHandle { - CList concheck_lst; - NMDevice *self; - NMDeviceConnectivityCallback callback; - gpointer user_data; - NMConnectivityCheckHandle *c_handle; - guint64 seq; - bool is_periodic:1; - bool is_periodic_bump:1; - bool is_periodic_bump_on_complete:1; - int addr_family; + CList concheck_lst; + NMDevice * self; + NMDeviceConnectivityCallback callback; + gpointer user_data; + NMConnectivityCheckHandle * c_handle; + guint64 seq; + bool is_periodic : 1; + bool is_periodic_bump : 1; + bool is_periodic_bump_on_complete : 1; + int addr_family; }; typedef struct { - int ifindex; - NMEthtoolFeatureStates *features; - NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM]; - NMEthtoolCoalesceState *coalesce; - NMEthtoolRingState *ring; + int ifindex; + NMEthtoolFeatureStates *features; + NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM]; + NMEthtoolCoalesceState *coalesce; + NMEthtoolRingState * ring; } EthtoolState; /*****************************************************************************/ enum { - STATE_CHANGED, - AUTOCONNECT_ALLOWED, - IP4_CONFIG_CHANGED, - IP6_CONFIG_CHANGED, - IP6_PREFIX_DELEGATED, - IP6_SUBNET_NEEDED, - REMOVED, - RECHECK_AUTO_ACTIVATE, - RECHECK_ASSUME, - LAST_SIGNAL, + STATE_CHANGED, + AUTOCONNECT_ALLOWED, + IP4_CONFIG_CHANGED, + IP6_CONFIG_CHANGED, + IP6_PREFIX_DELEGATED, + IP6_SUBNET_NEEDED, + REMOVED, + RECHECK_AUTO_ACTIVATE, + RECHECK_ASSUME, + LAST_SIGNAL, }; -static guint signals[LAST_SIGNAL] = { 0 }; - -NM_GOBJECT_PROPERTIES_DEFINE (NMDevice, - PROP_UDI, - PROP_PATH, - PROP_IFACE, - PROP_IP_IFACE, - PROP_DRIVER, - PROP_DRIVER_VERSION, - PROP_FIRMWARE_VERSION, - PROP_CAPABILITIES, - PROP_CARRIER, - PROP_MTU, - PROP_IP4_ADDRESS, - PROP_IP4_CONFIG, - PROP_DHCP4_CONFIG, - PROP_IP6_CONFIG, - PROP_DHCP6_CONFIG, - PROP_STATE, - PROP_STATE_REASON, - PROP_ACTIVE_CONNECTION, - PROP_DEVICE_TYPE, - PROP_LINK_TYPE, - PROP_MANAGED, - PROP_AUTOCONNECT, - PROP_FIRMWARE_MISSING, - PROP_NM_PLUGIN_MISSING, - PROP_TYPE_DESC, - PROP_RFKILL_TYPE, - PROP_IFINDEX, - PROP_AVAILABLE_CONNECTIONS, - PROP_PHYSICAL_PORT_ID, - PROP_MASTER, - PROP_PARENT, - PROP_HW_ADDRESS, - PROP_PERM_HW_ADDRESS, - PROP_HAS_PENDING_ACTION, - PROP_METERED, - PROP_LLDP_NEIGHBORS, - PROP_REAL, - PROP_SLAVES, - PROP_STATISTICS_REFRESH_RATE_MS, - PROP_STATISTICS_TX_BYTES, - PROP_STATISTICS_RX_BYTES, - PROP_IP4_CONNECTIVITY, - PROP_IP6_CONNECTIVITY, - PROP_INTERFACE_FLAGS, -); +static guint signals[LAST_SIGNAL] = {0}; + +NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, + PROP_UDI, + PROP_PATH, + PROP_IFACE, + PROP_IP_IFACE, + PROP_DRIVER, + PROP_DRIVER_VERSION, + PROP_FIRMWARE_VERSION, + PROP_CAPABILITIES, + PROP_CARRIER, + PROP_MTU, + PROP_IP4_ADDRESS, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_IP6_CONFIG, + PROP_DHCP6_CONFIG, + PROP_STATE, + PROP_STATE_REASON, + PROP_ACTIVE_CONNECTION, + PROP_DEVICE_TYPE, + PROP_LINK_TYPE, + PROP_MANAGED, + PROP_AUTOCONNECT, + PROP_FIRMWARE_MISSING, + PROP_NM_PLUGIN_MISSING, + PROP_TYPE_DESC, + PROP_RFKILL_TYPE, + PROP_IFINDEX, + PROP_AVAILABLE_CONNECTIONS, + PROP_PHYSICAL_PORT_ID, + PROP_MASTER, + PROP_PARENT, + PROP_HW_ADDRESS, + PROP_PERM_HW_ADDRESS, + PROP_HAS_PENDING_ACTION, + PROP_METERED, + PROP_LLDP_NEIGHBORS, + PROP_REAL, + PROP_SLAVES, + PROP_STATISTICS_REFRESH_RATE_MS, + PROP_STATISTICS_TX_BYTES, + PROP_STATISTICS_RX_BYTES, + PROP_IP4_CONNECTIVITY, + PROP_IP6_CONNECTIVITY, + PROP_INTERFACE_FLAGS, ); typedef struct _NMDevicePrivate { - bool in_state_changed; - - guint device_link_changed_id; - guint device_ip_link_changed_id; - - NMDeviceState state; - NMDeviceStateReason state_reason; - struct { - guint id; - - /* The @state/@reason is only valid, when @id is set. */ - NMDeviceState state; - NMDeviceStateReason reason; - } queued_state; - - union { - struct { - guint queued_ip_config_id_6; - guint queued_ip_config_id_4; - }; - guint queued_ip_config_id_x[2]; - }; - - GSList *pending_actions; - GSList *dad6_failed_addrs; - - NMDBusTrackObjPath parent_device; - - char * udi; - char * path; - char * iface; /* may change, could be renamed by user */ - int ifindex; - - int parent_ifindex; - - int auth_retries; - - union { - const guint8 hw_addr_len; /* read-only */ - guint8 hw_addr_len_; - }; - - HwAddrType hw_addr_type:5; - - bool real:1; - - bool update_ip_config_completed_v4:1; - bool update_ip_config_completed_v6:1; - - char * ip_iface; - int ip_ifindex; - NMDeviceType type; - char * type_desc; - NMLinkType link_type; - NMDeviceCapabilities capabilities; - char * driver; - char * driver_version; - char * firmware_version; - RfKillType rfkill_type; - bool firmware_missing:1; - bool nm_plugin_missing:1; - bool hw_addr_perm_fake:1; /* whether the permanent HW address could not be read and is a fake */ - - NMUtilsStableType current_stable_id_type:3; - - bool nm_owned:1; /* whether the device is a device owned and created by NM */ - - bool assume_state_guess_assume:1; - char * assume_state_connection_uuid; - - GHashTable * available_connections; - char * hw_addr; - char * hw_addr_perm; - char * hw_addr_initial; - char * physical_port_id; - guint dev_id; - - NMUnmanagedFlags unmanaged_mask; - NMUnmanagedFlags unmanaged_flags; - DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */ - - GCancellable *deactivating_cancellable; - - guint32 ip4_address; + bool in_state_changed; + + guint device_link_changed_id; + guint device_ip_link_changed_id; + + NMDeviceState state; + NMDeviceStateReason state_reason; + struct { + guint id; + + /* The @state/@reason is only valid, when @id is set. */ + NMDeviceState state; + NMDeviceStateReason reason; + } queued_state; + + union { + struct { + guint queued_ip_config_id_6; + guint queued_ip_config_id_4; + }; + guint queued_ip_config_id_x[2]; + }; + + GSList *pending_actions; + GSList *dad6_failed_addrs; + + NMDBusTrackObjPath parent_device; + + char *udi; + char *path; + + union { + const char *const iface; + char * iface_; + }; + union { + const char *const ip_iface; + char * ip_iface_; + }; + + union { + const int ifindex; + int ifindex_; + }; + union { + const int ip_ifindex; + int ip_ifindex_; + }; + + NMNetnsSharedIPHandle *shared_ip_handle; + + int parent_ifindex; + + int auth_retries; + + union { + const guint8 hw_addr_len; /* read-only */ + guint8 hw_addr_len_; + }; + + HwAddrType hw_addr_type : 5; + + bool real : 1; + + bool update_ip_config_completed_v4 : 1; + bool update_ip_config_completed_v6 : 1; + + NMDeviceType type; + char * type_desc; + NMLinkType link_type; + NMDeviceCapabilities capabilities; + char * driver; + char * driver_version; + char * firmware_version; + RfKillType rfkill_type; + bool firmware_missing : 1; + bool nm_plugin_missing : 1; + bool + hw_addr_perm_fake : 1; /* whether the permanent HW address could not be read and is a fake */ + + NMUtilsStableType current_stable_id_type : 3; + + bool nm_owned : 1; /* whether the device is a device owned and created by NM */ + + bool assume_state_guess_assume : 1; + char *assume_state_connection_uuid; + + GHashTable *available_connections; + char * hw_addr; + char * hw_addr_perm; + char * hw_addr_initial; + char * physical_port_id; + guint dev_id; + + NMUnmanagedFlags unmanaged_mask; + NMUnmanagedFlags unmanaged_flags; + DeleteOnDeactivateData + *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */ + + GCancellable *deactivating_cancellable; + + NMActRequest * queued_act_request; + bool queued_act_request_is_waiting_for_carrier : 1; + NMDBusTrackObjPath act_request; + + union { + struct { + guint activation_source_id_6; + guint activation_source_id_4; /* for layer2 and IPv4. */ + }; + guint activation_source_id_x[2]; + }; + + union { + struct { + ActivationHandleFunc activation_source_func_6; + ActivationHandleFunc activation_source_func_4; /* for layer2 and IPv4. */ + }; + ActivationHandleFunc activation_source_func_x[2]; + }; + + guint recheck_assume_id; + + struct { + guint call_id; + NMDeviceStateReason available_reason; + NMDeviceStateReason unavailable_reason; + } recheck_available; + + struct { + NMDispatcherCallId *call_id; + NMDeviceState post_state; + NMDeviceStateReason post_state_reason; + } dispatcher; + + /* Link stuff */ + guint link_connected_id; + guint link_disconnected_id; + guint carrier_defer_id; + guint carrier_wait_id; + gulong config_changed_id; + guint32 mtu; + guint32 ip6_mtu; + guint32 mtu_initial; + guint32 ip6_mtu_initial; + NMDeviceMtuSource mtu_source; + + guint32 v4_route_table; + guint32 v6_route_table; + + /* when carrier goes away, we give a grace period of _get_carrier_wait_ms() + * until taking action. + * + * When changing MTU, the device might take longer then that. So, whenever + * NM changes the MTU it sets @carrier_wait_until_ms to CARRIER_WAIT_TIME_AFTER_MTU_MS + * in the future. This is used to extend the grace period in this particular case. */ + gint64 carrier_wait_until_ms; + + union { + const NMDeviceSysIfaceState sys_iface_state; + NMDeviceSysIfaceState sys_iface_state_; + }; + + bool carrier : 1; + bool ignore_carrier : 1; + + bool up : 1; /* IFF_UP */ + + bool v4_commit_first_time : 1; + bool v6_commit_first_time : 1; + + bool default_route_metric_penalty_ip4_has : 1; + bool default_route_metric_penalty_ip6_has : 1; + + bool v4_route_table_initialized : 1; + bool v6_route_table_initialized : 1; + + bool l3config_merge_flags_has : 1; + + bool v4_route_table_all_sync_before : 1; + bool v6_route_table_all_sync_before : 1; + + NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags : 5; + + bool is_enslaved : 1; + + bool ipv6ll_handle : 1; /* TRUE if NM handles the device's IPv6LL address */ + bool ipv6ll_has : 1; + bool ndisc_started : 1; + bool device_link_changed_down : 1; + + bool concheck_rp_filter_checked : 1; + + NMDeviceStageState stage1_sriov_state : 3; + + /* Generic DHCP stuff */ + char *dhcp_anycast_address; + + char *current_stable_id; + + /* Proxy Configuration */ + NMProxyConfig * proxy_config; + NMPacrunnerConfId *pacrunner_conf_id; + + /* IP configuration info. Combined config from VPN, settings, and device */ + union { + struct { + NMIP6Config *ip_config_6; + NMIP4Config *ip_config_4; + }; + NMIPConfig *ip_config_x[2]; + }; + + /* Config from DHCP, PPP, LLv4, etc */ + AppliedConfig dev_ip_config_4; + + /* config from the setting */ + union { + struct { + NMIP6Config *con_ip_config_6; + NMIP4Config *con_ip_config_4; + }; + NMIPConfig *con_ip_config_x[2]; + }; + + /* Stuff added outside NM */ + union { + struct { + NMIP6Config *ext_ip_config_6; + NMIP4Config *ext_ip_config_4; + }; + NMIPConfig *ext_ip_config_x[2]; + }; + + /* VPNs which use this device */ + union { + struct { + GSList *vpn_configs_6; + GSList *vpn_configs_4; + }; + GSList *vpn_configs_x[2]; + }; + + /* Extra device configuration, injected by the subclass of NMDevice. + * This is used for example by NMDeviceModem for WWAN configuration. */ + union { + struct { + AppliedConfig dev2_ip_config_6; + AppliedConfig dev2_ip_config_4; + }; + AppliedConfig dev2_ip_config_x[2]; + }; + + /* DHCPv4 tracking */ + struct { + char *pac_url; + } dhcp4; + + struct { + /* IP6 config from DHCP */ + AppliedConfig ip6_config; + /* Event ID of the current IP6 config from DHCP */ + char * event_id; + gulong prefix_sigid; + NMNDiscDHCPLevel mode; + guint needed_prefixes; + } dhcp6; + + union { + struct { + DhcpData dhcp_data_6; + DhcpData dhcp_data_4; + }; + DhcpData dhcp_data_x[2]; + }; + + struct { + NMLogDomain log_domain; + guint timeout; + guint watch; + GPid pid; + char * binary; + char * address; + guint deadline; + } gw_ping; + + /* dnsmasq stuff for shared connections */ + NMDnsMasqManager *dnsmasq_manager; + gulong dnsmasq_state_id; + + /* Firewall */ + FirewallState fw_state : 4; + NMFirewallManager * fw_mgr; + NMFirewallManagerCallId *fw_call; + + /* IPv4LL stuff */ + sd_ipv4ll *ipv4ll; + guint ipv4ll_timeout; + guint rt6_temporary_not_available_id; + + /* IPv4 DAD stuff */ + struct { + GSList * dad_list; + NMAcdManager *announcing; + } acd; + + union { + struct { + const NMDeviceIPState ip_state_6; + const NMDeviceIPState ip_state_4; + }; + union { + const NMDeviceIPState ip_state_x[2]; + NMDeviceIPState ip_state_x_[2]; + }; + }; + + AppliedConfig ac_ip6_config; /* config from IPv6 autoconfiguration */ + NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */ + NMIP6Config * dad6_ip6_config; + struct in6_addr ipv6ll_addr; + + GHashTable *rt6_temporary_not_available; + + NMNDisc * ndisc; + gulong ndisc_changed_id; + gulong ndisc_timeout_id; + NMSettingIP6ConfigPrivacy ndisc_use_tempaddr; + + guint linklocal6_timeout_id; + guint8 linklocal6_dad_counter; + + GHashTable *ip6_saved_properties; + + EthtoolState *ethtool_state; + + gboolean needs_ip6_subnet; + + /* master interface for bridge/bond/team slave */ + NMDevice *master; + gulong master_ready_id; + + /* slave management */ + CList slaves; /* list of SlaveInfo */ + + NMMetered metered; + + NMSettings *settings; + NMManager * manager; + + NMNetns *netns; + + NMLldpListener *lldp_listener; + + NMConnectivity *concheck_mgr; + CList concheck_lst_head; + struct { + /* if periodic checks are enabled, this is the source id for the next check. */ + guint p_cur_id; + + /* the currently configured max periodic interval. */ + guint p_max_interval; + + /* the current interval. If we are probing, the interval might be lower + * then the configured max interval. */ + guint p_cur_interval; + + /* the timestamp, when we last scheduled the timer p_cur_id with current interval + * p_cur_interval. */ + gint64 p_cur_basetime_ns; + + NMConnectivityState state; + } concheck_x[2]; + + guint check_delete_unrealized_id; + guint32 interface_flags; + + struct { + SriovOp *pending; /* SR-IOV operation currently running */ + SriovOp *next; /* next SR-IOV operation scheduled */ + } sriov; + guint sriov_reset_pending; - NMActRequest * queued_act_request; - bool queued_act_request_is_waiting_for_carrier:1; - NMDBusTrackObjPath act_request; - - union { - struct { - guint activation_source_id_6; - guint activation_source_id_4; /* for layer2 and IPv4. */ - }; - guint activation_source_id_x[2]; - }; - - union { - struct { - ActivationHandleFunc activation_source_func_6; - ActivationHandleFunc activation_source_func_4; /* for layer2 and IPv4. */ - }; - ActivationHandleFunc activation_source_func_x[2]; - }; - - guint recheck_assume_id; - - struct { - guint call_id; - NMDeviceStateReason available_reason; - NMDeviceStateReason unavailable_reason; - } recheck_available; - - struct { - NMDispatcherCallId *call_id; - NMDeviceState post_state; - NMDeviceStateReason post_state_reason; - } dispatcher; - - /* Link stuff */ - guint link_connected_id; - guint link_disconnected_id; - guint carrier_defer_id; - guint carrier_wait_id; - gulong config_changed_id; - guint32 mtu; - guint32 ip6_mtu; - guint32 mtu_initial; - guint32 ip6_mtu_initial; - NMDeviceMtuSource mtu_source; - - guint32 v4_route_table; - guint32 v6_route_table; - - /* when carrier goes away, we give a grace period of _get_carrier_wait_ms() - * until taking action. - * - * When changing MTU, the device might take longer then that. So, whenever - * NM changes the MTU it sets @carrier_wait_until_ms to CARRIER_WAIT_TIME_AFTER_MTU_MS - * in the future. This is used to extend the grace period in this particular case. */ - gint64 carrier_wait_until_ms; - - bool carrier:1; - bool ignore_carrier:1; - - bool up:1; /* IFF_UP */ - - bool v4_commit_first_time:1; - bool v6_commit_first_time:1; - - bool default_route_metric_penalty_ip4_has:1; - bool default_route_metric_penalty_ip6_has:1; - - NMDeviceSysIfaceState sys_iface_state:2; - - bool v4_route_table_initialized:1; - bool v6_route_table_initialized:1; - - bool v4_route_table_all_sync_before:1; - bool v6_route_table_all_sync_before:1; - - NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:5; - - bool is_enslaved:1; - - bool ipv6ll_handle:1; /* TRUE if NM handles the device's IPv6LL address */ - bool ipv6ll_has:1; - bool ndisc_started:1; - bool device_link_changed_down:1; - - bool concheck_rp_filter_checked:1; - - NMDeviceStageState stage1_sriov_state:3; - - /* Generic DHCP stuff */ - char * dhcp_anycast_address; - - char * current_stable_id; - - /* Proxy Configuration */ - NMProxyConfig *proxy_config; - NMPacrunnerConfId *pacrunner_conf_id; - - /* IP configuration info. Combined config from VPN, settings, and device */ - union { - struct { - NMIP6Config *ip_config_6; - NMIP4Config *ip_config_4; - }; - NMIPConfig *ip_config_x[2]; - }; - - /* Config from DHCP, PPP, LLv4, etc */ - AppliedConfig dev_ip_config_4; - - /* config from the setting */ - union { - struct { - NMIP6Config *con_ip_config_6; - NMIP4Config *con_ip_config_4; - }; - NMIPConfig *con_ip_config_x[2]; - }; - - /* Stuff added outside NM */ - union { - struct { - NMIP6Config *ext_ip_config_6; - NMIP4Config *ext_ip_config_4; - }; - NMIPConfig *ext_ip_config_x[2]; - }; - - /* VPNs which use this device */ - union { - struct { - GSList *vpn_configs_6; - GSList *vpn_configs_4; - }; - GSList *vpn_configs_x[2]; - }; - - /* Extra device configuration, injected by the subclass of NMDevice. - * This is used for example by NMDeviceModem for WWAN configuration. */ - union { - struct { - AppliedConfig dev2_ip_config_6; - AppliedConfig dev2_ip_config_4; - }; - AppliedConfig dev2_ip_config_x[2]; - }; - - /* DHCPv4 tracking */ - struct { - char * pac_url; - char * root_path; - } dhcp4; - - struct { - /* IP6 config from DHCP */ - AppliedConfig ip6_config; - /* Event ID of the current IP6 config from DHCP */ - char * event_id; - gulong prefix_sigid; - NMNDiscDHCPLevel mode; - guint needed_prefixes; - } dhcp6; - - union { - struct { - DhcpData dhcp_data_6; - DhcpData dhcp_data_4; - }; - DhcpData dhcp_data_x[2]; - }; - - struct { - NMLogDomain log_domain; - guint timeout; - guint watch; - GPid pid; - char *binary; - char *address; - guint deadline; - } gw_ping; - - /* dnsmasq stuff for shared connections */ - NMDnsMasqManager *dnsmasq_manager; - gulong dnsmasq_state_id; - - /* Firewall */ - FirewallState fw_state:4; - NMFirewallManager *fw_mgr; - NMFirewallManagerCallId *fw_call; - - /* IPv4LL stuff */ - sd_ipv4ll * ipv4ll; - guint ipv4ll_timeout; - guint rt6_temporary_not_available_id; - - /* IPv4 DAD stuff */ - struct { - GSList * dad_list; - NMAcdManager * announcing; - } acd; - - union { - struct { - const NMDeviceIPState ip_state_6; - const NMDeviceIPState ip_state_4; - }; - union { - const NMDeviceIPState ip_state_x[2]; - NMDeviceIPState ip_state_x_[2]; - }; - }; - - AppliedConfig ac_ip6_config; /* config from IPv6 autoconfiguration */ - NMIP6Config * ext_ip6_config_captured; /* Configuration captured from platform. */ - NMIP6Config * dad6_ip6_config; - struct in6_addr ipv6ll_addr; - - GHashTable * rt6_temporary_not_available; - - NMNDisc * ndisc; - gulong ndisc_changed_id; - gulong ndisc_timeout_id; - NMSettingIP6ConfigPrivacy ndisc_use_tempaddr; - - guint linklocal6_timeout_id; - guint8 linklocal6_dad_counter; - - GHashTable * ip6_saved_properties; - - EthtoolState *ethtool_state; - - gboolean needs_ip6_subnet; - - /* master interface for bridge/bond/team slave */ - NMDevice * master; - gulong master_ready_id; - - /* slave management */ - CList slaves; /* list of SlaveInfo */ - - NMMetered metered; - - NMSettings *settings; - NMManager *manager; - - NMNetns *netns; - - NMLldpListener *lldp_listener; - - NMConnectivity *concheck_mgr; - CList concheck_lst_head; - struct { - /* if periodic checks are enabled, this is the source id for the next check. */ - guint p_cur_id; - - /* the currently configured max periodic interval. */ - guint p_max_interval; - - /* the current interval. If we are probing, the interval might be lower - * then the configured max interval. */ - guint p_cur_interval; - - /* the timestamp, when we last scheduled the timer p_cur_id with current interval - * p_cur_interval. */ - gint64 p_cur_basetime_ns; - - NMConnectivityState state; - } concheck_x[2]; - - guint check_delete_unrealized_id; - guint32 interface_flags; - - struct { - SriovOp *pending; /* SR-IOV operation currently running */ - SriovOp *next; /* next SR-IOV operation scheduled */ - } sriov; - guint sriov_reset_pending; - - struct { - guint timeout_id; - guint refresh_rate_ms; - guint64 tx_bytes; - guint64 rx_bytes; - } stats; + struct { + guint timeout_id; + guint refresh_rate_ms; + guint64 tx_bytes; + guint64 rx_bytes; + } stats; } NMDevicePrivate; -G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) +G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) #define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE) /*****************************************************************************/ static const NMDBusInterfaceInfoExtended interface_info_device; -static const GDBusSignalInfo signal_info_state_changed; - -static void nm_device_set_proxy_config (NMDevice *self, const char *pac_url); - -static gboolean update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_configs); - -static gboolean nm_device_set_ip_config (NMDevice *self, - int addr_family, - NMIPConfig *config, - gboolean commit, - GPtrArray *ip4_dev_route_blacklist); - -static gboolean ip_config_merge_and_apply (NMDevice *self, - int addr_family, - gboolean commit); - -static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); -static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); -static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason); - -static void addrconf6_start_with_link_ready (NMDevice *self); -static gboolean linklocal6_start (NMDevice *self); - -static void _carrier_wait_check_queued_act_request (NMDevice *self); -static gint64 _get_carrier_wait_ms (NMDevice *self); - -static const char *_activation_func_to_string (ActivationHandleFunc func); - -static void _set_state_full (NMDevice *self, - NMDeviceState state, - NMDeviceStateReason reason, - gboolean quitting); -static void queued_state_clear (NMDevice *device); -static gboolean queued_ip4_config_change (gpointer user_data); -static gboolean queued_ip6_config_change (gpointer user_data); -static void ip_check_ping_watch_cb (GPid pid, int status, gpointer user_data); -static gboolean ip_config_valid (NMDeviceState state); -static NMActStageReturn dhcp4_start (NMDevice *self); -static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll); -static void nm_device_start_ip_check (NMDevice *self); -static void realize_start_setup (NMDevice *self, - const NMPlatformLink *plink, - gboolean assume_state_guess_assume, - const char *assume_state_connection_uuid, - gboolean set_nm_owned, - NMUnmanFlagOp unmanaged_user_explicit, - gboolean force_platform_init); -static void _set_mtu (NMDevice *self, guint32 mtu); -static void _commit_mtu (NMDevice *self, const NMIP4Config *config); -static void _cancel_activation (NMDevice *self); - -static void concheck_update_state (NMDevice *self, - int addr_family, - NMConnectivityState state, - gboolean is_periodic); - -static void activate_stage4_ip_config_timeout_4 (NMDevice *self); -static void activate_stage4_ip_config_timeout_6 (NMDevice *self); - -static void (*const activate_stage4_ip_config_timeout_x[2]) (NMDevice *self) = { - activate_stage4_ip_config_timeout_6, - activate_stage4_ip_config_timeout_4, +static const GDBusSignalInfo signal_info_state_changed; + +static void nm_device_set_proxy_config(NMDevice *self, const char *pac_url); + +static gboolean update_ext_ip_config(NMDevice *self, int addr_family, gboolean intersect_configs); + +static gboolean nm_device_set_ip_config(NMDevice * self, + int addr_family, + NMIPConfig *config, + gboolean commit, + GPtrArray * ip4_dev_route_blacklist); + +static gboolean ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit); + +static gboolean nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure); +static void nm_device_slave_notify_enslave(NMDevice *self, gboolean success); +static void nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason); + +static void addrconf6_start_with_link_ready(NMDevice *self); +static gboolean linklocal6_start(NMDevice *self); + +static guint32 default_route_metric_penalty_get(NMDevice *self, int addr_family); + +static guint _prop_get_ipv4_dad_timeout(NMDevice *self); + +static void _carrier_wait_check_queued_act_request(NMDevice *self); +static gint64 _get_carrier_wait_ms(NMDevice *self); + +static const char *_activation_func_to_string(ActivationHandleFunc func); + +static void +_set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting); +static void queued_state_clear(NMDevice *device); +static gboolean queued_ip4_config_change(gpointer user_data); +static gboolean queued_ip6_config_change(gpointer user_data); +static void ip_check_ping_watch_cb(GPid pid, int status, gpointer user_data); +static gboolean ip_config_valid(NMDeviceState state); +static NMActStageReturn dhcp4_start(NMDevice *self); +static gboolean dhcp6_start(NMDevice *self, gboolean wait_for_ll); +static void nm_device_start_ip_check(NMDevice *self); +static void realize_start_setup(NMDevice * self, + const NMPlatformLink *plink, + gboolean assume_state_guess_assume, + const char * assume_state_connection_uuid, + gboolean set_nm_owned, + NMUnmanFlagOp unmanaged_user_explicit, + gboolean force_platform_init); +static void _set_mtu(NMDevice *self, guint32 mtu); +static void _commit_mtu(NMDevice *self, const NMIP4Config *config); +static void _cancel_activation(NMDevice *self); + +static void concheck_update_state(NMDevice * self, + int addr_family, + NMConnectivityState state, + gboolean is_periodic); + +static void activate_stage4_ip_config_timeout_4(NMDevice *self); +static void activate_stage4_ip_config_timeout_6(NMDevice *self); + +static void (*const activate_stage4_ip_config_timeout_x[2])(NMDevice *self) = { + activate_stage4_ip_config_timeout_6, + activate_stage4_ip_config_timeout_4, }; -static void sriov_op_cb (GError *error, gpointer user_data); +static void sriov_op_cb(GError *error, gpointer user_data); -static void activate_stage5_ip_config_result_4 (NMDevice *self); -static void activate_stage5_ip_config_result_6 (NMDevice *self); +static void activate_stage5_ip_config_result_4(NMDevice *self); +static void activate_stage5_ip_config_result_6(NMDevice *self); -static void (*const activate_stage5_ip_config_result_x[2]) (NMDevice *self) = { - activate_stage5_ip_config_result_6, - activate_stage5_ip_config_result_4, +static void (*const activate_stage5_ip_config_result_x[2])(NMDevice *self) = { + activate_stage5_ip_config_result_6, + activate_stage5_ip_config_result_4, }; /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (queued_state_to_string, NMDeviceState, - NM_UTILS_LOOKUP_DEFAULT ( NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNKNOWN, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNMANAGED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_UNAVAILABLE, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DISCONNECTED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_PREPARE, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_CONFIG, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_NEED_AUTH, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CONFIG, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_IP_CHECK, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_SECONDARIES, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_ACTIVATED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_DEACTIVATING, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_FAILED, NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), -); +static NM_UTILS_LOOKUP_STR_DEFINE( + queued_state_to_string, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNKNOWN, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNMANAGED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNAVAILABLE, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DISCONNECTED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_PREPARE, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_CONFIG, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_NEED_AUTH, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CONFIG, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CHECK, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_SECONDARIES, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_ACTIVATED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DEACTIVATING, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_FAILED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), ); const char * -nm_device_state_to_str (NMDeviceState state) -{ - return queued_state_to_string (state) + NM_STRLEN (NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); -} - -NM_UTILS_LOOKUP_STR_DEFINE (nm_device_state_reason_to_str, NMDeviceStateReason, - NM_UTILS_LOOKUP_DEFAULT (NULL), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NOW_MANAGED, "managed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "unmanaged"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONFIG_FAILED, "config-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "ip-config-unavailable"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "ip-config-expired"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NO_SECRETS, "no-secrets"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "supplicant-disconnect"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, "supplicant-config-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "supplicant-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "supplicant-timeout"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_START_FAILED, "ppp-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "ppp-disconnect"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PPP_FAILED, "ppp-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "dhcp-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_ERROR, "dhcp-error"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DHCP_FAILED, "dhcp-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "sharing-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SHARED_FAILED, "sharing-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "autoip-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "autoip-error"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "autoip-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_BUSY, "modem-busy"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "modem-no-dialtone"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "modem-no-carrier"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "modem-dial-timeout"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "modem-dial-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "modem-init-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "gsm-apn-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, "gsm-registration-idle"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, "gsm-registration-denied"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, "gsm-registration-timeout"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, "gsm-registration-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "gsm-pin-check-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "firmware-missing"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_REMOVED, "removed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SLEEPING, "sleeping"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "connection-removed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_USER_REQUESTED, "user-requested"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CARRIER, "carrier-changed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "connection-assumed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "supplicant-available"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "modem-not-found"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_BT_FAILED, "bluetooth-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "gsm-sim-not-inserted"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "gsm-sim-pin-required"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "gsm-sim-puk-required"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "gsm-sim-wrong"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "infiniband-mode"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "dependency-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_BR2684_FAILED, "br2684-bridge-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, "modem-manager-unavailable"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "ssid-not-found"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, "secondary-connection-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "dcb-fcoe-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "teamd-control-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_FAILED, "modem-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "modem-available"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "sim-pin-incorrect"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, "parent-managed-changed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, "sriov-configuration-failed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"), -); - -#define reason_to_string_a(reason) NM_UTILS_LOOKUP_STR_A (nm_device_state_reason_to_str, reason) - -static -NM_UTILS_LOOKUP_STR_DEFINE (mtu_source_to_str, NMDeviceMtuSource, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_PARENT, "parent"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_IP_CONFIG, "ip-config"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_MTU_SOURCE_CONNECTION, "connection"), -); +nm_device_state_to_str(NMDeviceState state) +{ + return queued_state_to_string(state) + NM_STRLEN(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); +} + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_device_state_reason_to_str, + NMDeviceStateReason, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, "managed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "unmanaged"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, "config-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "ip-config-unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "ip-config-expired"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, "no-secrets"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "supplicant-disconnect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, + "supplicant-config-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "supplicant-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "supplicant-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, "ppp-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "ppp-disconnect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, "ppp-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "dhcp-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, "dhcp-error"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, "dhcp-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "sharing-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, "sharing-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "autoip-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "autoip-error"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "autoip-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, "modem-busy"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "modem-no-dialtone"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "modem-no-carrier"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "modem-dial-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "modem-dial-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "modem-init-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "gsm-apn-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, + "gsm-registration-idle"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, + "gsm-registration-denied"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, + "gsm-registration-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, + "gsm-registration-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "gsm-pin-check-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "firmware-missing"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_REMOVED, "removed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, "sleeping"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "connection-removed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, "user-requested"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CARRIER, "carrier-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "connection-assumed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "supplicant-available"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "modem-not-found"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, "bluetooth-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "gsm-sim-not-inserted"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "gsm-sim-pin-required"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "gsm-sim-puk-required"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "gsm-sim-wrong"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "infiniband-mode"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "dependency-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, "br2684-bridge-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, + "modem-manager-unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "ssid-not-found"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, + "secondary-connection-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "dcb-fcoe-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "teamd-control-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, "modem-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "modem-available"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "sim-pin-incorrect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, + "parent-managed-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, + "sriov-configuration-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"), ); + +#define reason_to_string_a(reason) NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, reason) + +static NM_UTILS_LOOKUP_STR_DEFINE(mtu_source_to_str, + NMDeviceMtuSource, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_PARENT, "parent"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_IP_CONFIG, + "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION, + "connection"), ); + +/*****************************************************************************/ + +static NMSettingIP6ConfigPrivacy +_ip6_privacy_clamp(NMSettingIP6ConfigPrivacy use_tempaddr) +{ + switch (use_tempaddr) { + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + return use_tempaddr; + default: + return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + } +} + +/*****************************************************************************/ + +static const char * +_prop_get_connection_stable_id(NMDevice * self, + NMConnection * connection, + NMUtilsStableType *out_stable_type) +{ + NMDevicePrivate *priv; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_CONNECTION(connection)); + nm_assert(out_stable_type); + + priv = NM_DEVICE_GET_PRIVATE(self); + + /* we cache the generated stable ID for the time of an activation. + * + * The reason is, that we don't want the stable-id to change as long + * as the device is active. + * + * Especially with ${RANDOM} stable-id we want to generate *one* configuration + * for each activation. */ + if (G_UNLIKELY(!priv->current_stable_id)) { + gs_free char * default_id = NULL; + gs_free char * generated = NULL; + NMUtilsStableType stable_type; + NMSettingConnection *s_con; + gboolean hwaddr_is_fake; + const char * hwaddr; + const char * stable_id; + const char * uuid; + + s_con = nm_connection_get_setting_connection(connection); + + stable_id = nm_setting_connection_get_stable_id(s_con); + + if (!stable_id) { + default_id = + nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.stable-id"), + self); + stable_id = default_id; + } + + uuid = nm_connection_get_uuid(connection); + + /* the cloned-mac-address may be generated based on the stable-id. + * Thus, at this point, we can only use the permanent MAC address + * as seed. */ + hwaddr = nm_device_get_permanent_hw_address_full(self, TRUE, &hwaddr_is_fake); + + stable_type = nm_utils_stable_id_parse(stable_id, + nm_device_get_ip_iface(self), + !hwaddr_is_fake ? hwaddr : NULL, + nm_utils_boot_id_str(), + uuid, + &generated); + + /* current_stable_id_type is a bitfield! */ + priv->current_stable_id_type = stable_type; + nm_assert(stable_type <= (NMUtilsStableType) 0x3); + nm_assert(stable_type + (NMUtilsStableType) 1 > (NMUtilsStableType) 0); + nm_assert(priv->current_stable_id_type == stable_type); + + if (stable_type == NM_UTILS_STABLE_TYPE_UUID) + priv->current_stable_id = g_strdup(uuid); + else if (stable_type == NM_UTILS_STABLE_TYPE_STABLE_ID) + priv->current_stable_id = g_strdup(stable_id); + else if (stable_type == NM_UTILS_STABLE_TYPE_GENERATED) + priv->current_stable_id = + nm_str_realloc(nm_utils_stable_id_generated_complete(generated)); + else { + nm_assert(stable_type == NM_UTILS_STABLE_TYPE_RANDOM); + priv->current_stable_id = nm_str_realloc(nm_utils_stable_id_random()); + } + _LOGT(LOGD_DEVICE, + "stable-id: type=%d, \"%s\"" + "%s%s%s", + (int) priv->current_stable_id_type, + priv->current_stable_id, + NM_PRINT_FMT_QUOTED(stable_type == NM_UTILS_STABLE_TYPE_GENERATED, + " from \"", + generated, + "\"", + "")); + } + + nm_assert(priv->current_stable_id); + *out_stable_type = priv->current_stable_id_type; + return priv->current_stable_id; +} + +static GBytes * +_prop_get_ipv6_dhcp_duid(NMDevice * self, + NMConnection *connection, + GBytes * hwaddr, + gboolean * out_enforce) +{ + NMSettingIPConfig *s_ip6; + const char * duid; + gs_free char * duid_default = NULL; + const char * duid_error; + GBytes * duid_out; + gboolean duid_enforce = TRUE; + gs_free char * logstr1 = NULL; + const guint8 * hwaddr_bin; + gsize hwaddr_len; + int arp_type; + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + duid = nm_setting_ip6_config_get_dhcp_duid(NM_SETTING_IP6_CONFIG(s_ip6)); + + if (!duid) { + duid_default = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.dhcp-duid"), + self); + duid = duid_default; + if (!duid) + duid = "lease"; + } + + if (nm_streq(duid, "lease")) { + duid_enforce = FALSE; + duid_out = nm_utils_generate_duid_from_machine_id(); + goto out_good; + } + + if (!_nm_utils_dhcp_duid_valid(duid, &duid_out)) { + duid_error = "invalid duid"; + goto out_fail; + } + + if (duid_out) + goto out_good; + + if (NM_IN_STRSET(duid, "ll", "llt")) { + if (!hwaddr) { + duid_error = "missing link-layer address"; + goto out_fail; + } + + hwaddr_bin = g_bytes_get_data(hwaddr, &hwaddr_len); + arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len); + if (arp_type < 0) { + duid_error = "unsupported link-layer address"; + goto out_fail; + } + + if (nm_streq(duid, "ll")) + duid_out = nm_utils_generate_duid_ll(arp_type, hwaddr_bin, hwaddr_len); + else { + duid_out = nm_utils_generate_duid_llt(arp_type, + hwaddr_bin, + hwaddr_len, + nm_utils_host_id_get_timestamp_ns() + / NM_UTILS_NSEC_PER_SEC); + } + + goto out_good; + } + + if (NM_IN_STRSET(duid, "stable-ll", "stable-llt", "stable-uuid")) { + /* preferably, we would salt the checksum differently for each @duid type. We missed + * to do that initially, so most types use the DEFAULT_SALT. + * + * Implementations that are added later, should use a distinct salt instead, + * like "stable-ll"/"stable-llt" with ARPHRD_INFINIBAND below. */ + const guint32 DEFAULT_SALT = 670531087u; + nm_auto_free_checksum GChecksum *sum = NULL; + NMUtilsStableType stable_type; + const char * stable_id = NULL; + guint32 salted_header; + const guint8 * host_id; + gsize host_id_len; + union { + guint8 sha256[NM_UTILS_CHECKSUM_LENGTH_SHA256]; + guint8 hwaddr_eth[ETH_ALEN]; + guint8 hwaddr_infiniband[INFINIBAND_ALEN]; + NMUuid uuid; + struct _nm_packed { + guint8 hwaddr[ETH_ALEN]; + guint32 timestamp; + } llt_eth; + struct _nm_packed { + guint8 hwaddr[INFINIBAND_ALEN]; + guint32 timestamp; + } llt_infiniband; + } digest; + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + + if (NM_IN_STRSET(duid, "stable-ll", "stable-llt")) { + /* for stable LL/LLT DUIDs, we still need a hardware address to detect + * the arp-type. Alternatively, we would be able to detect it based on + * other means (e.g. NMDevice type), but instead require the hardware + * address to be present. This is at least consistent with the "ll"/"llt" + * modes above. */ + if (!hwaddr) { + duid_error = "missing link-layer address"; + goto out_fail; + } + if ((arp_type = nm_utils_arp_type_detect_from_hwaddrlen(g_bytes_get_size(hwaddr))) + < 0) { + duid_error = "unsupported link-layer address"; + goto out_fail; + } + + if (arp_type == ARPHRD_ETHER) + salted_header = DEFAULT_SALT; + else { + nm_assert(arp_type == ARPHRD_INFINIBAND); + salted_header = 0x42492CEFu + ((guint32) arp_type); + } + } else { + salted_header = DEFAULT_SALT; + arp_type = -1; + } + + salted_header = htonl(salted_header + ((guint32) stable_type)); + + nm_utils_host_id_get(&host_id, &host_id_len); + + sum = g_checksum_new(G_CHECKSUM_SHA256); + g_checksum_update(sum, (const guchar *) &salted_header, sizeof(salted_header)); + g_checksum_update(sum, (const guchar *) stable_id, -1); + g_checksum_update(sum, (const guchar *) host_id, host_id_len); + nm_utils_checksum_get_digest(sum, digest.sha256); + + G_STATIC_ASSERT_EXPR(sizeof(digest) == sizeof(digest.sha256)); + + if (nm_streq(duid, "stable-ll")) { + switch (arp_type) { + case ARPHRD_ETHER: + duid_out = nm_utils_generate_duid_ll(arp_type, + digest.hwaddr_eth, + sizeof(digest.hwaddr_eth)); + break; + case ARPHRD_INFINIBAND: + duid_out = nm_utils_generate_duid_ll(arp_type, + digest.hwaddr_infiniband, + sizeof(digest.hwaddr_infiniband)); + break; + default: + g_return_val_if_reached(NULL); + } + } else if (nm_streq(duid, "stable-llt")) { + gint64 time; + guint32 timestamp; + +#define EPOCH_DATETIME_THREE_YEARS (356 * 24 * 3600 * 3) + + /* We want a variable time between the host_id timestamp and three years + * before. Let's compute the time (in seconds) from 0 to 3 years; then we'll + * subtract it from the host_id timestamp. + */ + time = nm_utils_host_id_get_timestamp_ns() / NM_UTILS_NSEC_PER_SEC; + + /* don't use too old timestamps. They cannot be expressed in DUID-LLT and + * would all be truncated to zero. */ + time = NM_MAX(time, NM_UTILS_EPOCH_DATETIME_200001010000 + EPOCH_DATETIME_THREE_YEARS); + + switch (arp_type) { + case ARPHRD_ETHER: + timestamp = unaligned_read_be32(&digest.llt_eth.timestamp); + time -= timestamp % EPOCH_DATETIME_THREE_YEARS; + duid_out = nm_utils_generate_duid_llt(arp_type, + digest.llt_eth.hwaddr, + sizeof(digest.llt_eth.hwaddr), + time); + break; + case ARPHRD_INFINIBAND: + timestamp = unaligned_read_be32(&digest.llt_infiniband.timestamp); + time -= timestamp % EPOCH_DATETIME_THREE_YEARS; + duid_out = nm_utils_generate_duid_llt(arp_type, + digest.llt_infiniband.hwaddr, + sizeof(digest.llt_infiniband.hwaddr), + time); + break; + default: + g_return_val_if_reached(NULL); + } + } else { + nm_assert(nm_streq(duid, "stable-uuid")); + duid_out = nm_utils_generate_duid_uuid(&digest.uuid); + } + + goto out_good; + } + + g_return_val_if_reached(NULL); + +out_fail: + nm_assert(!duid_out && duid_error); + { + NMUuid uuid; + + _LOGW(LOGD_IP6 | LOGD_DHCP6, + "ipv6.dhcp-duid: failure to generate %s DUID: %s. Fallback to random DUID-UUID.", + duid, + duid_error); + + nm_utils_random_bytes(&uuid, sizeof(uuid)); + duid_out = nm_utils_generate_duid_uuid(&uuid); + } + +out_good: + nm_assert(duid_out); + _LOGD(LOGD_IP6 | LOGD_DHCP6, + "ipv6.dhcp-duid: generate %s DUID '%s' (%s)", + duid, + (logstr1 = nm_dhcp_utils_duid_to_string(duid_out)), + duid_enforce ? "enforcing" : "prefer lease"); + + NM_SET_OUT(out_enforce, duid_enforce); + return duid_out; +} + +static guint32 +_prop_get_ipv6_ra_timeout(NMDevice *self) +{ + NMConnection *connection; + gint32 timeout; + + G_STATIC_ASSERT_EXPR(NM_RA_TIMEOUT_DEFAULT == 0); + G_STATIC_ASSERT_EXPR(NM_RA_TIMEOUT_INFINITY == G_MAXINT32); + + connection = nm_device_get_applied_connection(self); + + timeout = nm_setting_ip6_config_get_ra_timeout( + NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(connection))); + if (timeout > 0) + return timeout; + nm_assert(timeout == 0); + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.ra-timeout"), + self, + 0, + G_MAXINT32, + 0); +} + +static NMSettingConnectionMdns +_prop_get_connection_mdns(NMDevice *self) +{ + NMConnection * connection; + NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_MDNS_DEFAULT); + + connection = nm_device_get_applied_connection(self); + if (connection) + mdns = nm_setting_connection_get_mdns(nm_connection_get_setting_connection(connection)); + if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) + return mdns; + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.mdns"), + self, + NM_SETTING_CONNECTION_MDNS_NO, + NM_SETTING_CONNECTION_MDNS_YES, + NM_SETTING_CONNECTION_MDNS_DEFAULT); +} + +static NMSettingConnectionLlmnr +_prop_get_connection_llmnr(NMDevice *self) +{ + NMConnection * connection; + NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_LLMNR_DEFAULT); + + connection = nm_device_get_applied_connection(self); + if (connection) + llmnr = nm_setting_connection_get_llmnr(nm_connection_get_setting_connection(connection)); + if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) + return llmnr; + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.llmnr"), + self, + NM_SETTING_CONNECTION_LLMNR_NO, + NM_SETTING_CONNECTION_LLMNR_YES, + NM_SETTING_CONNECTION_LLMNR_DEFAULT); +} + +static guint32 +_prop_get_ipvx_route_table(NMDevice *self, int addr_family) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceClass * klass; + NMConnection * connection; + NMSettingIPConfig * s_ip; + guint32 route_table = 0; + gboolean is_user_config = TRUE; + NMSettingConnection *s_con; + NMSettingVrf * s_vrf; + + nm_assert_addr_family(addr_family); + + /* the route table setting affects how we sync routes. We shall + * not change it while the device is active, hence, cache it. */ + if (addr_family == AF_INET) { + if (priv->v4_route_table_initialized) + return priv->v4_route_table; + } else { + if (priv->v6_route_table_initialized) + return priv->v6_route_table; + } + + connection = nm_device_get_applied_connection(self); + if (connection) { + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (s_ip) + route_table = nm_setting_ip_config_get_route_table(s_ip); + } + if (route_table == 0u) { + gint64 v; + + v = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? NM_CON_DEFAULT("ipv4.route-table") + : NM_CON_DEFAULT("ipv6.route-table"), + self, + 0, + G_MAXUINT32, + -1); + if (v != -1) { + route_table = v; + is_user_config = FALSE; + } + } + + if (route_table == 0u && connection + && (s_con = nm_connection_get_setting_connection(connection)) + && (nm_streq0(nm_setting_connection_get_slave_type(s_con), NM_SETTING_VRF_SETTING_NAME) + && priv->master && nm_device_get_device_type(priv->master) == NM_DEVICE_TYPE_VRF)) { + const NMPlatformLnkVrf *lnk; + + lnk = nm_platform_link_get_lnk_vrf(nm_device_get_platform(self), + nm_device_get_ifindex(priv->master), + NULL); + + if (lnk) + route_table = lnk->table; + } + + if (route_table == 0u && connection + && (s_vrf = (NMSettingVrf *) nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF))) { + route_table = nm_setting_vrf_get_table(s_vrf); + } + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->coerce_route_table) + route_table = klass->coerce_route_table(self, addr_family, route_table, is_user_config); + + if (addr_family == AF_INET) { + priv->v4_route_table_initialized = TRUE; + priv->v4_route_table = route_table; + } else { + priv->v6_route_table_initialized = TRUE; + priv->v6_route_table = route_table; + } + + _LOGT(LOGD_DEVICE, + "ipv%c.route-table = %u%s", + addr_family == AF_INET ? '4' : '6', + (guint)(route_table ?: RT_TABLE_MAIN), + route_table != 0u ? "" : " (policy routing not enabled)"); + + return route_table; +} + +static gboolean +_prop_get_connection_lldp(NMDevice *self) +{ + NMConnection * connection; + NMSettingConnection * s_con; + NMSettingConnectionLldp lldp = NM_SETTING_CONNECTION_LLDP_DEFAULT; + + connection = nm_device_get_applied_connection(self); + g_return_val_if_fail(connection, FALSE); + + s_con = nm_connection_get_setting_connection(connection); + g_return_val_if_fail(s_con, FALSE); + + lldp = nm_setting_connection_get_lldp(s_con); + if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) { + lldp = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.lldp"), + self, + NM_SETTING_CONNECTION_LLDP_DEFAULT, + NM_SETTING_CONNECTION_LLDP_ENABLE_RX, + NM_SETTING_CONNECTION_LLDP_DEFAULT); + if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) + lldp = NM_SETTING_CONNECTION_LLDP_DISABLE; + } + return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX; +} + +static guint +_prop_get_ipv4_dad_timeout(NMDevice *self) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip4 = NULL; + int timeout = -1; + + connection = nm_device_get_applied_connection(self); + if (connection) + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (s_ip4) + timeout = nm_setting_ip_config_get_dad_timeout(s_ip4); + if (timeout >= 0) + return timeout; + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dad-timeout"), + self, + 0, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, + 0); +} + +static guint32 +_prop_get_ipvx_dhcp_timeout(NMDevice *self, int addr_family) +{ + NMDeviceClass *klass; + NMConnection * connection; + int timeout_i; + guint32 timeout; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert_addr_family(addr_family); + + connection = nm_device_get_applied_connection(self); + + timeout_i = nm_setting_ip_config_get_dhcp_timeout( + nm_connection_get_setting_ip_config(connection, addr_family)); + nm_assert(timeout_i >= 0 && timeout_i <= G_MAXINT32); + + timeout = (guint32) timeout_i; + if (timeout) + goto out; + + timeout = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? NM_CON_DEFAULT("ipv4.dhcp-timeout") + : NM_CON_DEFAULT("ipv6.dhcp-timeout"), + self, + 0, + G_MAXINT32, + 0); + if (timeout) + goto out; + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->get_dhcp_timeout_for_device) { + timeout = klass->get_dhcp_timeout_for_device(self, addr_family); + if (timeout) + goto out; + } + + timeout = NM_DHCP_TIMEOUT_DEFAULT; + +out: + G_STATIC_ASSERT_EXPR(G_MAXINT32 == NM_DHCP_TIMEOUT_INFINITY); + nm_assert(timeout > 0); + nm_assert(timeout <= G_MAXINT32); + return timeout; +} + +/** + * _prop_get_ipvx_dhcp_iaid: + * @self: the #NMDevice + * @addr_family: the address family + * @connection: the connection + * @out_is_explicit: on return, %TRUE if the user set a valid IAID in + * the connection or in global configuration; %FALSE if the connection + * property was empty and no valid global configuration was provided. + * + * Returns: a IAID value for this device and the given connection. + */ +static guint32 +_prop_get_ipvx_dhcp_iaid(NMDevice * self, + int addr_family, + NMConnection *connection, + gboolean * out_is_explicit) +{ + NMSettingIPConfig *s_ip; + const char * iaid_str; + gs_free char * iaid_str_free = NULL; + guint32 iaid; + const char * iface; + const char * fail_reason; + gboolean is_explicit = TRUE; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + iaid_str = nm_setting_ip_config_get_dhcp_iaid(s_ip); + if (!iaid_str) { + iaid_str_free = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + addr_family == AF_INET ? NM_CON_DEFAULT("ipv4.dhcp-iaid") + : NM_CON_DEFAULT("ipv6.dhcp-iaid"), + self); + iaid_str = iaid_str_free; + if (!iaid_str) { + iaid_str = NM_IAID_IFNAME; + is_explicit = FALSE; + } else if (!_nm_utils_iaid_verify(iaid_str, NULL)) { + _LOGW(LOGD_DEVICE, + "invalid global default '%s' for ipv%c.dhcp-iaid", + iaid_str, + nm_utils_addr_family_to_char(addr_family)); + iaid_str = NM_IAID_IFNAME; + is_explicit = FALSE; + } + } + + if (nm_streq0(iaid_str, NM_IAID_MAC)) { + const NMPlatformLink *pllink; + + pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + if (!pllink || pllink->l_address.len < 4) { + fail_reason = "invalid link-layer address"; + goto out_fail; + } + + /* @iaid is in native endianness. Use unaligned_read_be32() + * so that the IAID for a given MAC address is the same on + * BE and LE machines. */ + iaid = unaligned_read_be32(&pllink->l_address.data[pllink->l_address.len - 4]); + goto out_good; + } else if (nm_streq0(iaid_str, NM_IAID_PERM_MAC)) { + guint8 hwaddr_buf[NM_UTILS_HWADDR_LEN_MAX]; + const char *hwaddr_str; + gsize hwaddr_len; + + hwaddr_str = nm_device_get_permanent_hw_address(self); + if (!hwaddr_str) { + fail_reason = "no permanent link-layer address"; + goto out_fail; + } + + if (!_nm_utils_hwaddr_aton(hwaddr_str, hwaddr_buf, sizeof(hwaddr_buf), &hwaddr_len)) + g_return_val_if_reached(0); + + if (hwaddr_len < 4) { + fail_reason = "invalid link-layer address"; + goto out_fail; + } + + iaid = unaligned_read_be32(&hwaddr_buf[hwaddr_len - 4]); + goto out_good; + } else if (nm_streq(iaid_str, "stable")) { + nm_auto_free_checksum GChecksum *sum = NULL; + guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1]; + NMUtilsStableType stable_type; + const char * stable_id; + guint32 salted_header; + const guint8 * host_id; + gsize host_id_len; + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + salted_header = htonl(53390459 + stable_type); + nm_utils_host_id_get(&host_id, &host_id_len); + iface = nm_device_get_ip_iface(self); + + sum = g_checksum_new(G_CHECKSUM_SHA1); + g_checksum_update(sum, (const guchar *) &salted_header, sizeof(salted_header)); + g_checksum_update(sum, (const guchar *) stable_id, strlen(stable_id) + 1); + g_checksum_update(sum, (const guchar *) iface, strlen(iface) + 1); + g_checksum_update(sum, (const guchar *) host_id, host_id_len); + nm_utils_checksum_get_digest(sum, digest); + + iaid = unaligned_read_be32(digest); + goto out_good; + } else if ((iaid = _nm_utils_ascii_str_to_int64(iaid_str, 10, 0, G_MAXUINT32, -1)) != -1) { + goto out_good; + } else { + iface = nm_device_get_ip_iface(self); + iaid = nm_utils_create_dhcp_iaid(TRUE, (const guint8 *) iface, strlen(iface)); + goto out_good; + } + +out_fail: + nm_assert(fail_reason); + _LOGW(addr_family == AF_INET ? (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4) + : (LOGD_DEVICE | LOGD_DHCP6 | LOGD_IP6), + "ipv%c.dhcp-iaid: failure to generate IAID: %s. Using interface-name based IAID", + nm_utils_addr_family_to_char(addr_family), + fail_reason); + is_explicit = FALSE; + iface = nm_device_get_ip_iface(self); + iaid = nm_utils_create_dhcp_iaid(TRUE, (const guint8 *) iface, strlen(iface)); +out_good: + _LOGD(addr_family == AF_INET ? (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4) + : (LOGD_DEVICE | LOGD_DHCP6 | LOGD_IP6), + "ipv%c.dhcp-iaid: using %u (0x%08x) IAID (str: '%s', explicit %d)", + nm_utils_addr_family_to_char(addr_family), + iaid, + iaid, + iaid_str, + is_explicit); + NM_SET_OUT(out_is_explicit, is_explicit); + return iaid; +} + +static NMDhcpHostnameFlags +_prop_get_ipvx_dhcp_hostname_flags(NMDevice *self, int addr_family) +{ + NMConnection * connection; + NMSettingIPConfig * s_ip; + NMDhcpHostnameFlags flags; + gs_free_error GError *error = NULL; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DHCP_HOSTNAME_FLAG_NONE); + + connection = nm_device_get_applied_connection(self); + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + g_return_val_if_fail(s_ip, NM_DHCP_HOSTNAME_FLAG_NONE); + + if (!nm_setting_ip_config_get_dhcp_send_hostname(s_ip)) + return NM_DHCP_HOSTNAME_FLAG_NONE; + + flags = nm_setting_ip_config_get_dhcp_hostname_flags(s_ip); + if (flags != NM_DHCP_HOSTNAME_FLAG_NONE) + return flags; + + flags = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + addr_family == AF_INET ? NM_CON_DEFAULT("ipv4.dhcp-hostname-flags") + : NM_CON_DEFAULT("ipv6.dhcp-hostname-flags"), + self, + 0, + NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS, + 0); + + if (!_nm_utils_validate_dhcp_hostname_flags(flags, addr_family, &error)) { + _LOGW(LOGD_DEVICE, + "invalid global default value 0x%x for ipv%d.%s: %s", + (guint) flags, + addr_family == AF_INET ? 4 : 6, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, + error->message); + flags = NM_DHCP_HOSTNAME_FLAG_NONE; + } + + if (flags != NM_DHCP_HOSTNAME_FLAG_NONE) + return flags; + + if (addr_family == AF_INET) + return NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP4; + else + return NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP6; +} + +static const char * +_prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con, char **out_mud_url) +{ + const char * mud_url; + gs_free char *s = NULL; + + nm_assert(out_mud_url && !*out_mud_url); + + mud_url = nm_setting_connection_get_mud_url(s_con); + + if (mud_url) { + if (nm_streq(mud_url, NM_CONNECTION_MUD_URL_NONE)) + return NULL; + return mud_url; + } + + s = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.mud-url"), + self); + if (s) { + if (nm_streq(s, NM_CONNECTION_MUD_URL_NONE)) + return NULL; + if (nm_sd_http_url_is_valid_https(s)) + return (*out_mud_url = g_steal_pointer(&s)); + } + + return NULL; +} + +static GBytes * +_prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes *hwaddr) +{ + NMSettingIPConfig *s_ip4; + const char * client_id; + gs_free char * client_id_default = NULL; + guint8 * client_id_buf; + const char * fail_reason; + guint8 hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX]; + const guint8 * hwaddr_bin; + int arp_type; + gsize hwaddr_len; + GBytes * result; + gs_free char * logstr1 = NULL; + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + client_id = nm_setting_ip4_config_get_dhcp_client_id(NM_SETTING_IP4_CONFIG(s_ip4)); + + if (!client_id) { + client_id_default = + nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-client-id"), + self); + if (client_id_default && client_id_default[0]) { + /* a non-empty client-id is always valid, see nm_dhcp_utils_client_id_string_to_bytes(). */ + client_id = client_id_default; + } + } + + if (!client_id) { + _LOGD(LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, + "ipv4.dhcp-client-id: no explicit client-id configured"); + return NULL; + } + + if (nm_streq(client_id, "mac")) { + if (!hwaddr) { + fail_reason = "missing link-layer address"; + goto out_fail; + } + + hwaddr_bin = g_bytes_get_data(hwaddr, &hwaddr_len); + arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len); + if (arp_type < 0) { + fail_reason = "unsupported link-layer address"; + goto out_fail; + } + + result = nm_utils_dhcp_client_id_mac(arp_type, hwaddr_bin, hwaddr_len); + goto out_good; + } + + if (nm_streq(client_id, "perm-mac")) { + const char *hwaddr_str; + + hwaddr_str = nm_device_get_permanent_hw_address(self); + if (!hwaddr_str) { + fail_reason = "missing permanent link-layer address"; + goto out_fail; + } + + if (!_nm_utils_hwaddr_aton(hwaddr_str, hwaddr_bin_buf, sizeof(hwaddr_bin_buf), &hwaddr_len)) + g_return_val_if_reached(NULL); + + arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len); + if (arp_type < 0) { + fail_reason = "unsupported permanent link-layer address"; + goto out_fail; + } + + result = nm_utils_dhcp_client_id_mac(arp_type, hwaddr_bin_buf, hwaddr_len); + goto out_good; + } + + if (nm_streq(client_id, "duid")) { + guint32 iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET, connection, NULL); + + result = nm_utils_dhcp_client_id_systemd_node_specific(iaid); + goto out_good; + } + + if (nm_streq(client_id, "stable")) { + nm_auto_free_checksum GChecksum *sum = NULL; + guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1]; + NMUtilsStableType stable_type; + const char * stable_id; + guint32 salted_header; + const guint8 * host_id; + gsize host_id_len; + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + salted_header = htonl(2011610591 + stable_type); + nm_utils_host_id_get(&host_id, &host_id_len); + + sum = g_checksum_new(G_CHECKSUM_SHA1); + g_checksum_update(sum, (const guchar *) &salted_header, sizeof(salted_header)); + g_checksum_update(sum, (const guchar *) stable_id, strlen(stable_id) + 1); + g_checksum_update(sum, (const guchar *) host_id, host_id_len); + nm_utils_checksum_get_digest(sum, digest); + + client_id_buf = g_malloc(1 + 15); + client_id_buf[0] = 0; + memcpy(&client_id_buf[1], digest, 15); + result = g_bytes_new_take(client_id_buf, 1 + 15); + goto out_good; + } + + result = nm_dhcp_utils_client_id_string_to_bytes(client_id); + goto out_good; + +out_fail: + nm_assert(fail_reason); + _LOGW(LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, + "ipv4.dhcp-client-id: failure to generate client id (%s). Use random client id", + fail_reason); + client_id_buf = g_malloc(1 + 15); + client_id_buf[0] = 0; + nm_utils_random_bytes(&client_id_buf[1], 15); + result = g_bytes_new_take(client_id_buf, 1 + 15); + +out_good: + nm_assert(result); + _LOGD(LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, + "ipv4.dhcp-client-id: use \"%s\" client ID: %s", + client_id, + (logstr1 = nm_dhcp_utils_duid_to_string(result))); + return result; +} + +static GBytes * +_prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config *s_ip4) +{ + gs_free char *config_data_prop = NULL; + gs_free char *to_free = NULL; + const char * conn_prop; + GBytes * bytes = NULL; + const char * bin; + gsize len; + + conn_prop = nm_setting_ip4_config_get_dhcp_vendor_class_identifier(s_ip4); + + if (!conn_prop) { + /* set in NetworkManager.conf ? */ + config_data_prop = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-vendor-class-identifier"), + self); + + if (config_data_prop && nm_utils_validate_dhcp4_vendor_class_id(config_data_prop, NULL)) + conn_prop = config_data_prop; + } + + if (conn_prop) { + bin = nm_utils_buf_utf8safe_unescape(conn_prop, + NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, + &len, + (gpointer *) &to_free); + if (to_free) + bytes = g_bytes_new_take(g_steal_pointer(&to_free), len); + else + bytes = g_bytes_new(bin, len); + } + + return bytes; +} + +static NMSettingIP6ConfigPrivacy +_prop_get_ipv6_ip6_privacy(NMDevice *self) +{ + NMSettingIP6ConfigPrivacy ip6_privacy; + NMConnection * connection; + + g_return_val_if_fail(self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + + /* 1.) First look at the per-connection setting. If it is not -1 (unknown), + * use it. */ + connection = nm_device_get_applied_connection(self); + if (connection) { + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection); + + if (s_ip6) { + ip6_privacy = nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)); + ip6_privacy = _ip6_privacy_clamp(ip6_privacy); + if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) + return ip6_privacy; + } + } + + /* 2.) use the default value from the configuration. */ + ip6_privacy = + nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.ip6-privacy"), + self, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) + return ip6_privacy; + + if (!nm_device_get_ip_ifindex(self)) + return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + + /* 3.) No valid default-value configured. Fallback to reading sysctl. + * + * Instead of reading static config files in /etc, just read the current sysctl value. + * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves + * the "default" entry untouched. */ + ip6_privacy = nm_platform_sysctl_get_int32( + nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv6/conf/default/use_tempaddr"), + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + return _ip6_privacy_clamp(ip6_privacy); +} + +static const char * +_prop_get_x_cloned_mac_address(NMDevice * self, + NMConnection *connection, + gboolean is_wifi, + char ** out_addr) +{ + NMSetting * setting; + const char *addr = NULL; + + nm_assert(out_addr && !*out_addr); + + setting = nm_connection_get_setting(connection, + is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); + if (setting) { + addr = is_wifi ? nm_setting_wireless_get_cloned_mac_address((NMSettingWireless *) setting) + : nm_setting_wired_get_cloned_mac_address((NMSettingWired *) setting); + } + + if (!addr) { + gs_free char *a = NULL; + + a = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + is_wifi ? NM_CON_DEFAULT("wifi.cloned-mac-address") + : NM_CON_DEFAULT("ethernet.cloned-mac-address"), + self); + + addr = NM_CLONED_MAC_PRESERVE; + + if (!a) { + if (is_wifi) { + NMSettingMacRandomization v; + + /* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */ + a = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("wifi.mac-address-randomization"), + self); + v = _nm_utils_ascii_str_to_int64(a, + 10, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT); + if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) + addr = NM_CLONED_MAC_RANDOM; + } + } else if (NM_CLONED_MAC_IS_SPECIAL(a) || nm_utils_hwaddr_valid(a, ETH_ALEN)) + addr = *out_addr = g_steal_pointer(&a); + } + + return addr; +} + +static const char * +_prop_get_x_generate_mac_address_mask(NMDevice * self, + NMConnection *connection, + gboolean is_wifi, + char ** out_value) +{ + NMSetting * setting; + const char *value = NULL; + char * a; + + nm_assert(out_value && !*out_value); + + setting = nm_connection_get_setting(connection, + is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); + if (setting) { + value = + is_wifi + ? nm_setting_wireless_get_generate_mac_address_mask((NMSettingWireless *) setting) + : nm_setting_wired_get_generate_mac_address_mask((NMSettingWired *) setting); + if (value) + return value; + } + + a = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + is_wifi ? NM_CON_DEFAULT("wifi.generate-mac-address-mask") + : NM_CON_DEFAULT("ethernet.generate-mac-address-mask"), + self); + if (!a) + return NULL; + *out_value = a; + return a; +} /*****************************************************************************/ static void -_ethtool_features_reset (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state) +_ethtool_features_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) { - gs_free NMEthtoolFeatureStates *features; + gs_free NMEthtoolFeatureStates *features; - features = g_steal_pointer (ðtool_state->features); + features = g_steal_pointer(ðtool_state->features); - if (!nm_platform_ethtool_set_features (platform, - ethtool_state->ifindex, - features, - ethtool_state->requested, - FALSE)) - _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more offload features"); - else - _LOGD (LOGD_DEVICE, "ethtool: offload features successfully reset"); + if (!nm_platform_ethtool_set_features(platform, + ethtool_state->ifindex, + features, + ethtool_state->requested, + FALSE)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more offload features"); + else + _LOGD(LOGD_DEVICE, "ethtool: offload features successfully reset"); } static void -_ethtool_features_set (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state, - NMSettingEthtool *s_ethtool) +_ethtool_features_set(NMDevice * self, + NMPlatform * platform, + EthtoolState * ethtool_state, + NMSettingEthtool *s_ethtool) { - gs_free NMEthtoolFeatureStates *features = NULL; + gs_free NMEthtoolFeatureStates *features = NULL; - if (ethtool_state->features) - _ethtool_features_reset (self, platform, ethtool_state); + if (ethtool_state->features) + _ethtool_features_reset(self, platform, ethtool_state); - if (nm_setting_ethtool_init_features (s_ethtool, ethtool_state->requested) == 0) - return; + if (nm_setting_ethtool_init_features(s_ethtool, ethtool_state->requested) == 0) + return; - features = nm_platform_ethtool_get_link_features (platform, - ethtool_state->ifindex); - if (!features) { - _LOGW (LOGD_DEVICE, "ethtool: failure setting offload features (cannot read features)"); - return; - } + features = nm_platform_ethtool_get_link_features(platform, ethtool_state->ifindex); + if (!features) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting offload features (cannot read features)"); + return; + } - if (!nm_platform_ethtool_set_features (platform, - ethtool_state->ifindex, - features, - ethtool_state->requested, - TRUE)) - _LOGW (LOGD_DEVICE, "ethtool: failure setting one or more offload features"); - else - _LOGD (LOGD_DEVICE, "ethtool: offload features successfully set"); + if (!nm_platform_ethtool_set_features(platform, + ethtool_state->ifindex, + features, + ethtool_state->requested, + TRUE)) + _LOGW(LOGD_DEVICE, "ethtool: failure setting one or more offload features"); + else + _LOGD(LOGD_DEVICE, "ethtool: offload features successfully set"); - ethtool_state->features = g_steal_pointer (&features); + ethtool_state->features = g_steal_pointer(&features); } static void -_ethtool_coalesce_reset (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state) +_ethtool_coalesce_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) { - gs_free NMEthtoolCoalesceState *coalesce = NULL; + gs_free NMEthtoolCoalesceState *coalesce = NULL; - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_PLATFORM (platform)); - nm_assert (ethtool_state); + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(ethtool_state); - coalesce = g_steal_pointer (ðtool_state->coalesce); - if (!coalesce) - return; + coalesce = g_steal_pointer(ðtool_state->coalesce); + if (!coalesce) + return; - if (!nm_platform_ethtool_set_coalesce (platform, - ethtool_state->ifindex, - coalesce)) - _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more coalesce settings"); - else - _LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully reset"); + if (!nm_platform_ethtool_set_coalesce(platform, ethtool_state->ifindex, coalesce)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more coalesce settings"); + else + _LOGD(LOGD_DEVICE, "ethtool: coalesce settings successfully reset"); } static void -_ethtool_coalesce_set (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state, - NMSettingEthtool *s_ethtool) -{ - NMEthtoolCoalesceState coalesce_old; - NMEthtoolCoalesceState coalesce_new; - gboolean has_old = FALSE; - GHashTable *hash; - GHashTableIter iter; - const char *name; - GVariant *variant; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_PLATFORM (platform)); - nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool)); - nm_assert (ethtool_state); - nm_assert (!ethtool_state->coalesce); - - hash = _nm_setting_option_hash (NM_SETTING (s_ethtool), FALSE); - if (!hash) - return; - - g_hash_table_iter_init (&iter, hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) { - NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name (name); - - if (!nm_ethtool_id_is_coalesce (ethtool_id)) - continue; - - if (!has_old) { - if (!nm_platform_ethtool_get_link_coalesce (platform, - ethtool_state->ifindex, - &coalesce_old)) { - _LOGW (LOGD_DEVICE, "ethtool: failure getting coalesce settings (cannot read)"); - return; - } - has_old = TRUE; - coalesce_new = coalesce_old; - } - - nm_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)); - coalesce_new.s[_NM_ETHTOOL_ID_COALESCE_AS_IDX (ethtool_id)] = g_variant_get_uint32 (variant); - } - - if (!has_old) - return; - - ethtool_state->coalesce = nm_memdup (&coalesce_old, sizeof (coalesce_old)); - - if (!nm_platform_ethtool_set_coalesce (platform, - ethtool_state->ifindex, - &coalesce_new)) { - _LOGW (LOGD_DEVICE, "ethtool: failure setting coalesce settings"); - return; - } - - _LOGD (LOGD_DEVICE, "ethtool: coalesce settings successfully set"); +_ethtool_coalesce_set(NMDevice * self, + NMPlatform * platform, + EthtoolState * ethtool_state, + NMSettingEthtool *s_ethtool) +{ + NMEthtoolCoalesceState coalesce_old; + NMEthtoolCoalesceState coalesce_new; + gboolean has_old = FALSE; + GHashTable * hash; + GHashTableIter iter; + const char * name; + GVariant * variant; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + nm_assert(ethtool_state); + nm_assert(!ethtool_state->coalesce); + + hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE); + if (!hash) + return; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name); + + if (!nm_ethtool_id_is_coalesce(ethtool_id)) + continue; + + if (!has_old) { + if (!nm_platform_ethtool_get_link_coalesce(platform, + ethtool_state->ifindex, + &coalesce_old)) { + _LOGW(LOGD_DEVICE, "ethtool: failure getting coalesce settings (cannot read)"); + return; + } + has_old = TRUE; + coalesce_new = coalesce_old; + } + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + coalesce_new.s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(ethtool_id)] = g_variant_get_uint32(variant); + } + + if (!has_old) + return; + + ethtool_state->coalesce = nm_memdup(&coalesce_old, sizeof(coalesce_old)); + + if (!nm_platform_ethtool_set_coalesce(platform, ethtool_state->ifindex, &coalesce_new)) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting coalesce settings"); + return; + } + + _LOGD(LOGD_DEVICE, "ethtool: coalesce settings successfully set"); } static void -_ethtool_ring_reset (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state) +_ethtool_ring_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) { - gs_free NMEthtoolRingState *ring = NULL; + gs_free NMEthtoolRingState *ring = NULL; - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_PLATFORM (platform)); - nm_assert (ethtool_state); + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(ethtool_state); - ring = g_steal_pointer (ðtool_state->ring); - if (!ring) - return; + ring = g_steal_pointer(ðtool_state->ring); + if (!ring) + return; - if (!nm_platform_ethtool_set_ring (platform, - ethtool_state->ifindex, - ring)) - _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more ring settings"); - else - _LOGD (LOGD_DEVICE, "ethtool: ring settings successfully reset"); + if (!nm_platform_ethtool_set_ring(platform, ethtool_state->ifindex, ring)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more ring settings"); + else + _LOGD(LOGD_DEVICE, "ethtool: ring settings successfully reset"); } static void -_ethtool_ring_set (NMDevice *self, - NMPlatform *platform, - EthtoolState *ethtool_state, - NMSettingEthtool *s_ethtool) -{ - NMEthtoolRingState ring_old; - NMEthtoolRingState ring_new; - GHashTable *hash; - GHashTableIter iter; - const char *name; - GVariant *variant; - gboolean has_old = FALSE; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_PLATFORM (platform)); - nm_assert (NM_IS_SETTING_ETHTOOL (s_ethtool)); - nm_assert (ethtool_state); - nm_assert (!ethtool_state->ring); - - hash = _nm_setting_option_hash (NM_SETTING (s_ethtool), FALSE); - if (!hash) - return; - - g_hash_table_iter_init (&iter, hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) { - NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name (name); - guint32 u32; - - if (!nm_ethtool_id_is_ring (ethtool_id)) - continue; - - nm_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)); - - if (!has_old) { - if (!nm_platform_ethtool_get_link_ring (platform, - ethtool_state->ifindex, - &ring_old)) { - _LOGW (LOGD_DEVICE, "ethtool: failure setting ring options (cannot read existing setting)"); - return; - } - has_old = TRUE; - ring_new = ring_old; - } - - u32 = g_variant_get_uint32 (variant); - - switch (ethtool_id) { - case NM_ETHTOOL_ID_RING_RX: - ring_new.rx_pending = u32; - break; - case NM_ETHTOOL_ID_RING_RX_JUMBO: - ring_new.rx_jumbo_pending = u32; - break; - case NM_ETHTOOL_ID_RING_RX_MINI: - ring_new.rx_mini_pending = u32; - break; - case NM_ETHTOOL_ID_RING_TX: - ring_new.tx_pending = u32; - break; - default: - nm_assert_not_reached (); - } - } - - if (!has_old) - return; - - ethtool_state->ring = nm_memdup (&ring_old, sizeof (ring_old)); - - if (!nm_platform_ethtool_set_ring (platform, - ethtool_state->ifindex, - &ring_new)) { - _LOGW (LOGD_DEVICE, "ethtool: failure setting ring settings"); - return; - } - - _LOGD (LOGD_DEVICE, "ethtool: ring settings successfully set"); +_ethtool_ring_set(NMDevice * self, + NMPlatform * platform, + EthtoolState * ethtool_state, + NMSettingEthtool *s_ethtool) +{ + NMEthtoolRingState ring_old; + NMEthtoolRingState ring_new; + GHashTable * hash; + GHashTableIter iter; + const char * name; + GVariant * variant; + gboolean has_old = FALSE; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + nm_assert(ethtool_state); + nm_assert(!ethtool_state->ring); + + hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE); + if (!hash) + return; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name); + guint32 u32; + + if (!nm_ethtool_id_is_ring(ethtool_id)) + continue; + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + + if (!has_old) { + if (!nm_platform_ethtool_get_link_ring(platform, ethtool_state->ifindex, &ring_old)) { + _LOGW(LOGD_DEVICE, + "ethtool: failure setting ring options (cannot read existing setting)"); + return; + } + has_old = TRUE; + ring_new = ring_old; + } + + u32 = g_variant_get_uint32(variant); + + switch (ethtool_id) { + case NM_ETHTOOL_ID_RING_RX: + ring_new.rx_pending = u32; + break; + case NM_ETHTOOL_ID_RING_RX_JUMBO: + ring_new.rx_jumbo_pending = u32; + break; + case NM_ETHTOOL_ID_RING_RX_MINI: + ring_new.rx_mini_pending = u32; + break; + case NM_ETHTOOL_ID_RING_TX: + ring_new.tx_pending = u32; + break; + default: + nm_assert_not_reached(); + } + } + + if (!has_old) + return; + + ethtool_state->ring = nm_memdup(&ring_old, sizeof(ring_old)); + + if (!nm_platform_ethtool_set_ring(platform, ethtool_state->ifindex, &ring_new)) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting ring settings"); + return; + } + + _LOGD(LOGD_DEVICE, "ethtool: ring settings successfully set"); } static void -_ethtool_state_reset (NMDevice *self) +_ethtool_state_reset(NMDevice *self) { - NMPlatform *platform = nm_device_get_platform (self); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free EthtoolState *ethtool_state = g_steal_pointer (&priv->ethtool_state); + NMPlatform * platform = nm_device_get_platform(self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free EthtoolState *ethtool_state = g_steal_pointer(&priv->ethtool_state); - if (!ethtool_state) - return; + if (!ethtool_state) + return; - if (ethtool_state->features) - _ethtool_features_reset (self, platform, ethtool_state); - if (ethtool_state->coalesce) - _ethtool_coalesce_reset (self, platform, ethtool_state); - if (ethtool_state->ring) - _ethtool_ring_reset (self, platform, ethtool_state); + if (ethtool_state->features) + _ethtool_features_reset(self, platform, ethtool_state); + if (ethtool_state->coalesce) + _ethtool_coalesce_reset(self, platform, ethtool_state); + if (ethtool_state->ring) + _ethtool_ring_reset(self, platform, ethtool_state); } static void -_ethtool_state_set (NMDevice *self) -{ - int ifindex; - NMPlatform *platform; - NMConnection *connection; - NMSettingEthtool *s_ethtool; - gs_free EthtoolState *ethtool_state = NULL; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex <= 0) - return; - - platform = nm_device_get_platform (self); - nm_assert (platform); - - connection = nm_device_get_applied_connection (self); - if (!connection) - return; - - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); - if (!s_ethtool) - return; - - ethtool_state = g_new0 (EthtoolState, 1); - ethtool_state->ifindex = ifindex; - - _ethtool_features_set (self, - platform, - ethtool_state, - s_ethtool); - _ethtool_coalesce_set (self, - platform, - ethtool_state, - s_ethtool); - _ethtool_ring_set (self, - platform, - ethtool_state, - s_ethtool); - - if ( ethtool_state->features - || ethtool_state->coalesce - || ethtool_state->ring) - priv->ethtool_state = g_steal_pointer (ðtool_state); +_ethtool_state_set(NMDevice *self) +{ + int ifindex; + NMPlatform * platform; + NMConnection * connection; + NMSettingEthtool *s_ethtool; + gs_free EthtoolState *ethtool_state = NULL; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + return; + + platform = nm_device_get_platform(self); + nm_assert(platform); + + connection = nm_device_get_applied_connection(self); + if (!connection) + return; + + s_ethtool = NM_SETTING_ETHTOOL(nm_connection_get_setting(connection, NM_TYPE_SETTING_ETHTOOL)); + if (!s_ethtool) + return; + + ethtool_state = g_new0(EthtoolState, 1); + ethtool_state->ifindex = ifindex; + + _ethtool_features_set(self, platform, ethtool_state, s_ethtool); + _ethtool_coalesce_set(self, platform, ethtool_state, s_ethtool); + _ethtool_ring_set(self, platform, ethtool_state, s_ethtool); + + if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring) + priv->ethtool_state = g_steal_pointer(ðtool_state); } /*****************************************************************************/ static gboolean -is_loopback (NMDevice *self) +is_loopback(NMDevice *self) { - return NM_IS_DEVICE_GENERIC (self) - && NM_DEVICE_GET_PRIVATE (self)->ifindex == 1; + return NM_IS_DEVICE_GENERIC(self) && NM_DEVICE_GET_PRIVATE(self)->ifindex == 1; } gboolean -nm_device_is_vpn (NMDevice *self) +nm_device_is_vpn(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - /* NetworkManager currently treats VPN connections (loaded from NetworkManager VPN plugins) - * differently. Those are considered VPNs. - * However, some native device types may also be considered VPNs... - * - * We should avoid distinguishing between is-vpn and "regular" devices. Is an (unencrypted) - * IP tunnel a VPN? Is MACSec on top of an IP tunnel a VPN? - * Sometimes we differentiate, but avoid unless reasonable. */ + /* NetworkManager currently treats VPN connections (loaded from NetworkManager VPN plugins) + * differently. Those are considered VPNs. + * However, some native device types may also be considered VPNs... + * + * We should avoid distinguishing between is-vpn and "regular" devices. Is an (unencrypted) + * IP tunnel a VPN? Is MACSec on top of an IP tunnel a VPN? + * Sometimes we differentiate, but avoid unless reasonable. */ - return NM_IS_DEVICE_WIREGUARD (self); + return NM_IS_DEVICE_WIREGUARD(self); } NMSettings * -nm_device_get_settings (NMDevice *self) +nm_device_get_settings(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->settings; + return NM_DEVICE_GET_PRIVATE(self)->settings; } NMManager * -nm_device_get_manager (NMDevice *self) +nm_device_get_manager(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->manager; + return NM_DEVICE_GET_PRIVATE(self)->manager; } NMNetns * -nm_device_get_netns (NMDevice *self) +nm_device_get_netns(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->netns; + return NM_DEVICE_GET_PRIVATE(self)->netns; } NMDedupMultiIndex * -nm_device_get_multi_index (NMDevice *self) +nm_device_get_multi_index(NMDevice *self) { - return nm_netns_get_multi_idx (nm_device_get_netns (self)); + return nm_netns_get_multi_idx(nm_device_get_netns(self)); } NMPlatform * -nm_device_get_platform (NMDevice *self) +nm_device_get_platform(NMDevice *self) { - return nm_netns_get_platform (nm_device_get_netns (self)); + return nm_netns_get_platform(nm_device_get_netns(self)); } static NMConnectivity * -concheck_get_mgr (NMDevice *self) +concheck_get_mgr(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (G_UNLIKELY (!priv->concheck_mgr)) - priv->concheck_mgr = g_object_ref (nm_connectivity_get ()); - return priv->concheck_mgr; + if (G_UNLIKELY(!priv->concheck_mgr)) + priv->concheck_mgr = g_object_ref(nm_connectivity_get()); + return priv->concheck_mgr; } NMIP4Config * -nm_device_ip4_config_new (NMDevice *self) +nm_device_ip4_config_new(NMDevice *self) { - return nm_ip4_config_new (nm_device_get_multi_index (self), - nm_device_get_ip_ifindex (self)); + return nm_ip4_config_new(nm_device_get_multi_index(self), nm_device_get_ip_ifindex(self)); } NMIP6Config * -nm_device_ip6_config_new (NMDevice *self) +nm_device_ip6_config_new(NMDevice *self) { - return nm_ip6_config_new (nm_device_get_multi_index (self), - nm_device_get_ip_ifindex (self)); + return nm_ip6_config_new(nm_device_get_multi_index(self), nm_device_get_ip_ifindex(self)); } NMIPConfig * -nm_device_ip_config_new (NMDevice *self, int addr_family) +nm_device_ip_config_new(NMDevice *self, int addr_family) +{ + nm_assert_addr_family(addr_family); + + return addr_family == AF_INET ? (gpointer) nm_device_ip4_config_new(self) + : (gpointer) nm_device_ip6_config_new(self); +} + +NML3ConfigData * +nm_device_create_l3_config_data(NMDevice *self) { - nm_assert_addr_family (addr_family); + int ifindex; + + nm_assert(NM_IS_DEVICE(self)); + + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + g_return_val_if_reached(NULL); - return addr_family == AF_INET - ? (gpointer) nm_device_ip4_config_new (self) - : (gpointer) nm_device_ip6_config_new (self); + return nm_l3_config_data_new(nm_device_get_multi_index(self), ifindex); } static void -applied_config_clear (AppliedConfig *config) +applied_config_clear(AppliedConfig *config) { - g_clear_object (&config->current); - g_clear_object (&config->orig); + g_clear_object(&config->current); + g_clear_object(&config->orig); } static void -applied_config_init (AppliedConfig *config, gpointer ip_config) +applied_config_init(AppliedConfig *config, gpointer ip_config) { - nm_assert ( !ip_config - || (!config->orig && !config->current) - || nm_ip_config_get_addr_family (ip_config) == nm_ip_config_get_addr_family (config->orig ?: config->current)); - nm_assert ( !ip_config - || NM_IS_IP_CONFIG (ip_config, AF_UNSPEC)); + nm_assert(!ip_config || (!config->orig && !config->current) + || nm_ip_config_get_addr_family(ip_config) + == nm_ip_config_get_addr_family(config->orig ?: config->current)); + nm_assert(!ip_config || NM_IS_IP_CONFIG(ip_config)); - nm_g_object_ref (ip_config); - applied_config_clear (config); - config->orig = ip_config; + nm_g_object_ref(ip_config); + applied_config_clear(config); + config->orig = ip_config; } static void -applied_config_init_new (AppliedConfig *config, NMDevice *self, int addr_family) +applied_config_init_new(AppliedConfig *config, NMDevice *self, int addr_family) { - gs_unref_object NMIPConfig *c = nm_device_ip_config_new (self, addr_family); + gs_unref_object NMIPConfig *c = nm_device_ip_config_new(self, addr_family); - applied_config_init (config, c); + applied_config_init(config, c); } static NMIPConfig * -applied_config_get_current (AppliedConfig *config) +applied_config_get_current(AppliedConfig *config) { - return config->current ?: config->orig; + return config->current ?: config->orig; } static void -applied_config_add_address (AppliedConfig *config, const NMPlatformIPAddress *address) +applied_config_add_address(AppliedConfig *config, const NMPlatformIPAddress *address) { - if (config->orig) - nm_ip_config_add_address (config->orig, address); - else - nm_assert (!config->current); + if (config->orig) + nm_ip_config_add_address(config->orig, address); + else + nm_assert(!config->current); - if (config->current) - nm_ip_config_add_address (config->current, address); + if (config->current) + nm_ip_config_add_address(config->current, address); } static void -applied_config_add_nameserver (AppliedConfig *config, const NMIPAddr *ns) +applied_config_add_nameserver(AppliedConfig *config, const NMIPAddr *ns) { - if (config->orig) - nm_ip_config_add_nameserver (config->orig, ns); - else - nm_assert (!config->current); + if (config->orig) + nm_ip_config_add_nameserver(config->orig, ns); + else + nm_assert(!config->current); - if (config->current) - nm_ip_config_add_nameserver (config->current, ns); + if (config->current) + nm_ip_config_add_nameserver(config->current, ns); } static void -applied_config_add_search (AppliedConfig *config, const char *new) +applied_config_add_search(AppliedConfig *config, const char *new) { - if (config->orig) - nm_ip_config_add_search (config->orig, new); - else - nm_assert (!config->current); + if (config->orig) + nm_ip_config_add_search(config->orig, new); + else + nm_assert(!config->current); - if (config->current) - nm_ip_config_add_search (config->current, new); + if (config->current) + nm_ip_config_add_search(config->current, new); } static void -applied_config_reset_searches (AppliedConfig *config) +applied_config_reset_searches(AppliedConfig *config) { - if (config->orig) - nm_ip_config_reset_searches (config->orig); - else - nm_assert (!config->current); + if (config->orig) + nm_ip_config_reset_searches(config->orig); + else + nm_assert(!config->current); - if (config->current) - nm_ip_config_reset_searches (config->current); + if (config->current) + nm_ip_config_reset_searches(config->current); } static void -applied_config_reset_nameservers (AppliedConfig *config) +applied_config_reset_nameservers(AppliedConfig *config) { - if (config->orig) - nm_ip_config_reset_nameservers (config->orig); - else - nm_assert (!config->current); + if (config->orig) + nm_ip_config_reset_nameservers(config->orig); + else + nm_assert(!config->current); - if (config->current) - nm_ip_config_reset_nameservers (config->current); + if (config->current) + nm_ip_config_reset_nameservers(config->current); } /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (_sys_iface_state_to_str, NMDeviceSysIfaceState, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"), -); +static NM_UTILS_LOOKUP_STR_DEFINE( + _sys_iface_state_to_str, + NMDeviceSysIfaceState, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"), ); NMDeviceSysIfaceState -nm_device_sys_iface_state_get (NMDevice *self) +nm_device_sys_iface_state_get(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); - return NM_DEVICE_GET_PRIVATE (self)->sys_iface_state; + return NM_DEVICE_GET_PRIVATE(self)->sys_iface_state; } gboolean -nm_device_sys_iface_state_is_external (NMDevice *self) +nm_device_sys_iface_state_is_external(NMDevice *self) { - return NM_IN_SET (nm_device_sys_iface_state_get (self), - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); + return NM_IN_SET(nm_device_sys_iface_state_get(self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); } gboolean -nm_device_sys_iface_state_is_external_or_assume (NMDevice *self) +nm_device_sys_iface_state_is_external_or_assume(NMDevice *self) { - return NM_IN_SET (nm_device_sys_iface_state_get (self), - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME); + return NM_IN_SET(nm_device_sys_iface_state_get(self), + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME); } void -nm_device_sys_iface_state_set (NMDevice *self, - NMDeviceSysIfaceState sys_iface_state) +nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_state) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IN_SET (sys_iface_state, - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME, - NM_DEVICE_SYS_IFACE_STATE_MANAGED, - NM_DEVICE_SYS_IFACE_STATE_REMOVED)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IN_SET(sys_iface_state, + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME, + NM_DEVICE_SYS_IFACE_STATE_MANAGED, + NM_DEVICE_SYS_IFACE_STATE_REMOVED)); - priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->sys_iface_state != sys_iface_state) { - _LOGT (LOGD_DEVICE, "sys-iface-state: %s -> %s", - _sys_iface_state_to_str (priv->sys_iface_state), - _sys_iface_state_to_str (sys_iface_state)); - priv->sys_iface_state = sys_iface_state; - } + priv = NM_DEVICE_GET_PRIVATE(self); + if (priv->sys_iface_state != sys_iface_state) { + _LOGT(LOGD_DEVICE, + "sys-iface-state: %s -> %s", + _sys_iface_state_to_str(priv->sys_iface_state), + _sys_iface_state_to_str(sys_iface_state)); + priv->sys_iface_state_ = sys_iface_state; + } - /* this function only sets a flag, no immediate actions are initiated. - * - * If you change this, make sure that all callers are fine with such actions. */ + /* this function only sets a flag, no immediate actions are initiated. + * + * If you change this, make sure that all callers are fine with such actions. */ - nm_assert (priv->sys_iface_state == sys_iface_state); + nm_assert(priv->sys_iface_state == sys_iface_state); } static void -_active_connection_set_state_flags_full (NMDevice *self, - NMActivationStateFlags flags, - NMActivationStateFlags mask) +_active_connection_set_state_flags_full(NMDevice * self, + NMActivationStateFlags flags, + NMActivationStateFlags mask) { - NMActiveConnection *ac; + NMActiveConnection *ac; - ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (self)); - if (ac) - nm_active_connection_set_state_flags_full (ac, flags, mask); + ac = NM_ACTIVE_CONNECTION(nm_device_get_act_request(self)); + if (ac) + nm_active_connection_set_state_flags_full(ac, flags, mask); } static void -_active_connection_set_state_flags (NMDevice *self, - NMActivationStateFlags flags) +_active_connection_set_state_flags(NMDevice *self, NMActivationStateFlags flags) { - _active_connection_set_state_flags_full (self, flags, flags); + _active_connection_set_state_flags_full(self, flags, flags); } /*****************************************************************************/ void -nm_device_assume_state_get (NMDevice *self, - gboolean *out_assume_state_guess_assume, - const char **out_assume_state_connection_uuid) +nm_device_assume_state_get(NMDevice * self, + gboolean * out_assume_state_guess_assume, + const char **out_assume_state_connection_uuid) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); - NM_SET_OUT (out_assume_state_guess_assume, priv->assume_state_guess_assume); - NM_SET_OUT (out_assume_state_connection_uuid, priv->assume_state_connection_uuid); + priv = NM_DEVICE_GET_PRIVATE(self); + NM_SET_OUT(out_assume_state_guess_assume, priv->assume_state_guess_assume); + NM_SET_OUT(out_assume_state_connection_uuid, priv->assume_state_connection_uuid); } static void -_assume_state_set (NMDevice *self, - gboolean assume_state_guess_assume, - const char *assume_state_connection_uuid) +_assume_state_set(NMDevice * self, + gboolean assume_state_guess_assume, + const char *assume_state_connection_uuid) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - nm_assert (NM_IS_DEVICE (self)); + nm_assert(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); - if ( priv->assume_state_guess_assume == !!assume_state_guess_assume - && nm_streq0 (priv->assume_state_connection_uuid, assume_state_connection_uuid)) - return; + priv = NM_DEVICE_GET_PRIVATE(self); + if (priv->assume_state_guess_assume == !!assume_state_guess_assume + && nm_streq0(priv->assume_state_connection_uuid, assume_state_connection_uuid)) + return; - _LOGD (LOGD_DEVICE, "assume-state: set guess-assume=%c, connection=%s%s%s", - assume_state_guess_assume ? '1' : '0', - NM_PRINT_FMT_QUOTE_STRING (assume_state_connection_uuid)); - priv->assume_state_guess_assume = assume_state_guess_assume; - g_free (priv->assume_state_connection_uuid); - priv->assume_state_connection_uuid = g_strdup (assume_state_connection_uuid); + _LOGD(LOGD_DEVICE, + "assume-state: set guess-assume=%c, connection=%s%s%s", + assume_state_guess_assume ? '1' : '0', + NM_PRINT_FMT_QUOTE_STRING(assume_state_connection_uuid)); + priv->assume_state_guess_assume = assume_state_guess_assume; + g_free(priv->assume_state_connection_uuid); + priv->assume_state_connection_uuid = g_strdup(assume_state_connection_uuid); } void -nm_device_assume_state_reset (NMDevice *self) +nm_device_assume_state_reset(NMDevice *self) { - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - _assume_state_set (self, FALSE, NULL); + _assume_state_set(self, FALSE, NULL); } /*****************************************************************************/ static void -init_ip_config_dns_priority (NMDevice *self, NMIPConfig *config) +init_ip_config_dns_priority(NMDevice *self, NMIPConfig *config) { - const char *property; - int priority; + const char *property; + int priority; - property = (nm_ip_config_get_addr_family (config) == AF_INET) - ? NM_CON_DEFAULT ("ipv4.dns-priority") - : NM_CON_DEFAULT ("ipv6.dns-priority"); + property = (nm_ip_config_get_addr_family(config) == AF_INET) + ? NM_CON_DEFAULT("ipv4.dns-priority") + : NM_CON_DEFAULT("ipv6.dns-priority"); - priority = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property, - self, - G_MININT, - G_MAXINT, - 0); + priority = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + property, + self, + G_MININT, + G_MAXINT, + 0); - if (priority == 0) { - priority = nm_device_is_vpn (self) - ? NM_DNS_PRIORITY_DEFAULT_VPN - : NM_DNS_PRIORITY_DEFAULT_NORMAL; - } + if (priority == 0) { + priority = + nm_device_is_vpn(self) ? NM_DNS_PRIORITY_DEFAULT_VPN : NM_DNS_PRIORITY_DEFAULT_NORMAL; + } - nm_ip_config_set_dns_priority (config, priority); + nm_ip_config_set_dns_priority(config, priority); } /*****************************************************************************/ static char * -nm_device_sysctl_ip_conf_get (NMDevice *self, - int addr_family, - const char *property) +nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property) { - const char *ifname; + const char *ifname; - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - ifname = nm_device_get_ip_iface_from_platform (self); - if (!ifname) - return NULL; - return nm_platform_sysctl_ip_conf_get (nm_device_get_platform (self), addr_family, ifname, property); + ifname = nm_device_get_ip_iface_from_platform(self); + if (!ifname) + return NULL; + return nm_platform_sysctl_ip_conf_get(nm_device_get_platform(self), + addr_family, + ifname, + property); } static gint64 -nm_device_sysctl_ip_conf_get_int_checked (NMDevice *self, - int addr_family, - const char *property, - guint base, - gint64 min, - gint64 max, - gint64 fallback) -{ - const char *ifname; - - nm_assert_addr_family (addr_family); - - ifname = nm_device_get_ip_iface_from_platform (self); - if (!ifname) { - errno = EINVAL; - return fallback; - } - return nm_platform_sysctl_ip_conf_get_int_checked (nm_device_get_platform (self), - addr_family, - ifname, - property, - base, - min, - max, - fallback); +nm_device_sysctl_ip_conf_get_int_checked(NMDevice * self, + int addr_family, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + const char *ifname; + + nm_assert_addr_family(addr_family); + + ifname = nm_device_get_ip_iface_from_platform(self); + if (!ifname) { + errno = EINVAL; + return fallback; + } + return nm_platform_sysctl_ip_conf_get_int_checked(nm_device_get_platform(self), + addr_family, + ifname, + property, + base, + min, + max, + fallback); } static void -set_ipv6_token (NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) -{ - NMPlatform *platform; - int ifindex; - const NMPlatformLink *link; - char buf[32]; - gint64 val; - - /* Setting the kernel token is not strictly necessary as the - * IPv6 address is generated in userspace. However it is - * convenient so that users can see the token with iproute - * ('ip token'). */ - platform = nm_device_get_platform (self); - ifindex = nm_device_get_ip_ifindex (self); - link = nm_platform_link_get (platform, ifindex); - - if (link && link->inet6_token.id == iid.id) { - _LOGT (LOGD_DEVICE | LOGD_IP6, "token %s already set", token_str); - return; - } - - /* The kernel allows setting a token only when 'accept_ra' - * is 1: temporarily flip it if necessary; unfortunately - * this will also generate an additional Router Solicitation - * from kernel. */ - val = nm_device_sysctl_ip_conf_get_int_checked (self, - AF_INET6, - "accept_ra", - 10, - G_MININT32, - G_MAXINT32, - 1); - if (val != 1) - nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "1"); - - nm_platform_link_set_ipv6_token (platform, ifindex, iid); - - if (val != 1) { - nm_sprintf_buf (buf, "%d", (int) val); - nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", buf); - } +set_ipv6_token(NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) +{ + NMPlatform * platform; + int ifindex; + const NMPlatformLink *link; + char buf[32]; + gint64 val; + + /* Setting the kernel token is not strictly necessary as the + * IPv6 address is generated in userspace. However it is + * convenient so that users can see the token with iproute + * ('ip token'). */ + platform = nm_device_get_platform(self); + ifindex = nm_device_get_ip_ifindex(self); + link = nm_platform_link_get(platform, ifindex); + + if (link && link->inet6_token.id == iid.id) { + _LOGT(LOGD_DEVICE | LOGD_IP6, "token %s already set", token_str); + return; + } + + /* The kernel allows setting a token only when 'accept_ra' + * is 1: temporarily flip it if necessary; unfortunately + * this will also generate an additional Router Solicitation + * from kernel. */ + val = nm_device_sysctl_ip_conf_get_int_checked(self, + AF_INET6, + "accept_ra", + 10, + G_MININT32, + G_MAXINT32, + 1); + if (val != 1) + nm_device_sysctl_ip_conf_set(self, AF_INET6, "accept_ra", "1"); + + nm_platform_link_set_ipv6_token(platform, ifindex, iid); + + if (val != 1) { + nm_sprintf_buf(buf, "%d", (int) val); + nm_device_sysctl_ip_conf_set(self, AF_INET6, "accept_ra", buf); + } } gboolean -nm_device_sysctl_ip_conf_set (NMDevice *self, - int addr_family, - const char *property, - const char *value) -{ - NMPlatform *platform = nm_device_get_platform (self); - gs_free char *value_to_free = NULL; - const char *ifname; - - nm_assert_addr_family (addr_family); - - ifname = nm_device_get_ip_iface_from_platform (self); - if (!ifname) - return FALSE; - - if (!value) { - /* Set to a default value when we've got a NULL @value. */ - value_to_free = nm_platform_sysctl_ip_conf_get (platform, - addr_family, - "default", - property); - value = value_to_free; - if (!value) - return FALSE; - } - - return nm_platform_sysctl_ip_conf_set (platform, - addr_family, - ifname, - property, - value); +nm_device_sysctl_ip_conf_set(NMDevice * self, + int addr_family, + const char *property, + const char *value) +{ + NMPlatform * platform = nm_device_get_platform(self); + gs_free char *value_to_free = NULL; + const char * ifname; + + nm_assert_addr_family(addr_family); + + ifname = nm_device_get_ip_iface_from_platform(self); + if (!ifname) + return FALSE; + + if (!value) { + /* Set to a default value when we've got a NULL @value. */ + value_to_free = nm_platform_sysctl_ip_conf_get(platform, addr_family, "default", property); + value = value_to_free; + if (!value) + return FALSE; + } + + return nm_platform_sysctl_ip_conf_set(platform, addr_family, ifname, property, value); } /*****************************************************************************/ gboolean -nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps) +nm_device_has_capability(NMDevice *self, NMDeviceCapabilities caps) { - return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->capabilities, caps); + return NM_FLAGS_ANY(NM_DEVICE_GET_PRIVATE(self)->capabilities, caps); } static void -_add_capabilities (NMDevice *self, NMDeviceCapabilities capabilities) +_add_capabilities(NMDevice *self, NMDeviceCapabilities capabilities) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (!NM_FLAGS_ALL (priv->capabilities, capabilities)) { - priv->capabilities |= capabilities; - _notify (self, PROP_CAPABILITIES); - } -} - -/*****************************************************************************/ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); -static const char * -_get_stable_id (NMDevice *self, - NMConnection *connection, - NMUtilsStableType *out_stable_type) -{ - NMDevicePrivate *priv; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_CONNECTION (connection)); - nm_assert (out_stable_type); - - priv = NM_DEVICE_GET_PRIVATE (self); - - /* we cache the generated stable ID for the time of an activation. - * - * The reason is, that we don't want the stable-id to change as long - * as the device is active. - * - * Especially with ${RANDOM} stable-id we want to generate *one* configuration - * for each activation. */ - if (G_UNLIKELY (!priv->current_stable_id)) { - gs_free char *default_id = NULL; - gs_free char *generated = NULL; - NMUtilsStableType stable_type; - NMSettingConnection *s_con; - gboolean hwaddr_is_fake; - const char *hwaddr; - const char *stable_id; - const char *uuid; - - s_con = nm_connection_get_setting_connection (connection); - - stable_id = nm_setting_connection_get_stable_id (s_con); - - if (!stable_id) { - default_id = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.stable-id"), - self); - stable_id = default_id; - } - - uuid = nm_connection_get_uuid (connection); - - /* the cloned-mac-address may be generated based on the stable-id. - * Thus, at this point, we can only use the permanent MAC address - * as seed. */ - hwaddr = nm_device_get_permanent_hw_address_full (self, TRUE, &hwaddr_is_fake); - - stable_type = nm_utils_stable_id_parse (stable_id, - nm_device_get_ip_iface (self), - !hwaddr_is_fake ? hwaddr : NULL, - nm_utils_boot_id_str (), - uuid, - &generated); - - /* current_stable_id_type is a bitfield! */ - priv->current_stable_id_type = stable_type; - nm_assert (stable_type <= (NMUtilsStableType) 0x3); - nm_assert (stable_type + (NMUtilsStableType) 1 > (NMUtilsStableType) 0); - nm_assert (priv->current_stable_id_type == stable_type); - - if (stable_type == NM_UTILS_STABLE_TYPE_UUID) - priv->current_stable_id = g_strdup (uuid); - else if (stable_type == NM_UTILS_STABLE_TYPE_STABLE_ID) - priv->current_stable_id = g_strdup (stable_id); - else if (stable_type == NM_UTILS_STABLE_TYPE_GENERATED) - priv->current_stable_id = nm_str_realloc (nm_utils_stable_id_generated_complete (generated)); - else { - nm_assert (stable_type == NM_UTILS_STABLE_TYPE_RANDOM); - priv->current_stable_id = nm_str_realloc (nm_utils_stable_id_random ()); - } - _LOGT (LOGD_DEVICE, - "stable-id: type=%d, \"%s\"" - "%s%s%s", - (int) priv->current_stable_id_type, - priv->current_stable_id, - NM_PRINT_FMT_QUOTED (stable_type == NM_UTILS_STABLE_TYPE_GENERATED, " from \"", generated, "\"", "")); - } - - nm_assert (priv->current_stable_id); - *out_stable_type = priv->current_stable_id_type; - return priv->current_stable_id; + if (!NM_FLAGS_ALL(priv->capabilities, capabilities)) { + priv->capabilities |= capabilities; + _notify(self, PROP_CAPABILITIES); + } } /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (_ip_state_to_string, NMDeviceIPState, - NM_UTILS_LOOKUP_DEFAULT_WARN ("unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_IP_STATE_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_IP_STATE_WAIT, "wait"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_IP_STATE_CONF, "conf"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_IP_STATE_DONE, "done"), - NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_IP_STATE_FAIL, "fail"), -); +static NM_UTILS_LOOKUP_STR_DEFINE(_ip_state_to_string, + NMDeviceIPState, + NM_UTILS_LOOKUP_DEFAULT_WARN("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_WAIT, "wait"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_CONF, "conf"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_DONE, "done"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_FAIL, "fail"), ); static void -_set_ip_state (NMDevice *self, int addr_family, NMDeviceIPState new_state) +_set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - if (priv->ip_state_x[IS_IPv4] == new_state) - return; + if (priv->ip_state_x[IS_IPv4] == new_state) + return; - _LOGT (LOGD_DEVICE, "ip%c-state: set to %d (%s)", - nm_utils_addr_family_to_char (addr_family), - (int) new_state, - _ip_state_to_string (new_state)); + _LOGT(LOGD_DEVICE, + "ip%c-state: set to %d (%s)", + nm_utils_addr_family_to_char(addr_family), + (int) new_state, + _ip_state_to_string(new_state)); - priv->ip_state_x_[IS_IPv4] = new_state; + priv->ip_state_x_[IS_IPv4] = new_state; - if (new_state == NM_DEVICE_IP_STATE_DONE) { - /* we only set the IPx_READY flag once we reach NM_DEVICE_IP_STATE_DONE state. We don't - * ever clear it, even if we later enter NM_DEVICE_IP_STATE_FAIL state. - * - * This is not documented/guaranteed behavior, but seems to make sense for now. */ - _active_connection_set_state_flags (self, - addr_family == AF_INET - ? NM_ACTIVATION_STATE_FLAG_IP4_READY - : NM_ACTIVATION_STATE_FLAG_IP6_READY); - } + if (new_state == NM_DEVICE_IP_STATE_DONE) { + /* we only set the IPx_READY flag once we reach NM_DEVICE_IP_STATE_DONE state. We don't + * ever clear it, even if we later enter NM_DEVICE_IP_STATE_FAIL state. + * + * This is not documented/guaranteed behavior, but seems to make sense for now. */ + _active_connection_set_state_flags(self, + addr_family == AF_INET + ? NM_ACTIVATION_STATE_FLAG_IP4_READY + : NM_ACTIVATION_STATE_FLAG_IP6_READY); + } } /*****************************************************************************/ const char * -nm_device_get_udi (NMDevice *self) +nm_device_get_udi(NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - return NM_DEVICE_GET_PRIVATE (self)->udi; + return NM_DEVICE_GET_PRIVATE(self)->udi; } const char * -nm_device_get_iface (NMDevice *self) +nm_device_get_iface(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->iface; + return NM_DEVICE_GET_PRIVATE(self)->iface; +} + +static gboolean +_set_ifindex(NMDevice *self, int ifindex, gboolean is_ip_ifindex) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int * p_ifindex; + + if (ifindex < 0) + ifindex = 0; + + p_ifindex = is_ip_ifindex ? &priv->ip_ifindex_ : &priv->ifindex_; + + if (*p_ifindex == ifindex) + return FALSE; + + *p_ifindex = ifindex; + + _LOGD(LOGD_DEVICE, "ifindex: set %sifindex %d", is_ip_ifindex ? "ip-" : "", ifindex); + + if (!is_ip_ifindex) + _notify(self, PROP_IFINDEX); + + return TRUE; } /** @@ -1763,69 +2836,64 @@ nm_device_get_iface (NMDevice *self) * Returns: %TRUE if the device took control of the link, %FALSE otherwise */ gboolean -nm_device_take_over_link (NMDevice *self, int ifindex, char **old_name, GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformLink *plink; - NMPlatform *platform; - - nm_assert (ifindex > 0); - NM_SET_OUT (old_name, NULL); - - if ( priv->ifindex > 0 - && priv->ifindex != ifindex) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "the device already has ifindex %d", - priv->ifindex); - return FALSE; - } - - platform = nm_device_get_platform (self); - plink = nm_platform_link_get (platform, ifindex); - if (!plink) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "link %d not found", ifindex); - return FALSE; - } - - if (!nm_streq (plink->name, nm_device_get_iface (self))) { - gboolean up; - gboolean success; - gs_free char *name = NULL; - - up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP); - name = g_strdup (plink->name); - - /* Rename the link to the device ifname */ - if (up) - nm_platform_link_set_down (platform, ifindex); - success = nm_platform_link_set_name (platform, ifindex, nm_device_get_iface (self)); - if (up) - nm_platform_link_set_up (platform, ifindex, NULL); - - if (!success) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, - "failure renaming link %d", ifindex); - return FALSE; - } - - NM_SET_OUT (old_name, g_steal_pointer (&name)); - } - - if (priv->ifindex != ifindex) { - priv->ifindex = ifindex; - _notify (self, PROP_IFINDEX); - } - - return TRUE; +nm_device_take_over_link(NMDevice *self, int ifindex, char **old_name, GError **error) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const NMPlatformLink *plink; + NMPlatform * platform; + + nm_assert(ifindex > 0); + NM_SET_OUT(old_name, NULL); + + if (priv->ifindex > 0 && priv->ifindex != ifindex) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "the device already has ifindex %d", + priv->ifindex); + return FALSE; + } + + platform = nm_device_get_platform(self); + plink = nm_platform_link_get(platform, ifindex); + if (!plink) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "link %d not found", ifindex); + return FALSE; + } + + if (!nm_streq(plink->name, nm_device_get_iface(self))) { + gboolean up; + gboolean success; + gs_free char *name = NULL; + + up = NM_FLAGS_HAS(plink->n_ifi_flags, IFF_UP); + name = g_strdup(plink->name); + + /* Rename the link to the device ifname */ + if (up) + nm_platform_link_set_down(platform, ifindex); + success = nm_platform_link_set_name(platform, ifindex, nm_device_get_iface(self)); + if (up) + nm_platform_link_set_up(platform, ifindex, NULL); + + if (!success) { + nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "failure renaming link %d", ifindex); + return FALSE; + } + + NM_SET_OUT(old_name, g_steal_pointer(&name)); + } + + _set_ifindex(self, ifindex, FALSE); + + return TRUE; } int -nm_device_get_ifindex (NMDevice *self) +nm_device_get_ifindex(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), 0); + g_return_val_if_fail(NM_IS_DEVICE(self), 0); - return NM_DEVICE_GET_PRIVATE (self)->ifindex; + return NM_DEVICE_GET_PRIVATE(self)->ifindex; } /** @@ -1838,9 +2906,9 @@ nm_device_get_ifindex (NMDevice *self) * Returns: %TRUE if the device is a software-based device */ gboolean -nm_device_is_software (NMDevice *self) +nm_device_is_software(NMDevice *self) { - return NM_FLAGS_HAS (NM_DEVICE_GET_PRIVATE (self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE); + return NM_FLAGS_HAS(NM_DEVICE_GET_PRIVATE(self)->capabilities, NM_DEVICE_CAP_IS_SOFTWARE); } /** @@ -1850,116 +2918,113 @@ nm_device_is_software (NMDevice *self) * Returns: %TRUE if the device exists, %FALSE if the device is a placeholder */ gboolean -nm_device_is_real (NMDevice *self) +nm_device_is_real(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return NM_DEVICE_GET_PRIVATE (self)->real; + return NM_DEVICE_GET_PRIVATE(self)->real; } const char * -nm_device_get_ip_iface (NMDevice *self) +nm_device_get_ip_iface(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - priv = NM_DEVICE_GET_PRIVATE (self); - /* If it's not set, default to iface */ - return priv->ip_iface ?: priv->iface; + priv = NM_DEVICE_GET_PRIVATE(self); + /* If it's not set, default to iface */ + return priv->ip_iface ?: priv->iface; } const char * -nm_device_get_ip_iface_from_platform (NMDevice *self) +nm_device_get_ip_iface_from_platform(NMDevice *self) { - int ifindex; + int ifindex; - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex <= 0) - return NULL; + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + return NULL; - return nm_platform_link_get_name (nm_device_get_platform (self), ifindex); + return nm_platform_link_get_name(nm_device_get_platform(self), ifindex); } int -nm_device_get_ip_ifindex (const NMDevice *self) +nm_device_get_ip_ifindex(const NMDevice *self) { - const NMDevicePrivate *priv; + const NMDevicePrivate *priv; - g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail(self != NULL, 0); - priv = NM_DEVICE_GET_PRIVATE (self); - /* If it's not set, default to ifindex */ - return priv->ip_iface ? priv->ip_ifindex : priv->ifindex; + priv = NM_DEVICE_GET_PRIVATE(self); + /* If it's not set, default to ifindex */ + return priv->ip_iface ? priv->ip_ifindex : priv->ifindex; } static void -_set_ip_ifindex (NMDevice *self, - int ifindex, - const char *ifname) +_set_ip_ifindex(NMDevice *self, int ifindex, const char *ifname) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform; - gboolean eq_name; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform * platform; + gboolean eq_name; + + /* normalize arguments */ + if (ifindex <= 0) { + ifindex = 0; + ifname = NULL; + } - /* normalize arguments */ - if (ifindex <= 0) { - ifindex = 0; - ifname = NULL; - } + eq_name = nm_streq0(priv->ip_iface, ifname); - eq_name = nm_streq0 (priv->ip_iface, ifname); + if (eq_name && priv->ip_ifindex == ifindex) + return; - if ( eq_name - && priv->ip_ifindex == ifindex) - return; + _LOGD(LOGD_DEVICE, + "ip-ifindex: update ip-interface to %s%s%s, ifindex %d", + NM_PRINT_FMT_QUOTE_STRING(ifname), + ifindex); - _LOGD (LOGD_DEVICE, "ip-ifindex: update ip-interface to %s%s%s, ifindex %d", - NM_PRINT_FMT_QUOTE_STRING (ifname), - ifindex); + _set_ifindex(self, ifindex, TRUE); - priv->ip_ifindex = ifindex; - if (!eq_name) { - g_free (priv->ip_iface); - priv->ip_iface = g_strdup (ifname); - _notify (self, PROP_IP_IFACE); - } + if (!eq_name) { + g_free(priv->ip_iface_); + priv->ip_iface_ = g_strdup(ifname); + _notify(self, PROP_IP_IFACE); + } - if (priv->ip_ifindex > 0) { - platform = nm_device_get_platform (self); + if (priv->ip_ifindex > 0) { + platform = nm_device_get_platform(self); - nm_platform_process_events_ensure_link (platform, - priv->ip_ifindex, - priv->ip_iface); + nm_platform_process_events_ensure_link(platform, priv->ip_ifindex, priv->ip_iface); - if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - nm_platform_link_set_user_ipv6ll_enabled (platform, priv->ip_ifindex, TRUE); + if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) + nm_platform_link_set_user_ipv6ll_enabled(platform, priv->ip_ifindex, TRUE); - if (!nm_platform_link_is_up (platform, priv->ip_ifindex)) - nm_platform_link_set_up (platform, priv->ip_ifindex, NULL); - } + if (!nm_platform_link_is_up(platform, priv->ip_ifindex)) + nm_platform_link_set_up(platform, priv->ip_ifindex, NULL); + } - /* We don't care about any saved values from the old iface */ - g_hash_table_remove_all (priv->ip6_saved_properties); + /* We don't care about any saved values from the old iface */ + g_hash_table_remove_all(priv->ip6_saved_properties); } gboolean -nm_device_set_ip_ifindex (NMDevice *self, int ifindex) +nm_device_set_ip_ifindex(NMDevice *self, int ifindex) { - char ifname_buf[IFNAMSIZ]; - const char *ifname = NULL; + char ifname_buf[IFNAMSIZ]; + const char *ifname = NULL; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (nm_device_is_activating (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(nm_device_is_activating(self), FALSE); - if (ifindex > 0) { - ifname = nm_platform_if_indextoname (nm_device_get_platform (self), ifindex, ifname_buf); - if (!ifname) - _LOGW (LOGD_DEVICE, "ip-ifindex: ifindex %d not found", ifindex); - } + if (ifindex > 0) { + ifname = nm_platform_if_indextoname(nm_device_get_platform(self), ifindex, ifname_buf); + if (!ifname) + _LOGW(LOGD_DEVICE, "ip-ifindex: ifindex %d not found", ifindex); + } - _set_ip_ifindex (self, ifindex, ifname); - return ifindex > 0; + _set_ip_ifindex(self, ifindex, ifname); + return ifindex > 0; } /** @@ -1973,367 +3038,345 @@ nm_device_set_ip_ifindex (NMDevice *self, int ifindex) * and %FALSE, if @ifname is %NULL or no such interface exists. */ gboolean -nm_device_set_ip_iface (NMDevice *self, const char *ifname) +nm_device_set_ip_iface(NMDevice *self, const char *ifname) { - int ifindex = 0; + int ifindex = 0; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (nm_device_is_activating (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(nm_device_is_activating(self), FALSE); - if (ifname) { - ifindex = nm_platform_if_nametoindex (nm_device_get_platform (self), ifname); - if (ifindex <= 0) - _LOGW (LOGD_DEVICE, "ip-ifindex: ifname %s not found", ifname); - } + if (ifname) { + ifindex = nm_platform_if_nametoindex(nm_device_get_platform(self), ifname); + if (ifindex <= 0) + _LOGW(LOGD_DEVICE, "ip-ifindex: ifname %s not found", ifname); + } - _set_ip_ifindex (self, ifindex, ifname); - return ifindex > 0; -} - -static gboolean -_ip_iface_update (NMDevice *self, const char *ip_iface) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - g_return_val_if_fail (priv->ip_iface, FALSE); - g_return_val_if_fail (priv->ip_ifindex > 0, FALSE); - g_return_val_if_fail (ip_iface, FALSE); - - if (!ip_iface[0]) - return FALSE; - - if (nm_streq (priv->ip_iface, ip_iface)) - return FALSE; - - _LOGI (LOGD_DEVICE, "ip-ifname: interface index %d renamed ip_iface (%d) from '%s' to '%s'", - priv->ifindex, priv->ip_ifindex, - priv->ip_iface, ip_iface); - g_free (priv->ip_iface); - priv->ip_iface = g_strdup (ip_iface); - _notify (self, PROP_IP_IFACE); - return TRUE; + _set_ip_ifindex(self, ifindex, ifname); + return ifindex > 0; } /*****************************************************************************/ int -nm_device_parent_get_ifindex (NMDevice *self) +nm_device_parent_get_ifindex(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), 0); + g_return_val_if_fail(NM_IS_DEVICE(self), 0); - priv = NM_DEVICE_GET_PRIVATE (self); - return priv->parent_ifindex; + priv = NM_DEVICE_GET_PRIVATE(self); + return priv->parent_ifindex; } NMDevice * -nm_device_parent_get_device (NMDevice *self) +nm_device_parent_get_device(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->parent_device.obj; + return NM_DEVICE_GET_PRIVATE(self)->parent_device.obj; } static void -parent_changed_notify (NMDevice *self, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) +parent_changed_notify(NMDevice *self, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent) { - /* empty handler to allow subclasses to always chain up the virtual function. */ + /* empty handler to allow subclasses to always chain up the virtual function. */ } static gboolean -_parent_set_ifindex (NMDevice *self, - int parent_ifindex, - gboolean force_check) -{ - NMDevicePrivate *priv; - NMDevice *parent_device; - gboolean changed = FALSE; - int old_ifindex; - gs_unref_object NMDevice *old_device = NULL; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (parent_ifindex <= 0) - parent_ifindex = 0; - - old_ifindex = priv->parent_ifindex; - - if (priv->parent_ifindex == parent_ifindex) { - if (parent_ifindex > 0) { - if ( !force_check - && priv->parent_device.obj - && nm_device_get_ifindex (priv->parent_device.obj) == parent_ifindex) - return FALSE; - } else { - if (!priv->parent_device.obj) - return FALSE; - } - } else { - priv->parent_ifindex = parent_ifindex; - changed = TRUE; - } - - if (parent_ifindex > 0) { - parent_device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, parent_ifindex); - if (parent_device == self) - parent_device = NULL; - } else - parent_device = NULL; - - if (parent_device != priv->parent_device.obj) { - old_device = nm_g_object_ref (priv->parent_device.obj); - nm_dbus_track_obj_path_set (&priv->parent_device, parent_device, TRUE); - changed = TRUE; - } - - if (changed) { - if (priv->parent_ifindex <= 0) - _LOGD (LOGD_DEVICE, "parent: clear"); - else if (!priv->parent_device.obj) - _LOGD (LOGD_DEVICE, "parent: ifindex %d, no device", priv->parent_ifindex); - else { - _LOGD (LOGD_DEVICE, "parent: ifindex %d, device %p, %s", priv->parent_ifindex, - priv->parent_device.obj, nm_device_get_iface (priv->parent_device.obj)); - } - - NM_DEVICE_GET_CLASS (self)->parent_changed_notify (self, old_ifindex, old_device, priv->parent_ifindex, priv->parent_device.obj); - } - return changed; +_parent_set_ifindex(NMDevice *self, int parent_ifindex, gboolean force_check) +{ + NMDevicePrivate *priv; + NMDevice * parent_device; + gboolean changed = FALSE; + int old_ifindex; + gs_unref_object NMDevice *old_device = NULL; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (parent_ifindex <= 0) + parent_ifindex = 0; + + old_ifindex = priv->parent_ifindex; + + if (priv->parent_ifindex == parent_ifindex) { + if (parent_ifindex > 0) { + if (!force_check && priv->parent_device.obj + && nm_device_get_ifindex(priv->parent_device.obj) == parent_ifindex) + return FALSE; + } else { + if (!priv->parent_device.obj) + return FALSE; + } + } else { + priv->parent_ifindex = parent_ifindex; + changed = TRUE; + } + + if (parent_ifindex > 0) { + parent_device = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, parent_ifindex); + if (parent_device == self) + parent_device = NULL; + } else + parent_device = NULL; + + if (parent_device != priv->parent_device.obj) { + old_device = nm_g_object_ref(priv->parent_device.obj); + nm_dbus_track_obj_path_set(&priv->parent_device, parent_device, TRUE); + changed = TRUE; + } + + if (changed) { + if (priv->parent_ifindex <= 0) + _LOGD(LOGD_DEVICE, "parent: clear"); + else if (!priv->parent_device.obj) + _LOGD(LOGD_DEVICE, "parent: ifindex %d, no device", priv->parent_ifindex); + else { + _LOGD(LOGD_DEVICE, + "parent: ifindex %d, device %p, %s", + priv->parent_ifindex, + priv->parent_device.obj, + nm_device_get_iface(priv->parent_device.obj)); + } + + NM_DEVICE_GET_CLASS(self)->parent_changed_notify(self, + old_ifindex, + old_device, + priv->parent_ifindex, + priv->parent_device.obj); + } + return changed; } void -nm_device_parent_set_ifindex (NMDevice *self, - int parent_ifindex) +nm_device_parent_set_ifindex(NMDevice *self, int parent_ifindex) { - _parent_set_ifindex (self, parent_ifindex, FALSE); + _parent_set_ifindex(self, parent_ifindex, FALSE); } gboolean -nm_device_parent_notify_changed (NMDevice *self, - NMDevice *change_candidate, - gboolean device_removed) +nm_device_parent_notify_changed(NMDevice *self, NMDevice *change_candidate, gboolean device_removed) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - nm_assert (NM_IS_DEVICE (self)); - nm_assert (NM_IS_DEVICE (change_candidate)); + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_DEVICE(change_candidate)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->parent_ifindex > 0) { - if ( priv->parent_device.obj == change_candidate - || priv->parent_ifindex == nm_device_get_ifindex (change_candidate)) - return _parent_set_ifindex (self, priv->parent_ifindex, device_removed); - } - return FALSE; + if (priv->parent_ifindex > 0) { + if (priv->parent_device.obj == change_candidate + || priv->parent_ifindex == nm_device_get_ifindex(change_candidate)) + return _parent_set_ifindex(self, priv->parent_ifindex, device_removed); + } + return FALSE; } /*****************************************************************************/ const char * -nm_device_parent_find_for_connection (NMDevice *self, - const char *current_setting_parent) +nm_device_parent_find_for_connection(NMDevice *self, const char *current_setting_parent) { - const char *new_parent; - NMDevice *parent_device; + const char *new_parent; + NMDevice * parent_device; - parent_device = nm_device_parent_get_device (self); - if (!parent_device) - return NULL; + parent_device = nm_device_parent_get_device(self); + if (!parent_device) + return NULL; - new_parent = nm_device_get_iface (parent_device); - if (!new_parent) - return NULL; + new_parent = nm_device_get_iface(parent_device); + if (!new_parent) + return NULL; - if ( current_setting_parent - && !nm_streq (current_setting_parent, new_parent) - && nm_utils_is_uuid (current_setting_parent)) { - NMSettingsConnection *parent_connection; + if (current_setting_parent && !nm_streq(current_setting_parent, new_parent) + && nm_utils_is_uuid(current_setting_parent)) { + NMSettingsConnection *parent_connection; - /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_settings_get_connection_by_uuid (nm_device_get_settings (self), - current_setting_parent); - if ( parent_connection - && nm_device_check_connection_compatible (parent_device, - nm_settings_connection_get_connection (parent_connection), - NULL)) - return current_setting_parent; - } + /* Don't change a parent specified by UUID if it's still valid */ + parent_connection = nm_settings_get_connection_by_uuid(nm_device_get_settings(self), + current_setting_parent); + if (parent_connection + && nm_device_check_connection_compatible( + parent_device, + nm_settings_connection_get_connection(parent_connection), + NULL)) + return current_setting_parent; + } - return new_parent; + return new_parent; } /*****************************************************************************/ static void -_stats_update_counters (NMDevice *self, - guint64 tx_bytes, - guint64 rx_bytes) +_stats_update_counters(NMDevice *self, guint64 tx_bytes, guint64 rx_bytes) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; + gboolean tx_changed = FALSE; + gboolean rx_changed = FALSE; + + priv = NM_DEVICE_GET_PRIVATE(self); - priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->stats.tx_bytes != tx_bytes) { + priv->stats.tx_bytes = tx_bytes; + tx_changed = TRUE; + } + if (priv->stats.rx_bytes != rx_bytes) { + priv->stats.rx_bytes = rx_bytes; + rx_changed = TRUE; + } - if (priv->stats.tx_bytes != tx_bytes) { - priv->stats.tx_bytes = tx_bytes; - _notify (self, PROP_STATISTICS_TX_BYTES); - } - if (priv->stats.rx_bytes != rx_bytes) { - priv->stats.rx_bytes = rx_bytes; - _notify (self, PROP_STATISTICS_RX_BYTES); - } + nm_gobject_notify_together(self, + tx_changed ? PROP_STATISTICS_TX_BYTES : PROP_0, + rx_changed ? PROP_STATISTICS_RX_BYTES : PROP_0); } static void -_stats_update_counters_from_pllink (NMDevice *self, const NMPlatformLink *pllink) +_stats_update_counters_from_pllink(NMDevice *self, const NMPlatformLink *pllink) { - _stats_update_counters (self, pllink->tx_bytes, pllink->rx_bytes); + _stats_update_counters(self, pllink->tx_bytes, pllink->rx_bytes); } static gboolean -_stats_timeout_cb (gpointer user_data) +_stats_timeout_cb(gpointer user_data) { - NMDevice *self = user_data; - int ifindex; + NMDevice *self = user_data; + int ifindex; - ifindex = nm_device_get_ip_ifindex (self); + ifindex = nm_device_get_ip_ifindex(self); - _LOGT (LOGD_DEVICE, "stats: refresh %d", ifindex); + _LOGT(LOGD_DEVICE, "stats: refresh %d", ifindex); - if (ifindex > 0) - nm_platform_link_refresh (nm_device_get_platform (self), ifindex); + if (ifindex > 0) + nm_platform_link_refresh(nm_device_get_platform(self), ifindex); - return G_SOURCE_CONTINUE; + return G_SOURCE_CONTINUE; } static guint -_stats_refresh_rate_real (guint refresh_rate_ms) +_stats_refresh_rate_real(guint refresh_rate_ms) { - const guint STATS_REFRESH_RATE_MS_MIN = 200; + const guint STATS_REFRESH_RATE_MS_MIN = 200; - if (refresh_rate_ms == 0) - return 0; + if (refresh_rate_ms == 0) + return 0; - if (refresh_rate_ms < STATS_REFRESH_RATE_MS_MIN) { - /* you cannot set the refresh-rate arbitrarly small. E.g. - * setting to 1ms is just killing. Have a lowest number. */ - return STATS_REFRESH_RATE_MS_MIN; - } + if (refresh_rate_ms < STATS_REFRESH_RATE_MS_MIN) { + /* you cannot set the refresh-rate arbitrarily small. E.g. + * setting to 1ms is just killing. Have a lowest number. */ + return STATS_REFRESH_RATE_MS_MIN; + } - return refresh_rate_ms; + return refresh_rate_ms; } static void -_stats_set_refresh_rate (NMDevice *self, guint refresh_rate_ms) +_stats_set_refresh_rate(NMDevice *self, guint refresh_rate_ms) { - NMDevicePrivate *priv; - int ifindex; - guint old_rate; + NMDevicePrivate *priv; + int ifindex; + guint old_rate; - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->stats.refresh_rate_ms == refresh_rate_ms) - return; + if (priv->stats.refresh_rate_ms == refresh_rate_ms) + return; - old_rate = priv->stats.refresh_rate_ms; - priv->stats.refresh_rate_ms = refresh_rate_ms; - _notify (self, PROP_STATISTICS_REFRESH_RATE_MS); + old_rate = priv->stats.refresh_rate_ms; + priv->stats.refresh_rate_ms = refresh_rate_ms; + _notify(self, PROP_STATISTICS_REFRESH_RATE_MS); - _LOGD (LOGD_DEVICE, "stats: set refresh to %u ms", priv->stats.refresh_rate_ms); + _LOGD(LOGD_DEVICE, "stats: set refresh to %u ms", priv->stats.refresh_rate_ms); - if (!nm_device_is_real (self)) - return; + if (!nm_device_is_real(self)) + return; - refresh_rate_ms = _stats_refresh_rate_real (refresh_rate_ms); - if (_stats_refresh_rate_real (old_rate) == refresh_rate_ms) - return; + refresh_rate_ms = _stats_refresh_rate_real(refresh_rate_ms); + if (_stats_refresh_rate_real(old_rate) == refresh_rate_ms) + return; - nm_clear_g_source (&priv->stats.timeout_id); + nm_clear_g_source(&priv->stats.timeout_id); - if (!refresh_rate_ms) - return; + if (!refresh_rate_ms) + return; - /* trigger an initial refresh of the data whenever the refresh-rate changes. - * As we process the result in an idle handler with device_link_changed(), - * we don't get the result right away. */ - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex > 0) - nm_platform_link_refresh (nm_device_get_platform (self), ifindex); + /* trigger an initial refresh of the data whenever the refresh-rate changes. + * As we process the result in an idle handler with device_link_changed(), + * we don't get the result right away. */ + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex > 0) + nm_platform_link_refresh(nm_device_get_platform(self), ifindex); - priv->stats.timeout_id = g_timeout_add (refresh_rate_ms, _stats_timeout_cb, self); + priv->stats.timeout_id = g_timeout_add(refresh_rate_ms, _stats_timeout_cb, self); } /*****************************************************************************/ static gboolean -get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform = nm_device_get_platform (self); - const NMPlatformLink *pllink; - const guint8 *hwaddr; - guint8 pseudo_hwaddr[ETH_ALEN]; - gsize hwaddr_len; - int ifindex; - gboolean success; - - /* If we get here, we *must* have a kernel netdev, which implies an ifindex */ - ifindex = nm_device_get_ip_ifindex (self); - g_return_val_if_fail (ifindex > 0, FALSE); - - pllink = nm_platform_link_get (platform, ifindex); - if ( !pllink - || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN)) - return FALSE; - - hwaddr = nmp_link_address_get (&pllink->l_address, &hwaddr_len); - if (hwaddr_len <= 0) - return FALSE; - - if (pllink->type == NM_LINK_TYPE_6LOWPAN) { - /* If the underlying IEEE 802.15.4 device has a short address we generate - * a "pseudo 48-bit address" that's to be used in the same fashion as a - * wired Ethernet address. The mechanism is specified in Section 6. of - * RFC 4944 */ - guint16 pan_id; - guint16 short_addr; - - short_addr = nm_platform_wpan_get_short_addr (platform, pllink->parent); - if (short_addr != G_MAXUINT16) { - pan_id = nm_platform_wpan_get_pan_id (platform, pllink->parent); - pseudo_hwaddr[0] = short_addr & 0xff; - pseudo_hwaddr[1] = (short_addr >> 8) & 0xff; - pseudo_hwaddr[2] = 0; - pseudo_hwaddr[3] = 0; - pseudo_hwaddr[4] = pan_id & 0xff; - pseudo_hwaddr[5] = (pan_id >> 8) & 0xff; - - hwaddr = pseudo_hwaddr; - hwaddr_len = G_N_ELEMENTS (pseudo_hwaddr); - } - } - - success = nm_utils_get_ipv6_interface_identifier (pllink->type, - hwaddr, - hwaddr_len, - priv->dev_id, - out_iid); - if (!success) { - _LOGW (LOGD_PLATFORM, "failed to generate interface identifier " - "for link type %u hwaddr_len %zu", pllink->type, hwaddr_len); - } - return success; +get_ip_iface_identifier(NMDevice *self, NMUtilsIPv6IfaceId *out_iid) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform * platform = nm_device_get_platform(self); + const NMPlatformLink *pllink; + const guint8 * hwaddr; + guint8 pseudo_hwaddr[ETH_ALEN]; + gsize hwaddr_len; + int ifindex; + gboolean success; + + /* If we get here, we *must* have a kernel netdev, which implies an ifindex */ + ifindex = nm_device_get_ip_ifindex(self); + g_return_val_if_fail(ifindex > 0, FALSE); + + pllink = nm_platform_link_get(platform, ifindex); + if (!pllink || NM_IN_SET(pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN)) + return FALSE; + + hwaddr = nmp_link_address_get(&pllink->l_address, &hwaddr_len); + if (hwaddr_len <= 0) + return FALSE; + + if (pllink->type == NM_LINK_TYPE_6LOWPAN) { + /* If the underlying IEEE 802.15.4 device has a short address we generate + * a "pseudo 48-bit address" that's to be used in the same fashion as a + * wired Ethernet address. The mechanism is specified in Section 6. of + * RFC 4944 */ + guint16 pan_id; + guint16 short_addr; + + short_addr = nm_platform_wpan_get_short_addr(platform, pllink->parent); + if (short_addr != G_MAXUINT16) { + pan_id = nm_platform_wpan_get_pan_id(platform, pllink->parent); + pseudo_hwaddr[0] = short_addr & 0xff; + pseudo_hwaddr[1] = (short_addr >> 8) & 0xff; + pseudo_hwaddr[2] = 0; + pseudo_hwaddr[3] = 0; + pseudo_hwaddr[4] = pan_id & 0xff; + pseudo_hwaddr[5] = (pan_id >> 8) & 0xff; + + hwaddr = pseudo_hwaddr; + hwaddr_len = G_N_ELEMENTS(pseudo_hwaddr); + } + } + + success = nm_utils_get_ipv6_interface_identifier(pllink->type, + hwaddr, + hwaddr_len, + priv->dev_id, + out_iid); + if (!success) { + _LOGW(LOGD_PLATFORM, + "failed to generate interface identifier " + "for link type %u hwaddr_len %zu", + pllink->type, + hwaddr_len); + } + return success; } /** @@ -2352,56 +3395,56 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) * Returns: #TRUE if the @iid could be set */ static gboolean -nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token) +nm_device_get_ip_iface_identifier(NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token) { - NMSettingIP6Config *s_ip6; - const char *token = NULL; + NMSettingIP6Config *s_ip6; + const char * token = NULL; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - if (!ignore_token) { - s_ip6 = nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG); + if (!ignore_token) { + s_ip6 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG); - g_return_val_if_fail (s_ip6, FALSE); + g_return_val_if_fail(s_ip6, FALSE); - token = nm_setting_ip6_config_get_token (s_ip6); - } - if (token) - return nm_utils_ipv6_interface_identifier_get_from_token (iid, token); - else - return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); + token = nm_setting_ip6_config_get_token(s_ip6); + } + if (token) + return nm_utils_ipv6_interface_identifier_get_from_token(iid, token); + else + return NM_DEVICE_GET_CLASS(self)->get_ip_iface_identifier(self, iid); } const char * -nm_device_get_driver (NMDevice *self) +nm_device_get_driver(NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - return NM_DEVICE_GET_PRIVATE (self)->driver; + return NM_DEVICE_GET_PRIVATE(self)->driver; } const char * -nm_device_get_driver_version (NMDevice *self) +nm_device_get_driver_version(NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - return NM_DEVICE_GET_PRIVATE (self)->driver_version; + return NM_DEVICE_GET_PRIVATE(self)->driver_version; } NMDeviceType -nm_device_get_device_type (NMDevice *self) +nm_device_get_device_type(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_TYPE_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (self)->type; + return NM_DEVICE_GET_PRIVATE(self)->type; } NMLinkType -nm_device_get_link_type (NMDevice *self) +nm_device_get_link_type(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_LINK_TYPE_UNKNOWN); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_LINK_TYPE_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (self)->link_type; + return NM_DEVICE_GET_PRIVATE(self)->link_type; } /** @@ -2413,1261 +3456,1142 @@ nm_device_get_link_type (NMDevice *self) * Since: 1.2 **/ NMMetered -nm_device_get_metered (NMDevice *self) +nm_device_get_metered(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_METERED_UNKNOWN); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_METERED_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (self)->metered; + return NM_DEVICE_GET_PRIVATE(self)->metered; } guint32 -nm_device_get_route_metric_default (NMDeviceType device_type) -{ - /* Device 'priority' is used for the default route-metric and is based on - * the device type. The settings ipv4.route-metric and ipv6.route-metric - * can overwrite this default. - * - * For both IPv4 and IPv6 we use the same default values. - * - * The route-metric is used for the metric of the routes of device. - * This also applies to the default route. Therefore it affects also - * which device is the "best". - * - * For comparison, note that iproute2 by default adds IPv4 routes with - * metric 0, and IPv6 routes with metric 1024. The latter is the IPv6 - * "user default" in the kernel (NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6). - * In kernel, the full uint32_t range is available for route - * metrics (except for IPv6, where 0 means 1024). - */ - - switch (device_type) { - - /* 50 is also used for VPN plugins (NM_VPN_ROUTE_METRIC_DEFAULT). - * - * Note that returning 50 from this function means that this device-type is - * in some aspects a VPN. */ - case NM_DEVICE_TYPE_WIREGUARD: - return NM_VPN_ROUTE_METRIC_DEFAULT; - - case NM_DEVICE_TYPE_ETHERNET: - case NM_DEVICE_TYPE_VETH: - return 100; - case NM_DEVICE_TYPE_MACSEC: - return 125; - case NM_DEVICE_TYPE_INFINIBAND: - return 150; - case NM_DEVICE_TYPE_ADSL: - return 200; - case NM_DEVICE_TYPE_WIMAX: - return 250; - case NM_DEVICE_TYPE_BOND: - return 300; - case NM_DEVICE_TYPE_TEAM: - return 350; - case NM_DEVICE_TYPE_VLAN: - return 400; - case NM_DEVICE_TYPE_MACVLAN: - return 410; - case NM_DEVICE_TYPE_BRIDGE: - return 425; - case NM_DEVICE_TYPE_TUN: - return 450; - case NM_DEVICE_TYPE_PPP: - return 460; - case NM_DEVICE_TYPE_VRF: - return 470; - case NM_DEVICE_TYPE_VXLAN: - return 500; - case NM_DEVICE_TYPE_DUMMY: - return 550; - case NM_DEVICE_TYPE_WIFI: - return 600; - case NM_DEVICE_TYPE_OLPC_MESH: - return 650; - case NM_DEVICE_TYPE_IP_TUNNEL: - return 675; - case NM_DEVICE_TYPE_MODEM: - return 700; - case NM_DEVICE_TYPE_BT: - return 750; - case NM_DEVICE_TYPE_6LOWPAN: - return 775; - case NM_DEVICE_TYPE_OVS_BRIDGE: - case NM_DEVICE_TYPE_OVS_INTERFACE: - case NM_DEVICE_TYPE_OVS_PORT: - return 800; - case NM_DEVICE_TYPE_WPAN: - return 850; - case NM_DEVICE_TYPE_WIFI_P2P: - case NM_DEVICE_TYPE_GENERIC: - return 950; - case NM_DEVICE_TYPE_UNKNOWN: - return 10000; - case NM_DEVICE_TYPE_UNUSED1: - case NM_DEVICE_TYPE_UNUSED2: - /* omit default: to get compiler warning about missing switch cases */ - break; - } - return 11000; +nm_device_get_route_metric_default(NMDeviceType device_type) +{ + /* Device 'priority' is used for the default route-metric and is based on + * the device type. The settings ipv4.route-metric and ipv6.route-metric + * can overwrite this default. + * + * For both IPv4 and IPv6 we use the same default values. + * + * The route-metric is used for the metric of the routes of device. + * This also applies to the default route. Therefore it affects also + * which device is the "best". + * + * For comparison, note that iproute2 by default adds IPv4 routes with + * metric 0, and IPv6 routes with metric 1024. The latter is the IPv6 + * "user default" in the kernel (NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6). + * In kernel, the full uint32_t range is available for route + * metrics (except for IPv6, where 0 means 1024). + */ + + switch (device_type) { + /* 50 is also used for VPN plugins (NM_VPN_ROUTE_METRIC_DEFAULT). + * + * Note that returning 50 from this function means that this device-type is + * in some aspects a VPN. */ + case NM_DEVICE_TYPE_WIREGUARD: + return NM_VPN_ROUTE_METRIC_DEFAULT; + + case NM_DEVICE_TYPE_ETHERNET: + case NM_DEVICE_TYPE_VETH: + return 100; + case NM_DEVICE_TYPE_MACSEC: + return 125; + case NM_DEVICE_TYPE_INFINIBAND: + return 150; + case NM_DEVICE_TYPE_ADSL: + return 200; + case NM_DEVICE_TYPE_WIMAX: + return 250; + case NM_DEVICE_TYPE_BOND: + return 300; + case NM_DEVICE_TYPE_TEAM: + return 350; + case NM_DEVICE_TYPE_VLAN: + return 400; + case NM_DEVICE_TYPE_MACVLAN: + return 410; + case NM_DEVICE_TYPE_BRIDGE: + return 425; + case NM_DEVICE_TYPE_TUN: + return 450; + case NM_DEVICE_TYPE_PPP: + return 460; + case NM_DEVICE_TYPE_VRF: + return 470; + case NM_DEVICE_TYPE_VXLAN: + return 500; + case NM_DEVICE_TYPE_DUMMY: + return 550; + case NM_DEVICE_TYPE_WIFI: + return 600; + case NM_DEVICE_TYPE_OLPC_MESH: + return 650; + case NM_DEVICE_TYPE_IP_TUNNEL: + return 675; + case NM_DEVICE_TYPE_MODEM: + return 700; + case NM_DEVICE_TYPE_BT: + return 750; + case NM_DEVICE_TYPE_6LOWPAN: + return 775; + case NM_DEVICE_TYPE_OVS_BRIDGE: + case NM_DEVICE_TYPE_OVS_INTERFACE: + case NM_DEVICE_TYPE_OVS_PORT: + return 800; + case NM_DEVICE_TYPE_WPAN: + return 850; + case NM_DEVICE_TYPE_WIFI_P2P: + case NM_DEVICE_TYPE_GENERIC: + return 950; + case NM_DEVICE_TYPE_UNKNOWN: + return 10000; + case NM_DEVICE_TYPE_UNUSED1: + case NM_DEVICE_TYPE_UNUSED2: + /* omit default: to get compiler warning about missing switch cases */ + break; + } + return 11000; } static gboolean -default_route_metric_penalty_detect (NMDevice *self, int addr_family) +default_route_metric_penalty_detect(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); - /* currently we don't differentiate between IPv4 and IPv6 when detecting - * connectivity. */ - if ( priv->concheck_x[IS_IPv4].state != NM_CONNECTIVITY_FULL - && nm_connectivity_check_enabled (concheck_get_mgr (self))) - return TRUE; + /* currently we don't differentiate between IPv4 and IPv6 when detecting + * connectivity. */ + if (priv->concheck_x[IS_IPv4].state != NM_CONNECTIVITY_FULL + && nm_connectivity_check_enabled(concheck_get_mgr(self))) + return TRUE; - return FALSE; + return FALSE; } static guint32 -default_route_metric_penalty_get (NMDevice *self, int addr_family) +default_route_metric_penalty_get(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - if ( addr_family == AF_INET - ? priv->default_route_metric_penalty_ip4_has - : priv->default_route_metric_penalty_ip6_has) - return 20000; - return 0; + if (addr_family == AF_INET ? priv->default_route_metric_penalty_ip4_has + : priv->default_route_metric_penalty_ip6_has) + return 20000; + return 0; } guint32 -nm_device_get_route_metric (NMDevice *self, - int addr_family) -{ - gint64 route_metric; - NMSettingIPConfig *s_ip; - NMConnection *connection; - const char *property; - - g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), G_MAXUINT32); - - connection = nm_device_get_applied_connection (self); - if (connection) { - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - - /* Slave interfaces don't have IP settings, but we may get here when - * external changes are made or when noticing IP changes when starting - * the slave connection. - */ - if (s_ip) { - route_metric = nm_setting_ip_config_get_route_metric (s_ip); - if (route_metric >= 0) - goto out; - } - } - - /* use the current NMConfigData, which makes this configuration reloadable. - * Note that that means that the route-metric might change between SIGHUP. - * You must cache the returned value if that is a problem. */ - property = addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.route-metric") - : NM_CON_DEFAULT ("ipv6.route-metric"); - route_metric = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property, - self, - 0, G_MAXUINT32, -1); - if (route_metric >= 0) - goto out; - - route_metric = nm_manager_device_route_metric_reserve (NM_MANAGER_GET, - nm_device_get_ip_ifindex (self), - nm_device_get_device_type (self)); +nm_device_get_route_metric(NMDevice *self, int addr_family) +{ + gint64 route_metric; + NMSettingIPConfig *s_ip; + NMConnection * connection; + const char * property; + + g_return_val_if_fail(NM_IS_DEVICE(self), G_MAXUINT32); + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), G_MAXUINT32); + + connection = nm_device_get_applied_connection(self); + if (connection) { + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + + /* Slave interfaces don't have IP settings, but we may get here when + * external changes are made or when noticing IP changes when starting + * the slave connection. + */ + if (s_ip) { + route_metric = nm_setting_ip_config_get_route_metric(s_ip); + if (route_metric >= 0) + goto out; + } + } + + /* use the current NMConfigData, which makes this configuration reloadable. + * Note that that means that the route-metric might change between SIGHUP. + * You must cache the returned value if that is a problem. */ + property = addr_family == AF_INET ? NM_CON_DEFAULT("ipv4.route-metric") + : NM_CON_DEFAULT("ipv6.route-metric"); + route_metric = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + property, + self, + 0, + G_MAXUINT32, + -1); + if (route_metric >= 0) + goto out; + + route_metric = nm_manager_device_route_metric_reserve(NM_MANAGER_GET, + nm_device_get_ip_ifindex(self), + nm_device_get_device_type(self)); out: - return nm_utils_ip_route_metric_normalize (addr_family, route_metric); -} - -static NMSettingConnectionMdns -_get_mdns (NMDevice *self) -{ - NMConnection *connection; - NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; - - g_return_val_if_fail (NM_IS_DEVICE (self), NM_SETTING_CONNECTION_MDNS_DEFAULT); - - connection = nm_device_get_applied_connection (self); - if (connection) - mdns = nm_setting_connection_get_mdns (nm_connection_get_setting_connection (connection)); - if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) - return mdns; - - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.mdns"), - self, - NM_SETTING_CONNECTION_MDNS_NO, - NM_SETTING_CONNECTION_MDNS_YES, - NM_SETTING_CONNECTION_MDNS_DEFAULT); -} - -static NMSettingConnectionLlmnr -_get_llmnr (NMDevice *self) -{ - NMConnection *connection; - NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; - - g_return_val_if_fail (NM_IS_DEVICE (self), NM_SETTING_CONNECTION_LLMNR_DEFAULT); - - connection = nm_device_get_applied_connection (self); - if (connection) - llmnr = nm_setting_connection_get_llmnr (nm_connection_get_setting_connection (connection)); - if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) - return llmnr; - - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.llmnr"), - self, - NM_SETTING_CONNECTION_LLMNR_NO, - NM_SETTING_CONNECTION_LLMNR_YES, - NM_SETTING_CONNECTION_LLMNR_DEFAULT); -} - -static guint32 -_get_route_table (NMDevice *self, - int addr_family) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceClass *klass; - NMConnection *connection; - NMSettingIPConfig *s_ip; - guint32 route_table = 0; - gboolean is_user_config = TRUE; - NMSettingConnection *s_con; - NMSettingVrf *s_vrf; - - nm_assert_addr_family (addr_family); - - /* the route table setting affects how we sync routes. We shall - * not change it while the device is active, hence, cache it. */ - if (addr_family == AF_INET) { - if (priv->v4_route_table_initialized) - return priv->v4_route_table; - } else { - if (priv->v6_route_table_initialized) - return priv->v6_route_table; - } - - connection = nm_device_get_applied_connection (self); - if (connection) { - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - if (s_ip) - route_table = nm_setting_ip_config_get_route_table (s_ip); - } - if (route_table == 0u) { - gint64 v; - - v = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.route-table") - : NM_CON_DEFAULT ("ipv6.route-table"), - self, - 0, - G_MAXUINT32, - -1); - if (v != -1) { - route_table = v; - is_user_config = FALSE; - } - } - - if ( route_table == 0u - && connection - && (s_con = nm_connection_get_setting_connection (connection)) - && (nm_streq0 (nm_setting_connection_get_slave_type (s_con), NM_SETTING_VRF_SETTING_NAME) - && priv->master - && nm_device_get_device_type (priv->master) == NM_DEVICE_TYPE_VRF)) { - const NMPlatformLnkVrf *lnk; - - lnk = nm_platform_link_get_lnk_vrf (nm_device_get_platform (self), - nm_device_get_ifindex (priv->master), - NULL); - - if (lnk) - route_table = lnk->table; - } - - if ( route_table == 0u - && connection - && (s_vrf = (NMSettingVrf *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF))) { - route_table = nm_setting_vrf_get_table (s_vrf); - } - - klass = NM_DEVICE_GET_CLASS (self); - if (klass->coerce_route_table) - route_table = klass->coerce_route_table (self, addr_family, route_table, is_user_config); - - if (addr_family == AF_INET) { - priv->v4_route_table_initialized = TRUE; - priv->v4_route_table = route_table; - } else { - priv->v6_route_table_initialized = TRUE; - priv->v6_route_table = route_table; - } - - _LOGT (LOGD_DEVICE, - "ipv%c.route-table = %u%s", - addr_family == AF_INET ? '4' : '6', - (guint) (route_table ?: RT_TABLE_MAIN), - route_table != 0u ? "" : " (policy routing not enabled)"); - - return route_table; + return nm_utils_ip_route_metric_normalize(addr_family, route_metric); } guint32 -nm_device_get_route_table (NMDevice *self, - int addr_family) +nm_device_get_route_table(NMDevice *self, int addr_family) { - guint32 route_table; + guint32 route_table; - g_return_val_if_fail (NM_IS_DEVICE (self), RT_TABLE_MAIN); + g_return_val_if_fail(NM_IS_DEVICE(self), RT_TABLE_MAIN); - route_table = _get_route_table (self, addr_family); - return route_table ?: (guint32) RT_TABLE_MAIN; + route_table = _prop_get_ipvx_route_table(self, addr_family); + return route_table ?: (guint32) RT_TABLE_MAIN; } static NMIPRouteTableSyncMode -_get_route_table_sync_mode_stateful (NMDevice *self, - int addr_family) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDedupMultiIter ipconf_iter; - gboolean all_sync_now; - gboolean all_sync_eff; - - all_sync_now = _get_route_table (self, addr_family) != 0u; - - if (!all_sync_now) { - /* If there's a local route switch to all-sync in order - * to properly manage the local table */ - if (addr_family == AF_INET) { - const NMPlatformIP4Route *route; - - nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->con_ip_config_4, &route) { - if (nm_platform_route_type_uncoerce (route->type_coerced) == RTN_LOCAL) { - all_sync_now = TRUE; - break; - } - } - } else { - const NMPlatformIP6Route *route; - - nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->con_ip_config_6, &route) { - if (nm_platform_route_type_uncoerce (route->type_coerced) == RTN_LOCAL) { - all_sync_now = TRUE; - break; - } - } - } - } - - if (all_sync_now) - all_sync_eff = TRUE; - else { - /* When we change from all-sync to no all-sync, we do a last all-sync one - * more time. For that, we determine the effective all-state based on the - * cached/previous all-sync flag. - * - * The purpose of this is to support reapply of route-table (and thus the - * all-sync mode). If reapply toggles from all-sync to no-all-sync, we must - * sync one last time. */ - if (addr_family == AF_INET) - all_sync_eff = priv->v4_route_table_all_sync_before; - else - all_sync_eff = priv->v6_route_table_all_sync_before; - } - - if (addr_family == AF_INET) - priv->v4_route_table_all_sync_before = all_sync_now; - else - priv->v6_route_table_all_sync_before = all_sync_now; - - return all_sync_eff - ? NM_IP_ROUTE_TABLE_SYNC_MODE_ALL - : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN; +_get_route_table_sync_mode_stateful(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDedupMultiIter ipconf_iter; + gboolean all_sync_now; + gboolean all_sync_eff; + + all_sync_now = _prop_get_ipvx_route_table(self, addr_family) != 0u; + + if (!all_sync_now) { + /* If there's a local route switch to all-sync in order + * to properly manage the local table */ + if (addr_family == AF_INET) { + const NMPlatformIP4Route *route; + + nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->con_ip_config_4, &route) { + if (nm_platform_route_type_uncoerce(route->type_coerced) == RTN_LOCAL) { + all_sync_now = TRUE; + break; + } + } + } else { + const NMPlatformIP6Route *route; + + nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->con_ip_config_6, &route) { + if (nm_platform_route_type_uncoerce(route->type_coerced) == RTN_LOCAL) { + all_sync_now = TRUE; + break; + } + } + } + } + + if (all_sync_now) + all_sync_eff = TRUE; + else { + /* When we change from all-sync to no all-sync, we do a last all-sync one + * more time. For that, we determine the effective all-state based on the + * cached/previous all-sync flag. + * + * The purpose of this is to support reapply of route-table (and thus the + * all-sync mode). If reapply toggles from all-sync to no-all-sync, we must + * sync one last time. */ + if (addr_family == AF_INET) + all_sync_eff = priv->v4_route_table_all_sync_before; + else + all_sync_eff = priv->v6_route_table_all_sync_before; + } + + if (addr_family == AF_INET) + priv->v4_route_table_all_sync_before = all_sync_now; + else + priv->v6_route_table_all_sync_before = all_sync_now; + + return all_sync_eff ? NM_IP_ROUTE_TABLE_SYNC_MODE_ALL : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN; } const NMPObject * -nm_device_get_best_default_route (NMDevice *self, - int addr_family) +nm_device_get_best_default_route(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - switch (addr_family) { - case AF_INET: - return priv->ip_config_4 ? nm_ip4_config_best_default_route_get (priv->ip_config_4) : NULL; - case AF_INET6: - return priv->ip_config_6 ? nm_ip6_config_best_default_route_get (priv->ip_config_6) : NULL; - case AF_UNSPEC: - return (priv->ip_config_4 ? nm_ip4_config_best_default_route_get (priv->ip_config_4) : NULL) - ?: (priv->ip_config_6 ? nm_ip6_config_best_default_route_get (priv->ip_config_6) : NULL); - default: - g_return_val_if_reached (NULL); - } + switch (addr_family) { + case AF_INET: + return priv->ip_config_4 ? nm_ip4_config_best_default_route_get(priv->ip_config_4) : NULL; + case AF_INET6: + return priv->ip_config_6 ? nm_ip6_config_best_default_route_get(priv->ip_config_6) : NULL; + case AF_UNSPEC: + return (priv->ip_config_4 ? nm_ip4_config_best_default_route_get(priv->ip_config_4) : NULL) + ?: (priv->ip_config_6 ? nm_ip6_config_best_default_route_get(priv->ip_config_6) + : NULL); + default: + g_return_val_if_reached(NULL); + } } const char * -nm_device_get_type_desc (NMDevice *self) +nm_device_get_type_desc(NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - return NM_DEVICE_GET_PRIVATE (self)->type_desc; + return NM_DEVICE_GET_PRIVATE(self)->type_desc; } const char * -nm_device_get_type_description (NMDevice *self) +nm_device_get_type_description(NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail(self != NULL, NULL); - /* Beware: this function should return the same - * value as nm_device_get_type_description() in libnm. */ + /* Beware: this function should return the same + * value as nm_device_get_type_description() in libnm. */ - return NM_DEVICE_GET_CLASS (self)->get_type_description (self); + return NM_DEVICE_GET_CLASS(self)->get_type_description(self); } static const char * -get_type_description (NMDevice *self) -{ - NMDeviceClass *klass; - - nm_assert (NM_IS_DEVICE (self)); - - /* the default implementation for the description just returns the (modified) - * class name and depends entirely on the type of self. Note that we cache the - * description in the klass itself. - * - * Also note, that as the GObject class gets inited, it inherrits the fields - * of the parent class. That means, if NMDeviceVethClass was initialized after - * NMDeviceEthernetClass already has the description cached in the class - * (because we already fetched the description for an ethernet device), - * then default_type_description will wrongly contain "ethernet". - * To avoid that, and catch the situation, also cache the klass for - * which the description was cached. If that doesn't match, it was - * inherited and we need to reset it. */ - klass = NM_DEVICE_GET_CLASS (self); - if (G_UNLIKELY (klass->default_type_description_klass != klass)) { - const char *typename; - gs_free char *s = NULL; - - typename = G_OBJECT_TYPE_NAME (self); - if (g_str_has_prefix (typename, "NMDevice")) - typename += 8; - s = g_ascii_strdown (typename, -1); - klass->default_type_description = g_intern_string (s); - klass->default_type_description_klass = klass; - } - - nm_assert (klass->default_type_description); - return klass->default_type_description; +get_type_description(NMDevice *self) +{ + NMDeviceClass *klass; + + nm_assert(NM_IS_DEVICE(self)); + + /* the default implementation for the description just returns the (modified) + * class name and depends entirely on the type of self. Note that we cache the + * description in the klass itself. + * + * Also note, that as the GObject class gets inited, it inherrits the fields + * of the parent class. That means, if NMDeviceVethClass was initialized after + * NMDeviceEthernetClass already has the description cached in the class + * (because we already fetched the description for an ethernet device), + * then default_type_description will wrongly contain "ethernet". + * To avoid that, and catch the situation, also cache the klass for + * which the description was cached. If that doesn't match, it was + * inherited and we need to reset it. */ + klass = NM_DEVICE_GET_CLASS(self); + if (G_UNLIKELY(klass->default_type_description_klass != klass)) { + const char *typename; + gs_free char *s = NULL; + + typename = G_OBJECT_TYPE_NAME(self); + if (g_str_has_prefix(typename, "NMDevice")) + typename += 8; + s = g_ascii_strdown(typename, -1); + klass->default_type_description = g_intern_string(s); + klass->default_type_description_klass = klass; + } + + nm_assert(klass->default_type_description); + return klass->default_type_description; } gboolean -nm_device_has_carrier (NMDevice *self) +nm_device_has_carrier(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->carrier; + return NM_DEVICE_GET_PRIVATE(self)->carrier; } NMActRequest * -nm_device_get_act_request (NMDevice *self) +nm_device_get_act_request(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->act_request.obj; + return NM_DEVICE_GET_PRIVATE(self)->act_request.obj; } NMActivationStateFlags -nm_device_get_activation_state_flags (NMDevice *self) +nm_device_get_activation_state_flags(NMDevice *self) { - NMActRequest *ac; + NMActRequest *ac; - g_return_val_if_fail (NM_IS_DEVICE (self), NM_ACTIVATION_STATE_FLAG_NONE); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_ACTIVATION_STATE_FLAG_NONE); - ac = NM_DEVICE_GET_PRIVATE (self)->act_request.obj; - if (!ac) - return NM_ACTIVATION_STATE_FLAG_NONE; - return nm_active_connection_get_state_flags (NM_ACTIVE_CONNECTION (ac)); + ac = NM_DEVICE_GET_PRIVATE(self)->act_request.obj; + if (!ac) + return NM_ACTIVATION_STATE_FLAG_NONE; + return nm_active_connection_get_state_flags(NM_ACTIVE_CONNECTION(ac)); } NMSettingsConnection * -nm_device_get_settings_connection (NMDevice *self) +nm_device_get_settings_connection(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - return priv->act_request.obj ? nm_act_request_get_settings_connection (priv->act_request.obj) : NULL; + return priv->act_request.obj ? nm_act_request_get_settings_connection(priv->act_request.obj) + : NULL; } NMConnection * -nm_device_get_settings_connection_get_connection (NMDevice *self) +nm_device_get_settings_connection_get_connection(NMDevice *self) { - NMSettingsConnection *sett_con; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMSettingsConnection *sett_con; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->act_request.obj) - return NULL; + if (!priv->act_request.obj) + return NULL; - sett_con = nm_act_request_get_settings_connection (priv->act_request.obj); - if (!sett_con) - return NULL; + sett_con = nm_act_request_get_settings_connection(priv->act_request.obj); + if (!sett_con) + return NULL; - return nm_settings_connection_get_connection (sett_con); + return nm_settings_connection_get_connection(sett_con); } NMConnection * -nm_device_get_applied_connection (NMDevice *self) +nm_device_get_applied_connection(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - return priv->act_request.obj ? nm_act_request_get_applied_connection (priv->act_request.obj) : NULL; + return priv->act_request.obj ? nm_act_request_get_applied_connection(priv->act_request.obj) + : NULL; } gboolean -nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags) +nm_device_has_unmodified_applied_connection(NMDevice *self, NMSettingCompareFlags compare_flags) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->act_request.obj) - return FALSE; + if (!priv->act_request.obj) + return FALSE; - return nm_active_connection_has_unmodified_applied_connection ((NMActiveConnection *) priv->act_request.obj, compare_flags); + return nm_active_connection_has_unmodified_applied_connection( + (NMActiveConnection *) priv->act_request.obj, + compare_flags); } gpointer -nm_device_get_applied_setting (NMDevice *self, GType setting_type) +nm_device_get_applied_setting(NMDevice *self, GType setting_type) { - NMConnection *connection; + NMConnection *connection; - connection = nm_device_get_applied_connection (self); - return connection ? nm_connection_get_setting (connection, setting_type) : NULL; + connection = nm_device_get_applied_connection(self); + return connection ? nm_connection_get_setting(connection, setting_type) : NULL; } RfKillType -nm_device_get_rfkill_type (NMDevice *self) +nm_device_get_rfkill_type(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return NM_DEVICE_GET_PRIVATE (self)->rfkill_type; + return NM_DEVICE_GET_PRIVATE(self)->rfkill_type; } static const char * -nm_device_get_physical_port_id (NMDevice *self) +nm_device_get_physical_port_id(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->physical_port_id; + return NM_DEVICE_GET_PRIVATE(self)->physical_port_id; } /*****************************************************************************/ typedef enum { - CONCHECK_SCHEDULE_UPDATE_INTERVAL, - CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART, - CONCHECK_SCHEDULE_CHECK_EXTERNAL, - CONCHECK_SCHEDULE_CHECK_PERIODIC, - CONCHECK_SCHEDULE_RETURNED_MIN, - CONCHECK_SCHEDULE_RETURNED_BUMP, - CONCHECK_SCHEDULE_RETURNED_MAX, + CONCHECK_SCHEDULE_UPDATE_INTERVAL, + CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART, + CONCHECK_SCHEDULE_CHECK_EXTERNAL, + CONCHECK_SCHEDULE_CHECK_PERIODIC, + CONCHECK_SCHEDULE_RETURNED_MIN, + CONCHECK_SCHEDULE_RETURNED_BUMP, + CONCHECK_SCHEDULE_RETURNED_MAX, } ConcheckScheduleMode; -static NMDeviceConnectivityHandle *concheck_start (NMDevice *self, - int addr_family, - NMDeviceConnectivityCallback callback, - gpointer user_data, - gboolean is_periodic); +static NMDeviceConnectivityHandle *concheck_start(NMDevice * self, + int addr_family, + NMDeviceConnectivityCallback callback, + gpointer user_data, + gboolean is_periodic); -static void concheck_periodic_schedule_set (NMDevice *self, - int addr_family, - ConcheckScheduleMode mode); +static void +concheck_periodic_schedule_set(NMDevice *self, int addr_family, ConcheckScheduleMode mode); static gboolean -_concheck_periodic_timeout_cb (NMDevice *self, int addr_family) +_concheck_periodic_timeout_cb(NMDevice *self, int addr_family) { - _LOGt (LOGD_CONCHECK, "connectivity: [IPv%c] periodic timeout", - nm_utils_addr_family_to_char (addr_family)); - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_CHECK_PERIODIC); - return G_SOURCE_REMOVE; + _LOGt(LOGD_CONCHECK, + "connectivity: [IPv%c] periodic timeout", + nm_utils_addr_family_to_char(addr_family)); + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_CHECK_PERIODIC); + return G_SOURCE_REMOVE; } static gboolean -concheck_ip4_periodic_timeout_cb (gpointer user_data) +concheck_ip4_periodic_timeout_cb(gpointer user_data) { - return _concheck_periodic_timeout_cb (user_data, AF_INET); + return _concheck_periodic_timeout_cb(user_data, AF_INET); } static gboolean -concheck_ip6_periodic_timeout_cb (gpointer user_data) +concheck_ip6_periodic_timeout_cb(gpointer user_data) { - return _concheck_periodic_timeout_cb (user_data, AF_INET6); + return _concheck_periodic_timeout_cb(user_data, AF_INET6); } static gboolean -concheck_is_possible (NMDevice *self) +concheck_is_possible(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( !nm_device_is_real (self) - || is_loopback (self)) - return FALSE; + if (!nm_device_is_real(self) || is_loopback(self)) + return FALSE; - /* we enable periodic checks for every device state (except UNKNOWN). Especially with - * unmanaged devices, it is interesting to know whether we have connectivity on that device. */ - if (priv->state == NM_DEVICE_STATE_UNKNOWN) - return FALSE; + /* we enable periodic checks for every device state (except UNKNOWN). Especially with + * unmanaged devices, it is interesting to know whether we have connectivity on that device. */ + if (priv->state == NM_DEVICE_STATE_UNKNOWN) + return FALSE; - return TRUE; + return TRUE; } static gboolean -concheck_periodic_schedule_do (NMDevice *self, int addr_family, gint64 now_ns) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean periodic_check_disabled = FALSE; - gint64 expiry, tdiff; - const gboolean IS_IPv4 = (addr_family == AF_INET); - - /* we always cancel whatever was pending. */ - if (nm_clear_g_source (&priv->concheck_x[IS_IPv4].p_cur_id)) - periodic_check_disabled = TRUE; - - if (priv->concheck_x[IS_IPv4].p_max_interval == 0) { - /* periodic checks are disabled */ - goto out; - } - - if (!concheck_is_possible (self)) - goto out; - - nm_assert (now_ns > 0); - nm_assert (priv->concheck_x[IS_IPv4].p_cur_interval > 0); - - /* we schedule the timeout based on our current settings cur-interval and cur-basetime. - * Before calling concheck_periodic_schedule_do(), make sure that these properties are - * correct. */ - - expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - tdiff = expiry - now_ns; - - _LOGT (LOGD_CONCHECK, "connectivity: [IPv%c] periodic-check: %sscheduled in %lld milliseconds (%u seconds interval)", - nm_utils_addr_family_to_char (addr_family), - periodic_check_disabled ? "re-" : "", - (long long) (tdiff / NM_UTILS_NSEC_PER_MSEC), - priv->concheck_x[IS_IPv4].p_cur_interval); - - priv->concheck_x[IS_IPv4].p_cur_id = - g_timeout_add (NM_MAX ((gint64) 0, tdiff) / NM_UTILS_NSEC_PER_MSEC, - IS_IPv4 ? concheck_ip4_periodic_timeout_cb : concheck_ip6_periodic_timeout_cb, - self); - return TRUE; +concheck_periodic_schedule_do(NMDevice *self, int addr_family, gint64 now_ns) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean periodic_check_disabled = FALSE; + gint64 expiry, tdiff; + const gboolean IS_IPv4 = (addr_family == AF_INET); + + /* we always cancel whatever was pending. */ + if (nm_clear_g_source(&priv->concheck_x[IS_IPv4].p_cur_id)) + periodic_check_disabled = TRUE; + + if (priv->concheck_x[IS_IPv4].p_max_interval == 0) { + /* periodic checks are disabled */ + goto out; + } + + if (!concheck_is_possible(self)) + goto out; + + nm_assert(now_ns > 0); + nm_assert(priv->concheck_x[IS_IPv4].p_cur_interval > 0); + + /* we schedule the timeout based on our current settings cur-interval and cur-basetime. + * Before calling concheck_periodic_schedule_do(), make sure that these properties are + * correct. */ + + expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); + tdiff = expiry - now_ns; + + _LOGT(LOGD_CONCHECK, + "connectivity: [IPv%c] periodic-check: %sscheduled in %lld milliseconds (%u seconds " + "interval)", + nm_utils_addr_family_to_char(addr_family), + periodic_check_disabled ? "re-" : "", + (long long) (tdiff / NM_UTILS_NSEC_PER_MSEC), + priv->concheck_x[IS_IPv4].p_cur_interval); + + priv->concheck_x[IS_IPv4].p_cur_id = + g_timeout_add(NM_MAX((gint64) 0, tdiff) / NM_UTILS_NSEC_PER_MSEC, + IS_IPv4 ? concheck_ip4_periodic_timeout_cb : concheck_ip6_periodic_timeout_cb, + self); + return TRUE; out: - if (periodic_check_disabled) { - _LOGT (LOGD_CONCHECK, "connectivity: [IPv%c] periodic-check: unscheduled", - nm_utils_addr_family_to_char (addr_family)); - } - return FALSE; + if (periodic_check_disabled) { + _LOGT(LOGD_CONCHECK, + "connectivity: [IPv%c] periodic-check: unscheduled", + nm_utils_addr_family_to_char(addr_family)); + } + return FALSE; } #define CONCHECK_P_PROBE_INTERVAL 1 static void -concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckScheduleMode mode) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gint64 new_expiry, exp_expiry, cur_expiry, tdiff; - gint64 now_ns = 0; - const gboolean IS_IPv4 = (addr_family == AF_INET); - - if (priv->concheck_x[IS_IPv4].p_max_interval == 0) { - /* periodic check is disabled. Nothing to do. */ - return; - } - - if (!priv->concheck_x[IS_IPv4].p_cur_id) { - /* we currently don't have a timeout scheduled. No need to reschedule - * another one... */ - if (NM_IN_SET (mode, CONCHECK_SCHEDULE_UPDATE_INTERVAL, - CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART)) { - /* ... unless, we are about to start periodic checks after update-interval. - * In this case, fall through and restart the periodic checks below. */ - mode = CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART; - } else - return; - } - - switch (mode) { - case CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART: - priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL); - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); - if (concheck_periodic_schedule_do (self, addr_family, now_ns)) - concheck_start (self, addr_family, NULL, NULL, TRUE); - return; - - case CONCHECK_SCHEDULE_UPDATE_INTERVAL: - /* called with "UPDATE_INTERVAL" and already have a p_cur_id scheduled. */ - - nm_assert (priv->concheck_x[IS_IPv4].p_max_interval > 0); - nm_assert (priv->concheck_x[IS_IPv4].p_cur_interval > 0); - - if (priv->concheck_x[IS_IPv4].p_cur_interval <= priv->concheck_x[IS_IPv4].p_max_interval) { - /* we currently have a shorter interval set, than what we now have. Either, - * because we are probing, or because the previous max interval was shorter. - * - * Either way, the current timer is set just fine. Nothing to do, we will - * probe our way up. */ - return; - } - - cur_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_max_interval * NM_UTILS_NSEC_PER_SEC); - nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); - - priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval; - if (cur_expiry <= now_ns) { - /* Since the last time we scheduled a periodic check, already more than the - * new max_interval passed. We need to start a check right away (and - * schedule a timeout in cur-interval in the future). */ - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns; - if (concheck_periodic_schedule_do (self, addr_family, now_ns)) - concheck_start (self, addr_family, NULL, NULL, TRUE); - } else { - /* we are reducing the max-interval to a shorter interval that we have currently - * scheduled (with cur_interval). - * - * However, since the last time we scheduled the check, not even the new max-interval - * expired. All we need to do, is reschedule the timer to expire sooner. The cur_basetime - * is unchanged. */ - concheck_periodic_schedule_do (self, addr_family, now_ns); - } - return; - - case CONCHECK_SCHEDULE_CHECK_EXTERNAL: - /* a external connectivity check delays our periodic check. We reset the counter. */ - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); - concheck_periodic_schedule_do (self, addr_family, now_ns); - return; - - case CONCHECK_SCHEDULE_CHECK_PERIODIC: - { - gboolean any_periodic_pending; - NMDeviceConnectivityHandle *handle; - guint old_interval = priv->concheck_x[IS_IPv4].p_cur_interval; - - any_periodic_pending = FALSE; - c_list_for_each_entry (handle, &priv->concheck_lst_head, concheck_lst) { - if (handle->addr_family != addr_family) - continue; - if (handle->is_periodic_bump) { - handle->is_periodic_bump = FALSE; - handle->is_periodic_bump_on_complete = FALSE; - any_periodic_pending = TRUE; - } - } - if (any_periodic_pending) { - /* we reached a timeout to schedule a new periodic request, however we still - * have period requests pending that didn't complete yet. We need to bump the - * interval already. */ - priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (old_interval * 2, priv->concheck_x[IS_IPv4].p_max_interval); - } - - /* we just reached a timeout. The expected expiry (exp_expiry) should be - * pretty close to now_ns. - * - * We want to reschedule the timeout at exp_expiry (aka now) + cur_interval. */ - nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns); - exp_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (old_interval * NM_UTILS_NSEC_PER_SEC); - new_expiry = exp_expiry + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - tdiff = NM_MAX (new_expiry - now_ns, 0); - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = (now_ns + tdiff) - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - if (concheck_periodic_schedule_do (self, addr_family, now_ns)) { - handle = concheck_start (self, addr_family, NULL, NULL, TRUE); - if (old_interval != priv->concheck_x[IS_IPv4].p_cur_interval) { - /* we just bumped the interval already when scheduling this check. - * When the handle returns, don't bump a second time. - * - * But if we reach the timeout again before the handle returns (this - * code here) we will still bump the interval. */ - handle->is_periodic_bump_on_complete = FALSE; - } - } - return; - } - - /* we just got an event that we lost connectivity (that is, concheck returned). We reset - * the interval to min/max or increase the probe interval (bump). */ - case CONCHECK_SCHEDULE_RETURNED_MIN: - priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL); - break; - case CONCHECK_SCHEDULE_RETURNED_MAX: - priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval; - break; - case CONCHECK_SCHEDULE_RETURNED_BUMP: - priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_cur_interval * 2, priv->concheck_x[IS_IPv4].p_max_interval); - break; - } - - /* we are here, because we returned from a connectivity check and adjust the current interval. - * - * But note that we calculate the new timeout based on the time when we scheduled the - * last check, instead of counting from now. The reason is that we want that the times - * when we schedule checks be at precise intervals, without including the time it took for - * the connectivity check. */ - new_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - tdiff = NM_MAX (new_expiry - nm_utils_get_monotonic_timestamp_nsec_cached (&now_ns), 0); - priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns + tdiff - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); - concheck_periodic_schedule_do (self, addr_family, now_ns); +concheck_periodic_schedule_set(NMDevice *self, int addr_family, ConcheckScheduleMode mode) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gint64 new_expiry, exp_expiry, cur_expiry, tdiff; + gint64 now_ns = 0; + const gboolean IS_IPv4 = (addr_family == AF_INET); + + if (priv->concheck_x[IS_IPv4].p_max_interval == 0) { + /* periodic check is disabled. Nothing to do. */ + return; + } + + if (!priv->concheck_x[IS_IPv4].p_cur_id) { + /* we currently don't have a timeout scheduled. No need to reschedule + * another one... */ + if (NM_IN_SET(mode, + CONCHECK_SCHEDULE_UPDATE_INTERVAL, + CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART)) { + /* ... unless, we are about to start periodic checks after update-interval. + * In this case, fall through and restart the periodic checks below. */ + mode = CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART; + } else + return; + } + + switch (mode) { + case CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART: + priv->concheck_x[IS_IPv4].p_cur_interval = + NM_MIN(priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL); + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = + nm_utils_get_monotonic_timestamp_nsec_cached(&now_ns); + if (concheck_periodic_schedule_do(self, addr_family, now_ns)) + concheck_start(self, addr_family, NULL, NULL, TRUE); + return; + + case CONCHECK_SCHEDULE_UPDATE_INTERVAL: + /* called with "UPDATE_INTERVAL" and already have a p_cur_id scheduled. */ + + nm_assert(priv->concheck_x[IS_IPv4].p_max_interval > 0); + nm_assert(priv->concheck_x[IS_IPv4].p_cur_interval > 0); + + if (priv->concheck_x[IS_IPv4].p_cur_interval <= priv->concheck_x[IS_IPv4].p_max_interval) { + /* we currently have a shorter interval set, than what we now have. Either, + * because we are probing, or because the previous max interval was shorter. + * + * Either way, the current timer is set just fine. Nothing to do, we will + * probe our way up. */ + return; + } + + cur_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + + (priv->concheck_x[IS_IPv4].p_max_interval * NM_UTILS_NSEC_PER_SEC); + nm_utils_get_monotonic_timestamp_nsec_cached(&now_ns); + + priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval; + if (cur_expiry <= now_ns) { + /* Since the last time we scheduled a periodic check, already more than the + * new max_interval passed. We need to start a check right away (and + * schedule a timeout in cur-interval in the future). */ + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns; + if (concheck_periodic_schedule_do(self, addr_family, now_ns)) + concheck_start(self, addr_family, NULL, NULL, TRUE); + } else { + /* we are reducing the max-interval to a shorter interval that we have currently + * scheduled (with cur_interval). + * + * However, since the last time we scheduled the check, not even the new max-interval + * expired. All we need to do, is reschedule the timer to expire sooner. The cur_basetime + * is unchanged. */ + concheck_periodic_schedule_do(self, addr_family, now_ns); + } + return; + + case CONCHECK_SCHEDULE_CHECK_EXTERNAL: + /* a external connectivity check delays our periodic check. We reset the counter. */ + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = + nm_utils_get_monotonic_timestamp_nsec_cached(&now_ns); + concheck_periodic_schedule_do(self, addr_family, now_ns); + return; + + case CONCHECK_SCHEDULE_CHECK_PERIODIC: + { + gboolean any_periodic_pending; + NMDeviceConnectivityHandle *handle; + guint old_interval = priv->concheck_x[IS_IPv4].p_cur_interval; + + any_periodic_pending = FALSE; + c_list_for_each_entry (handle, &priv->concheck_lst_head, concheck_lst) { + if (handle->addr_family != addr_family) + continue; + if (handle->is_periodic_bump) { + handle->is_periodic_bump = FALSE; + handle->is_periodic_bump_on_complete = FALSE; + any_periodic_pending = TRUE; + } + } + if (any_periodic_pending) { + /* we reached a timeout to schedule a new periodic request, however we still + * have period requests pending that didn't complete yet. We need to bump the + * interval already. */ + priv->concheck_x[IS_IPv4].p_cur_interval = + NM_MIN(old_interval * 2, priv->concheck_x[IS_IPv4].p_max_interval); + } + + /* we just reached a timeout. The expected expiry (exp_expiry) should be + * pretty close to now_ns. + * + * We want to reschedule the timeout at exp_expiry (aka now) + cur_interval. */ + nm_utils_get_monotonic_timestamp_nsec_cached(&now_ns); + exp_expiry = + priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (old_interval * NM_UTILS_NSEC_PER_SEC); + new_expiry = + exp_expiry + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); + tdiff = NM_MAX(new_expiry - now_ns, 0); + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = + (now_ns + tdiff) - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); + if (concheck_periodic_schedule_do(self, addr_family, now_ns)) { + handle = concheck_start(self, addr_family, NULL, NULL, TRUE); + if (old_interval != priv->concheck_x[IS_IPv4].p_cur_interval) { + /* we just bumped the interval already when scheduling this check. + * When the handle returns, don't bump a second time. + * + * But if we reach the timeout again before the handle returns (this + * code here) we will still bump the interval. */ + handle->is_periodic_bump_on_complete = FALSE; + } + } + return; + } + + /* we just got an event that we lost connectivity (that is, concheck returned). We reset + * the interval to min/max or increase the probe interval (bump). */ + case CONCHECK_SCHEDULE_RETURNED_MIN: + priv->concheck_x[IS_IPv4].p_cur_interval = + NM_MIN(priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL); + break; + case CONCHECK_SCHEDULE_RETURNED_MAX: + priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval; + break; + case CONCHECK_SCHEDULE_RETURNED_BUMP: + priv->concheck_x[IS_IPv4].p_cur_interval = + NM_MIN(priv->concheck_x[IS_IPv4].p_cur_interval * 2, + priv->concheck_x[IS_IPv4].p_max_interval); + break; + } + + /* we are here, because we returned from a connectivity check and adjust the current interval. + * + * But note that we calculate the new timeout based on the time when we scheduled the + * last check, instead of counting from now. The reason is that we want that the times + * when we schedule checks be at precise intervals, without including the time it took for + * the connectivity check. */ + new_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); + tdiff = NM_MAX(new_expiry - nm_utils_get_monotonic_timestamp_nsec_cached(&now_ns), 0); + priv->concheck_x[IS_IPv4].p_cur_basetime_ns = + now_ns + tdiff - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NSEC_PER_SEC); + concheck_periodic_schedule_do(self, addr_family, now_ns); } static void -concheck_update_interval (NMDevice *self, int addr_family, gboolean check_now) +concheck_update_interval(NMDevice *self, int addr_family, gboolean check_now) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - guint new_interval; - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + guint new_interval; + const gboolean IS_IPv4 = (addr_family == AF_INET); - new_interval = nm_connectivity_get_interval (concheck_get_mgr (self)); + new_interval = nm_connectivity_get_interval(concheck_get_mgr(self)); - new_interval = NM_MIN (new_interval, 7 *24 * 3600); + new_interval = NM_MIN(new_interval, 7 * 24 * 3600); - if (new_interval != priv->concheck_x[IS_IPv4].p_max_interval) { - _LOGT (LOGD_CONCHECK, "connectivity: [IPv%c] periodic-check: set interval to %u seconds", - nm_utils_addr_family_to_char (addr_family), new_interval); - priv->concheck_x[IS_IPv4].p_max_interval = new_interval; - } + if (new_interval != priv->concheck_x[IS_IPv4].p_max_interval) { + _LOGT(LOGD_CONCHECK, + "connectivity: [IPv%c] periodic-check: set interval to %u seconds", + nm_utils_addr_family_to_char(addr_family), + new_interval); + priv->concheck_x[IS_IPv4].p_max_interval = new_interval; + } - if (!new_interval) { - /* this will cancel any potentially pending timeout because max-interval is zero. - * But it logs a nice message... */ - concheck_periodic_schedule_do (self, addr_family, 0); + if (!new_interval) { + /* this will cancel any potentially pending timeout because max-interval is zero. + * But it logs a nice message... */ + concheck_periodic_schedule_do(self, addr_family, 0); - /* also update the fake connectivity state. */ - concheck_update_state (self, addr_family, NM_CONNECTIVITY_FAKE, TRUE); - return; - } + /* also update the fake connectivity state. */ + concheck_update_state(self, addr_family, NM_CONNECTIVITY_FAKE, TRUE); + return; + } - concheck_periodic_schedule_set (self, - addr_family, - check_now - ? CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART - : CONCHECK_SCHEDULE_UPDATE_INTERVAL); + concheck_periodic_schedule_set(self, + addr_family, + check_now ? CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART + : CONCHECK_SCHEDULE_UPDATE_INTERVAL); } void -nm_device_check_connectivity_update_interval (NMDevice *self) +nm_device_check_connectivity_update_interval(NMDevice *self) { - concheck_update_interval (self, AF_INET, TRUE); - concheck_update_interval (self, AF_INET6, TRUE); + concheck_update_interval(self, AF_INET, TRUE); + concheck_update_interval(self, AF_INET6, TRUE); } static void -concheck_update_state (NMDevice *self, - int addr_family, - NMConnectivityState state, - gboolean allow_periodic_bump) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - - /* @state is a result of the connectivity check. We only expect a precise - * number of possible values. */ - nm_assert (NM_IN_SET (state, NM_CONNECTIVITY_LIMITED, - NM_CONNECTIVITY_PORTAL, - NM_CONNECTIVITY_FULL, - NM_CONNECTIVITY_FAKE, - NM_CONNECTIVITY_NONE, - NM_CONNECTIVITY_ERROR)); - - if (state == NM_CONNECTIVITY_ERROR) { - /* on error, we don't change the current connectivity state, - * except making UNKNOWN to NONE. */ - state = priv->concheck_x[IS_IPv4].state; - if (state == NM_CONNECTIVITY_UNKNOWN) - state = NM_CONNECTIVITY_NONE; - } else if (state == NM_CONNECTIVITY_FAKE) { - /* If the connectivity check is disabled and we obtain a fake - * result, make an optimistic guess. */ - if (priv->state == NM_DEVICE_STATE_ACTIVATED) { - /* FIXME: the fake connectivity state depends on the availablility of - * a default route. However, we have no mechanism that rechecks the - * value if a device route appears/disappears after the device - * was activated. */ - if (nm_device_get_best_default_route (self, AF_UNSPEC)) - state = NM_CONNECTIVITY_FULL; - else - state = NM_CONNECTIVITY_LIMITED; - } else - state = NM_CONNECTIVITY_NONE; - } - - if (priv->concheck_x[IS_IPv4].state == state) { - /* we got a connectivty update, but the state didn't change. If we were probing, - * we bump the probe frequency. */ - if (allow_periodic_bump) - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP); - return; - } - /* we need to update the probe interval before emitting signals. Emitting - * a signal might call back into NMDevice and change the probe settings. - * So, do that first. */ - if (state == NM_CONNECTIVITY_FULL) { - /* we reached full connectivity state. Stop probing by setting the - * interval to the max. */ - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_MAX); - } else if (priv->concheck_x[IS_IPv4].state == NM_CONNECTIVITY_FULL) { - /* we are about to loose connectivity. (re)start probing by setting - * the timeout interval to the min. */ - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_MIN); - } else { - if (allow_periodic_bump) - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP); - } - - _LOGD (LOGD_CONCHECK, "connectivity state changed from %s to %s", - nm_connectivity_state_to_string (priv->concheck_x[IS_IPv4].state), - nm_connectivity_state_to_string (state)); - priv->concheck_x[IS_IPv4].state = state; - - _notify (self, IS_IPv4 ? PROP_IP4_CONNECTIVITY : PROP_IP6_CONNECTIVITY); - - if ( priv->state == NM_DEVICE_STATE_ACTIVATED - && !nm_device_sys_iface_state_is_external (self)) { - if ( nm_device_get_best_default_route (self, AF_INET) - && !ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "Failed to update IPv4 route metric"); - if ( nm_device_get_best_default_route (self, AF_INET6) - && !ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "Failed to update IPv6 route metric"); - } +concheck_update_state(NMDevice * self, + int addr_family, + NMConnectivityState state, + gboolean allow_periodic_bump) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + + /* @state is a result of the connectivity check. We only expect a precise + * number of possible values. */ + nm_assert(NM_IN_SET(state, + NM_CONNECTIVITY_LIMITED, + NM_CONNECTIVITY_PORTAL, + NM_CONNECTIVITY_FULL, + NM_CONNECTIVITY_FAKE, + NM_CONNECTIVITY_NONE, + NM_CONNECTIVITY_ERROR)); + + if (state == NM_CONNECTIVITY_ERROR) { + /* on error, we don't change the current connectivity state, + * except making UNKNOWN to NONE. */ + state = priv->concheck_x[IS_IPv4].state; + if (state == NM_CONNECTIVITY_UNKNOWN) + state = NM_CONNECTIVITY_NONE; + } else if (state == NM_CONNECTIVITY_FAKE) { + /* If the connectivity check is disabled and we obtain a fake + * result, make an optimistic guess. */ + if (priv->state == NM_DEVICE_STATE_ACTIVATED) { + /* FIXME: the fake connectivity state depends on the availability of + * a default route. However, we have no mechanism that rechecks the + * value if a device route appears/disappears after the device + * was activated. */ + if (nm_device_get_best_default_route(self, AF_UNSPEC)) + state = NM_CONNECTIVITY_FULL; + else + state = NM_CONNECTIVITY_LIMITED; + } else + state = NM_CONNECTIVITY_NONE; + } + + if (priv->concheck_x[IS_IPv4].state == state) { + /* we got a connectivity update, but the state didn't change. If we were probing, + * we bump the probe frequency. */ + if (allow_periodic_bump) + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP); + return; + } + /* we need to update the probe interval before emitting signals. Emitting + * a signal might call back into NMDevice and change the probe settings. + * So, do that first. */ + if (state == NM_CONNECTIVITY_FULL) { + /* we reached full connectivity state. Stop probing by setting the + * interval to the max. */ + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_RETURNED_MAX); + } else if (priv->concheck_x[IS_IPv4].state == NM_CONNECTIVITY_FULL) { + /* we are about to loose connectivity. (re)start probing by setting + * the timeout interval to the min. */ + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_RETURNED_MIN); + } else { + if (allow_periodic_bump) + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP); + } + + _LOGD(LOGD_CONCHECK, + "connectivity state changed from %s to %s", + nm_connectivity_state_to_string(priv->concheck_x[IS_IPv4].state), + nm_connectivity_state_to_string(state)); + priv->concheck_x[IS_IPv4].state = state; + + _notify(self, IS_IPv4 ? PROP_IP4_CONNECTIVITY : PROP_IP6_CONNECTIVITY); + + if (priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_sys_iface_state_is_external(self)) { + if (nm_device_get_best_default_route(self, AF_INET) + && !ip_config_merge_and_apply(self, AF_INET, TRUE)) + _LOGW(LOGD_IP4, "Failed to update IPv4 route metric"); + if (nm_device_get_best_default_route(self, AF_INET6) + && !ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "Failed to update IPv6 route metric"); + } } static const char * -nm_device_get_effective_ip_config_method (NMDevice *self, - int addr_family) +nm_device_get_effective_ip_config_method(NMDevice *self, int addr_family) { - NMDeviceClass *klass; - NMConnection *connection = nm_device_get_applied_connection (self); - const char *method; + NMDeviceClass *klass; + NMConnection * connection = nm_device_get_applied_connection(self); + const char * method; - g_return_val_if_fail (NM_IS_CONNECTION (connection), "" /* bogus */); - nm_assert_addr_family (addr_family); + g_return_val_if_fail(NM_IS_CONNECTION(connection), "" /* bogus */); + nm_assert_addr_family(addr_family); - method = nm_utils_get_ip_config_method (connection, addr_family); + method = nm_utils_get_ip_config_method(connection, addr_family); - if ( (addr_family == AF_INET && nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) - || (addr_family == AF_INET6 && nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO))) { - klass = NM_DEVICE_GET_CLASS (self); - if (klass->get_auto_ip_config_method) { - const char *auto_method; + if ((addr_family == AF_INET && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + || (addr_family == AF_INET6 && nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO))) { + klass = NM_DEVICE_GET_CLASS(self); + if (klass->get_auto_ip_config_method) { + const char *auto_method; - auto_method = klass->get_auto_ip_config_method (self, addr_family); - if (auto_method) - return auto_method; - } - } + auto_method = klass->get_auto_ip_config_method(self, addr_family); + if (auto_method) + return auto_method; + } + } - return method; + return method; } static void -concheck_handle_complete (NMDeviceConnectivityHandle *handle, GError *error) +concheck_handle_complete(NMDeviceConnectivityHandle *handle, GError *error) { - const gboolean IS_IPv4 = (handle->addr_family == AF_INET); + const gboolean IS_IPv4 = (handle->addr_family == AF_INET); - /* The moment we invoke the callback, we unlink it. It signals - * that @handle is handled -- as far as the callee of callback - * is concerned. */ - c_list_unlink (&handle->concheck_lst); + /* The moment we invoke the callback, we unlink it. It signals + * that @handle is handled -- as far as the callee of callback + * is concerned. */ + c_list_unlink(&handle->concheck_lst); - if (handle->c_handle) - nm_connectivity_check_cancel (handle->c_handle); + if (handle->c_handle) + nm_connectivity_check_cancel(handle->c_handle); - if (handle->callback) { - handle->callback (handle->self, - handle, - NM_DEVICE_GET_PRIVATE (handle->self)->concheck_x[IS_IPv4].state, - error, - handle->user_data); - } + if (handle->callback) { + handle->callback(handle->self, + handle, + NM_DEVICE_GET_PRIVATE(handle->self)->concheck_x[IS_IPv4].state, + error, + handle->user_data); + } - g_slice_free (NMDeviceConnectivityHandle, handle); + g_slice_free(NMDeviceConnectivityHandle, handle); } static void -concheck_cb (NMConnectivity *connectivity, - NMConnectivityCheckHandle *c_handle, - NMConnectivityState state, - gpointer user_data) -{ - _nm_unused gs_unref_object NMDevice *self_keep_alive = NULL; - NMDevice *self; - NMDevicePrivate *priv; - NMDeviceConnectivityHandle *handle; - NMDeviceConnectivityHandle *other_handle; - gboolean handle_is_alive; - gboolean allow_periodic_bump; - gboolean any_periodic_before; - gboolean any_periodic_after; - guint64 seq; - - handle = user_data; - nm_assert (handle->c_handle == c_handle); - nm_assert (NM_IS_DEVICE (handle->self)); - - handle->c_handle = NULL; - self = handle->self; - - if (state == NM_CONNECTIVITY_CANCELLED) { - /* the only place where we nm_connectivity_check_cancel(@c_handle), is - * from inside concheck_handle_complete(). This is a recursive call, - * nothing to do. */ - _LOGT (LOGD_CONCHECK, "connectivity: [IPv%c] complete check (seq:%llu, cancelled)", - nm_utils_addr_family_to_char (handle->addr_family), - (long long unsigned) handle->seq); - return; - } - - /* we keep NMConnectivity instance alive. It cannot be disposing. */ - nm_assert (state != NM_CONNECTIVITY_DISPOSING); - - self_keep_alive = g_object_ref (self); - - /* keep @self alive, while we invoke callbacks. */ - priv = NM_DEVICE_GET_PRIVATE (self); - - nm_assert (handle && c_list_contains (&priv->concheck_lst_head, &handle->concheck_lst)); - - seq = handle->seq; - - _LOGT (LOGD_CONCHECK, "connectivity: [Ipv%c] complete check (seq:%llu, state:%s)", - nm_utils_addr_family_to_char (handle->addr_family), - (long long unsigned) handle->seq, - nm_connectivity_state_to_string (state)); - - /* find out, if there are any periodic checks pending (either whether they - * were scheduled before or after @handle. */ - any_periodic_before = FALSE; - any_periodic_after = FALSE; - c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) { - if (other_handle->addr_family != handle->addr_family) - continue; - if (other_handle->is_periodic_bump_on_complete) { - if (other_handle->seq < seq) - any_periodic_before = TRUE; - else if (other_handle->seq > seq) - any_periodic_after = TRUE; - } - } - if (NM_IN_SET (state, NM_CONNECTIVITY_ERROR)) { - /* the request failed. We consider this periodic check only as completed if - * this was a periodic check, and there are not checks pending (either - * before or after this one). - * - * We allow_periodic_bump, if the request failed and there are - * still other requests periodic pending. */ - allow_periodic_bump = handle->is_periodic_bump_on_complete - && !any_periodic_before - && !any_periodic_after; - } else { - /* the request succeeded. This marks the completion of a periodic check, - * if this handle was periodic, or any previously scheduled one (that - * we are going to complete below). */ - allow_periodic_bump = handle->is_periodic_bump_on_complete - || any_periodic_before; - } - - /* first update the new state, and emit signals. */ - concheck_update_state (self, handle->addr_family, state, allow_periodic_bump); - - handle_is_alive = FALSE; - - /* we might have invoked callbacks during concheck_update_state(). The caller might have - * cancelled and thus destroyed @handle. We have to check whether handle is still alive, - * by searching it in the list of alive handles. - * - * Also, we might want to complete all pending callbacks that were started before - * @handle, as they are automatically obsoleted. */ +concheck_cb(NMConnectivity * connectivity, + NMConnectivityCheckHandle *c_handle, + NMConnectivityState state, + gpointer user_data) +{ + _nm_unused gs_unref_object NMDevice *self_keep_alive = NULL; + NMDevice * self; + NMDevicePrivate * priv; + NMDeviceConnectivityHandle * handle; + NMDeviceConnectivityHandle * other_handle; + gboolean handle_is_alive; + gboolean allow_periodic_bump; + gboolean any_periodic_before; + gboolean any_periodic_after; + guint64 seq; + + handle = user_data; + nm_assert(handle->c_handle == c_handle); + nm_assert(NM_IS_DEVICE(handle->self)); + + handle->c_handle = NULL; + self = handle->self; + + if (state == NM_CONNECTIVITY_CANCELLED) { + /* the only place where we nm_connectivity_check_cancel(@c_handle), is + * from inside concheck_handle_complete(). This is a recursive call, + * nothing to do. */ + _LOGT(LOGD_CONCHECK, + "connectivity: [IPv%c] complete check (seq:%llu, cancelled)", + nm_utils_addr_family_to_char(handle->addr_family), + (long long unsigned) handle->seq); + return; + } + + /* we keep NMConnectivity instance alive. It cannot be disposing. */ + nm_assert(state != NM_CONNECTIVITY_DISPOSING); + + self_keep_alive = g_object_ref(self); + + /* keep @self alive, while we invoke callbacks. */ + priv = NM_DEVICE_GET_PRIVATE(self); + + nm_assert(handle && c_list_contains(&priv->concheck_lst_head, &handle->concheck_lst)); + + seq = handle->seq; + + _LOGT(LOGD_CONCHECK, + "connectivity: [Ipv%c] complete check (seq:%llu, state:%s)", + nm_utils_addr_family_to_char(handle->addr_family), + (long long unsigned) handle->seq, + nm_connectivity_state_to_string(state)); + + /* find out, if there are any periodic checks pending (either whether they + * were scheduled before or after @handle. */ + any_periodic_before = FALSE; + any_periodic_after = FALSE; + c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) { + if (other_handle->addr_family != handle->addr_family) + continue; + if (other_handle->is_periodic_bump_on_complete) { + if (other_handle->seq < seq) + any_periodic_before = TRUE; + else if (other_handle->seq > seq) + any_periodic_after = TRUE; + } + } + if (NM_IN_SET(state, NM_CONNECTIVITY_ERROR)) { + /* the request failed. We consider this periodic check only as completed if + * this was a periodic check, and there are not checks pending (either + * before or after this one). + * + * We allow_periodic_bump, if the request failed and there are + * still other requests periodic pending. */ + allow_periodic_bump = + handle->is_periodic_bump_on_complete && !any_periodic_before && !any_periodic_after; + } else { + /* the request succeeded. This marks the completion of a periodic check, + * if this handle was periodic, or any previously scheduled one (that + * we are going to complete below). */ + allow_periodic_bump = handle->is_periodic_bump_on_complete || any_periodic_before; + } + + /* first update the new state, and emit signals. */ + concheck_update_state(self, handle->addr_family, state, allow_periodic_bump); + + handle_is_alive = FALSE; + + /* we might have invoked callbacks during concheck_update_state(). The caller might have + * cancelled and thus destroyed @handle. We have to check whether handle is still alive, + * by searching it in the list of alive handles. + * + * Also, we might want to complete all pending callbacks that were started before + * @handle, as they are automatically obsoleted. */ check_handles: - c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) { - if (other_handle->addr_family != handle->addr_family) - continue; - if (other_handle->seq >= seq) { - /* it's not guaranteed that @handle is still in the list. It might already - * be canceled while invoking callbacks for a previous other_handle. - * If it is already cancelled, @handle is a dangling pointer. - * - * Since @seq is assigned uniquely and increasing, either @other_handle is - * @handle (and thus, handle is alive), or it isn't. */ - if (other_handle == handle) - handle_is_alive = TRUE; - break; - } - - nm_assert (other_handle != handle); - - if (!NM_IN_SET (state, NM_CONNECTIVITY_ERROR)) { - /* we also want to complete handles that were started before the current - * @handle. Their response is out-dated. */ - concheck_handle_complete (other_handle, NULL); - - /* we invoked callbacks, other handles might be cancelled and removed from the list. - * Need to iterate the list from the start. */ - goto check_handles; - } - } - - if (!handle_is_alive) { - /* We didn't find @handle in the list of alive handles. Thus, the handles - * was cancelled while we were invoking events. Nothing to do, and don't - * touch the dangling pointer. */ - return; - } - - concheck_handle_complete (handle, NULL); + c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) { + if (other_handle->addr_family != handle->addr_family) + continue; + if (other_handle->seq >= seq) { + /* it's not guaranteed that @handle is still in the list. It might already + * be canceled while invoking callbacks for a previous other_handle. + * If it is already cancelled, @handle is a dangling pointer. + * + * Since @seq is assigned uniquely and increasing, either @other_handle is + * @handle (and thus, handle is alive), or it isn't. */ + if (other_handle == handle) + handle_is_alive = TRUE; + break; + } + + nm_assert(other_handle != handle); + + if (!NM_IN_SET(state, NM_CONNECTIVITY_ERROR)) { + /* we also want to complete handles that were started before the current + * @handle. Their response is out-dated. */ + concheck_handle_complete(other_handle, NULL); + + /* we invoked callbacks, other handles might be cancelled and removed from the list. + * Need to iterate the list from the start. */ + goto check_handles; + } + } + + if (!handle_is_alive) { + /* We didn't find @handle in the list of alive handles. Thus, the handles + * was cancelled while we were invoking events. Nothing to do, and don't + * touch the dangling pointer. */ + return; + } + + concheck_handle_complete(handle, NULL); } static NMDeviceConnectivityHandle * -concheck_start (NMDevice *self, - int addr_family, - NMDeviceConnectivityCallback callback, - gpointer user_data, - gboolean is_periodic) -{ - static guint64 seq_counter = 0; - NMDevicePrivate *priv; - NMDeviceConnectivityHandle *handle; - const char *ifname; - - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - - priv = NM_DEVICE_GET_PRIVATE (self); - - handle = g_slice_new0 (NMDeviceConnectivityHandle); - handle->seq = ++seq_counter; - handle->self = self; - handle->callback = callback; - handle->user_data = user_data; - handle->is_periodic = is_periodic; - handle->is_periodic_bump = is_periodic; - handle->is_periodic_bump_on_complete = is_periodic; - handle->addr_family = addr_family; - - c_list_link_tail (&priv->concheck_lst_head, &handle->concheck_lst); - - _LOGT (LOGD_CONCHECK, "connectivity: [IPv%c] start check (seq:%llu%s)", - nm_utils_addr_family_to_char (addr_family), - (long long unsigned) handle->seq, - is_periodic ? ", periodic-check" : ""); - - if ( addr_family == AF_INET - && !priv->concheck_rp_filter_checked) { - - if ((ifname = nm_device_get_ip_iface_from_platform (self))) { - gboolean due_to_all; - int val; - - val = nm_platform_sysctl_ip_conf_get_rp_filter_ipv4 (nm_device_get_platform (self), - ifname, - TRUE, - &due_to_all); - if (val == 1) { - _LOGW (LOGD_CONCHECK, "connectivity: \"/proc/sys/net/ipv4/conf/%s/rp_filter\" is set to \"1\". " - "This might break connectivity checking for IPv4 on this device", - due_to_all ? "all" : ifname); - } - } - - /* we only check once per device. It's a warning after all. */ - priv->concheck_rp_filter_checked = TRUE; - } - - handle->c_handle = nm_connectivity_check_start (concheck_get_mgr (self), - handle->addr_family, - nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - nm_device_get_ip_iface (self), - concheck_cb, - handle); - return handle; +concheck_start(NMDevice * self, + int addr_family, + NMDeviceConnectivityCallback callback, + gpointer user_data, + gboolean is_periodic) +{ + static guint64 seq_counter = 0; + NMDevicePrivate * priv; + NMDeviceConnectivityHandle *handle; + const char * ifname; + + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); + + priv = NM_DEVICE_GET_PRIVATE(self); + + handle = g_slice_new0(NMDeviceConnectivityHandle); + handle->seq = ++seq_counter; + handle->self = self; + handle->callback = callback; + handle->user_data = user_data; + handle->is_periodic = is_periodic; + handle->is_periodic_bump = is_periodic; + handle->is_periodic_bump_on_complete = is_periodic; + handle->addr_family = addr_family; + + c_list_link_tail(&priv->concheck_lst_head, &handle->concheck_lst); + + _LOGT(LOGD_CONCHECK, + "connectivity: [IPv%c] start check (seq:%llu%s)", + nm_utils_addr_family_to_char(addr_family), + (long long unsigned) handle->seq, + is_periodic ? ", periodic-check" : ""); + + if (addr_family == AF_INET && !priv->concheck_rp_filter_checked) { + if ((ifname = nm_device_get_ip_iface_from_platform(self))) { + gboolean due_to_all; + int val; + + val = nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(nm_device_get_platform(self), + ifname, + TRUE, + &due_to_all); + if (val == 1) { + _LOGW(LOGD_CONCHECK, + "connectivity: \"/proc/sys/net/ipv4/conf/%s/rp_filter\" is set to \"1\". " + "This might break connectivity checking for IPv4 on this device", + due_to_all ? "all" : ifname); + } + } + + /* we only check once per device. It's a warning after all. */ + priv->concheck_rp_filter_checked = TRUE; + } + + handle->c_handle = nm_connectivity_check_start(concheck_get_mgr(self), + handle->addr_family, + nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + nm_device_get_ip_iface(self), + concheck_cb, + handle); + return handle; } NMDeviceConnectivityHandle * -nm_device_check_connectivity (NMDevice *self, - int addr_family, - NMDeviceConnectivityCallback callback, - gpointer user_data) +nm_device_check_connectivity(NMDevice * self, + int addr_family, + NMDeviceConnectivityCallback callback, + gpointer user_data) { - if (!concheck_is_possible (self)) - return NULL; + if (!concheck_is_possible(self)) + return NULL; - concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_CHECK_EXTERNAL); - return concheck_start (self, addr_family, callback, user_data, FALSE); + concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_CHECK_EXTERNAL); + return concheck_start(self, addr_family, callback, user_data, FALSE); } void -nm_device_check_connectivity_cancel (NMDeviceConnectivityHandle *handle) +nm_device_check_connectivity_cancel(NMDeviceConnectivityHandle *handle) { - gs_free_error GError *cancelled_error = NULL; + gs_free_error GError *cancelled_error = NULL; - g_return_if_fail (handle); - g_return_if_fail (NM_IS_DEVICE (handle->self)); - g_return_if_fail (!c_list_is_empty (&handle->concheck_lst)); + g_return_if_fail(handle); + g_return_if_fail(NM_IS_DEVICE(handle->self)); + g_return_if_fail(!c_list_is_empty(&handle->concheck_lst)); - /* nobody has access to periodic handles, and cannot cancel - * them externally. */ - nm_assert (!handle->is_periodic); + /* nobody has access to periodic handles, and cannot cancel + * them externally. */ + nm_assert(!handle->is_periodic); - nm_utils_error_set_cancelled (&cancelled_error, FALSE, "NMDevice"); - concheck_handle_complete (handle, cancelled_error); + nm_utils_error_set_cancelled(&cancelled_error, FALSE, "NMDevice"); + concheck_handle_complete(handle, cancelled_error); } NMConnectivityState -nm_device_get_connectivity_state (NMDevice *self, int addr_family) +nm_device_get_connectivity_state(NMDevice *self, int addr_family) { - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_val_if_fail (NM_IS_DEVICE (self), NM_CONNECTIVITY_UNKNOWN); - nm_assert_addr_family (addr_family); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_CONNECTIVITY_UNKNOWN); + nm_assert_addr_family(addr_family); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - switch (addr_family) { - case AF_INET: - case AF_INET6: - return priv->concheck_x[IS_IPv4].state; - default: - nm_assert (addr_family == AF_UNSPEC); - return NM_MAX_WITH_CMP (nm_connectivity_state_cmp, - priv->concheck_x[0].state, - priv->concheck_x[1].state); - } + switch (addr_family) { + case AF_INET: + case AF_INET6: + return priv->concheck_x[IS_IPv4].state; + default: + nm_assert(addr_family == AF_UNSPEC); + return NM_MAX_WITH_CMP(nm_connectivity_state_cmp, + priv->concheck_x[0].state, + priv->concheck_x[1].state); + } } /*****************************************************************************/ static SlaveInfo * -find_slave_info (NMDevice *self, NMDevice *slave) +find_slave_info(NMDevice *self, NMDevice *slave) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - CList *iter; - SlaveInfo *info; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + CList * iter; + SlaveInfo * info; - c_list_for_each (iter, &priv->slaves) { - info = c_list_entry (iter, SlaveInfo, lst_slave); - if (info->slave == slave) - return info; - } - return NULL; + c_list_for_each (iter, &priv->slaves) { + info = c_list_entry(iter, SlaveInfo, lst_slave); + if (info->slave == slave) + return info; + } + return NULL; } /** @@ -3683,63 +4607,62 @@ find_slave_info (NMDevice *self, NMDevice *slave) * other devices. */ static gboolean -nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection) +nm_device_master_enslave_slave(NMDevice *self, NMDevice *slave, NMConnection *connection) { - NMDevicePrivate *priv; - SlaveInfo *info; - gboolean success = FALSE; - gboolean configure; + NMDevicePrivate *priv; + SlaveInfo * info; + gboolean success = FALSE; + gboolean configure; - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); + g_return_val_if_fail(self != NULL, FALSE); + g_return_val_if_fail(slave != NULL, FALSE); + g_return_val_if_fail(NM_DEVICE_GET_CLASS(self)->enslave_slave != NULL, FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); - info = find_slave_info (self, slave); - if (!info) - return FALSE; + priv = NM_DEVICE_GET_PRIVATE(self); + info = find_slave_info(self, slave); + if (!info) + return FALSE; - if (info->slave_is_enslaved) - success = TRUE; - else { - configure = (info->configure && connection != NULL); - if (configure) - g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); + if (info->slave_is_enslaved) + success = TRUE; + else { + configure = (info->configure && connection != NULL); + if (configure) + g_return_val_if_fail(nm_device_get_state(slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure); - info->slave_is_enslaved = success; - } + success = NM_DEVICE_GET_CLASS(self)->enslave_slave(self, slave, connection, configure); + info->slave_is_enslaved = success; + } - nm_device_slave_notify_enslave (info->slave, success); + nm_device_slave_notify_enslave(info->slave, success); - /* Ensure the device's hardware address is up-to-date; it often changes - * when slaves change. - */ - nm_device_update_hw_address (self); + /* Ensure the device's hardware address is up-to-date; it often changes + * when slaves change. + */ + nm_device_update_hw_address(self); - /* Send ARP announcements if did not yet and have addresses. */ - if ( priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE - && !priv->acd.announcing) - nm_device_arp_announce (self); + /* Send ARP announcements if did not yet and have addresses. */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !priv->acd.announcing) + nm_device_arp_announce(self); - /* Restart IP configuration if we're waiting for slaves. Do this - * after updating the hardware address as IP config may need the - * new address. - */ - if (success) { - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_WAIT) - nm_device_activate_stage3_ip4_start (self); + /* Restart IP configuration if we're waiting for slaves. Do this + * after updating the hardware address as IP config may need the + * new address. + */ + if (success) { + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_WAIT) + nm_device_activate_stage3_ip4_start(self); - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_WAIT) - nm_device_activate_stage3_ip6_start (self); - } + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_WAIT) + nm_device_activate_stage3_ip6_start(self); + } - /* Since slave devices don't have their own IP configuration, - * set the MTU here. - */ - _commit_mtu (slave, NM_DEVICE_GET_PRIVATE (slave)->ip_config_4); + /* Since slave devices don't have their own IP configuration, + * set the MTU here. + */ + _commit_mtu(slave, NM_DEVICE_GET_PRIVATE(slave)->ip_config_4); - return success; + return success; } /** @@ -3747,6 +4670,8 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c * @self: the master device * @slave: the slave device to release * @configure: whether @self needs to actually release @slave + * @force: force the release of @slave even if it wasn't added + * to @master by NetworkManager * @reason: the state change reason for the @slave * * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, @@ -3754,60 +4679,72 @@ nm_device_master_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *c * updates the state of @self and @slave to reflect its release. */ static void -nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason) -{ - NMDevicePrivate *priv; - NMDevicePrivate *slave_priv; - SlaveInfo *info; - gs_unref_object NMDevice *self_free = NULL; - - g_return_if_fail (NM_DEVICE (self)); - g_return_if_fail (NM_DEVICE (slave)); - g_return_if_fail (NM_DEVICE_GET_CLASS (self)->release_slave != NULL); - - info = find_slave_info (self, slave); - - _LOGT (LOGD_CORE, "master: release one slave %p/%s%s", slave, nm_device_get_iface (slave), - !info ? " (not registered)" : ""); - - if (!info) - g_return_if_reached (); - - priv = NM_DEVICE_GET_PRIVATE (self); - slave_priv = NM_DEVICE_GET_PRIVATE (slave); - - g_return_if_fail (self == slave_priv->master); - nm_assert (slave == info->slave); - - /* first, let subclasses handle the release ... */ - if (info->slave_is_enslaved) - NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure); - - /* raise notifications about the release, including clearing is_enslaved. */ - nm_device_slave_notify_release (slave, reason); - - /* keep both alive until the end of the function. - * Transfers ownership from slave_priv->master. */ - self_free = self; - - c_list_unlink (&info->lst_slave); - slave_priv->master = NULL; - - g_signal_handler_disconnect (slave, info->watch_id); - g_object_unref (slave); - g_slice_free (SlaveInfo, info); - - if (c_list_is_empty (&priv->slaves)) { - _active_connection_set_state_flags_full (self, - 0, - NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES); - } - - /* Ensure the device's hardware address is up-to-date; it often changes - * when slaves change. - */ - nm_device_update_hw_address (self); - nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, NM_UNMAN_FLAG_OP_FORGET, NM_DEVICE_STATE_REASON_REMOVED); +nm_device_master_release_one_slave(NMDevice * self, + NMDevice * slave, + gboolean configure, + gboolean force, + NMDeviceStateReason reason) +{ + NMDevicePrivate *priv; + NMDevicePrivate *slave_priv; + SlaveInfo * info; + gs_unref_object NMDevice *self_free = NULL; + + g_return_if_fail(NM_DEVICE(self)); + g_return_if_fail(NM_DEVICE(slave)); + g_return_if_fail(!force || configure); + g_return_if_fail(NM_DEVICE_GET_CLASS(self)->release_slave != NULL); + + info = find_slave_info(self, slave); + + _LOGT(LOGD_CORE, + "master: release one slave %p/%s %s%s", + slave, + nm_device_get_iface(slave), + !info ? "(not registered)" : (info->slave_is_enslaved ? "(enslaved)" : "(not enslaved)"), + force ? " (force-configure)" : (configure ? " (configure)" : "")); + + if (!info) + g_return_if_reached(); + + priv = NM_DEVICE_GET_PRIVATE(self); + slave_priv = NM_DEVICE_GET_PRIVATE(slave); + + g_return_if_fail(self == slave_priv->master); + nm_assert(slave == info->slave); + + /* first, let subclasses handle the release ... */ + if (info->slave_is_enslaved || force) + NM_DEVICE_GET_CLASS(self)->release_slave(self, slave, configure); + + /* raise notifications about the release, including clearing is_enslaved. */ + nm_device_slave_notify_release(slave, reason); + + /* keep both alive until the end of the function. + * Transfers ownership from slave_priv->master. */ + self_free = self; + + c_list_unlink(&info->lst_slave); + slave_priv->master = NULL; + + g_signal_handler_disconnect(slave, info->watch_id); + g_object_unref(slave); + g_slice_free(SlaveInfo, info); + + if (c_list_is_empty(&priv->slaves)) { + _active_connection_set_state_flags_full(self, + 0, + NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES); + } + + /* Ensure the device's hardware address is up-to-date; it often changes + * when slaves change. + */ + nm_device_update_hw_address(self); + nm_device_set_unmanaged_by_flags(slave, + NM_UNMANAGED_IS_SLAVE, + NM_UNMAN_FLAG_OP_FORGET, + NM_DEVICE_STATE_REASON_REMOVED); } /** @@ -3818,736 +4755,761 @@ nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean co * IFF_UP-ed externally. */ static gboolean -can_unmanaged_external_down (NMDevice *self) +can_unmanaged_external_down(NMDevice *self) { - return !NM_DEVICE_GET_PRIVATE (self)->nm_owned - && nm_device_is_software (self); + return !NM_DEVICE_GET_PRIVATE(self)->nm_owned && nm_device_is_software(self); } static NMUnmanFlagOp -is_unmanaged_external_down (NMDevice *self, gboolean consider_can) +is_unmanaged_external_down(NMDevice *self, gboolean consider_can) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( consider_can - && !NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self)) - return NM_UNMAN_FLAG_OP_FORGET; + if (consider_can && !NM_DEVICE_GET_CLASS(self)->can_unmanaged_external_down(self)) + return NM_UNMAN_FLAG_OP_FORGET; - /* Manage externally-created software interfaces only when they are IFF_UP */ - if ( priv->ifindex <= 0 - || !priv->up - || !( !c_list_is_empty (&priv->slaves) - || nm_platform_link_can_assume (nm_device_get_platform (self), priv->ifindex))) - return NM_UNMAN_FLAG_OP_SET_UNMANAGED; + /* Manage externally-created software interfaces only when they are IFF_UP */ + if (priv->ifindex <= 0 || !priv->up + || !(!c_list_is_empty(&priv->slaves) + || nm_platform_link_can_assume(nm_device_get_platform(self), priv->ifindex))) + return NM_UNMAN_FLAG_OP_SET_UNMANAGED; - return NM_UNMAN_FLAG_OP_SET_MANAGED; + return NM_UNMAN_FLAG_OP_SET_MANAGED; } static void -set_unmanaged_external_down (NMDevice *self, gboolean only_if_unmanaged) +set_unmanaged_external_down(NMDevice *self, gboolean only_if_unmanaged) { - NMUnmanFlagOp ext_flags; + NMUnmanFlagOp ext_flags; - if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)) - return; + if (!nm_device_get_unmanaged_mask(self, NM_UNMANAGED_EXTERNAL_DOWN)) + return; - if (only_if_unmanaged) { - if (!nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) - return; - } + if (only_if_unmanaged) { + if (!nm_device_get_unmanaged_flags(self, NM_UNMANAGED_EXTERNAL_DOWN)) + return; + } - ext_flags = is_unmanaged_external_down (self, FALSE); - if (ext_flags != NM_UNMAN_FLAG_OP_SET_UNMANAGED) { - /* Ensure the assume check is queued before any queued state changes - * from the transition to UNAVAILABLE. - */ - nm_device_queue_recheck_assume (self); - } + ext_flags = is_unmanaged_external_down(self, FALSE); + if (ext_flags != NM_UNMAN_FLAG_OP_SET_UNMANAGED) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume(self); + } - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_EXTERNAL_DOWN, - ext_flags, - NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_EXTERNAL_DOWN, + ext_flags, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); } void -nm_device_update_dynamic_ip_setup (NMDevice *self) -{ - NMDevicePrivate *priv; - GError *error = NULL; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if ( priv->state < NM_DEVICE_STATE_IP_CONFIG - || priv->state > NM_DEVICE_STATE_ACTIVATED) - return; - - g_hash_table_remove_all (priv->ip6_saved_properties); - - if (priv->dhcp_data_4.client) { - if (!nm_device_dhcp4_renew (self, FALSE)) { - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DHCP_FAILED); - return; - } - } - if (priv->dhcp_data_6.client) { - if (!nm_device_dhcp6_renew (self, FALSE)) { - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DHCP_FAILED); - return; - } - } - if (priv->ndisc) { - /* FIXME: todo */ - } - if (priv->dnsmasq_manager) { - /* FIXME: todo */ - } - - if ( priv->lldp_listener - && nm_lldp_listener_is_running (priv->lldp_listener)) { - nm_lldp_listener_stop (priv->lldp_listener); - if (!nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error)) { - _LOGD (LOGD_DEVICE, "LLDP listener %p could not be restarted: %s", - priv->lldp_listener, error->message); - g_clear_error (&error); - } - } +nm_device_update_dynamic_ip_setup(NMDevice *self) +{ + NMDevicePrivate *priv; + GError * error = NULL; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->state < NM_DEVICE_STATE_IP_CONFIG || priv->state > NM_DEVICE_STATE_ACTIVATED) + return; + + g_hash_table_remove_all(priv->ip6_saved_properties); + + if (priv->dhcp_data_4.client) { + if (!nm_device_dhcp4_renew(self, FALSE)) { + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DHCP_FAILED); + return; + } + } + if (priv->dhcp_data_6.client) { + if (!nm_device_dhcp6_renew(self, FALSE)) { + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DHCP_FAILED); + return; + } + } + if (priv->ndisc) { + /* FIXME: todo */ + } + if (priv->dnsmasq_manager) { + /* FIXME: todo */ + } + + if (priv->lldp_listener && nm_lldp_listener_is_running(priv->lldp_listener)) { + nm_lldp_listener_stop(priv->lldp_listener); + if (!nm_lldp_listener_start(priv->lldp_listener, nm_device_get_ifindex(self), &error)) { + _LOGD(LOGD_DEVICE, + "LLDP listener %p could not be restarted: %s", + priv->lldp_listener, + error->message); + g_clear_error(&error); + } + } } /*****************************************************************************/ static void -carrier_changed_notify (NMDevice *self, gboolean carrier) +carrier_changed_notify(NMDevice *self, gboolean carrier) { - /* stub */ + /* stub */ } static void -carrier_changed (NMDevice *self, gboolean carrier) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->state <= NM_DEVICE_STATE_UNMANAGED) - return; - - nm_device_recheck_available_connections (self); - - /* ignore-carrier devices ignore all carrier-down events */ - if (priv->ignore_carrier && !carrier) - return; - - if (nm_device_is_master (self)) { - if (carrier) { - /* Force master to retry getting ip addresses when carrier - * is restored. */ - if (priv->state == NM_DEVICE_STATE_ACTIVATED) - nm_device_update_dynamic_ip_setup (self); - /* If needed, also resume IP configuration that is - * waiting for carrier. */ - if (nm_device_activate_ip4_state_in_wait (self)) - nm_device_activate_stage3_ip4_start (self); - if (nm_device_activate_ip6_state_in_wait (self)) - nm_device_activate_stage3_ip6_start (self); - return; - } - /* fall-through and change state of device */ - } else if (priv->is_enslaved && !carrier) { - /* Slaves don't deactivate when they lose carrier; for - * bonds/teams in particular that would be actively - * counterproductive. - */ - return; - } - - if (carrier) { - if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_CARRIER); - } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { - /* If the device is already in DISCONNECTED state without a carrier - * (probably because it is tagged for carrier ignore) ensure that - * when the carrier appears, auto connections are rechecked for - * the device. - */ - nm_device_emit_recheck_auto_activate (self); - } else if (priv->state == NM_DEVICE_STATE_ACTIVATED) { - /* If the device is active without a carrier (probably because it is - * tagged for carrier ignore) ensure that when the carrier appears we - * renew DHCP leases and such. - */ - nm_device_update_dynamic_ip_setup (self); - } - } else { - if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - if ( priv->queued_state.id - && priv->queued_state.state >= NM_DEVICE_STATE_DISCONNECTED) - queued_state_clear (self); - } else { - nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_CARRIER); - } - } +carrier_changed(NMDevice *self, gboolean carrier) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->state <= NM_DEVICE_STATE_UNMANAGED) + return; + + nm_device_recheck_available_connections(self); + + /* ignore-carrier devices ignore all carrier-down events */ + if (priv->ignore_carrier && !carrier) + return; + + if (nm_device_is_master(self)) { + if (carrier) { + /* Force master to retry getting ip addresses when carrier + * is restored. */ + if (priv->state == NM_DEVICE_STATE_ACTIVATED) + nm_device_update_dynamic_ip_setup(self); + /* If needed, also resume IP configuration that is + * waiting for carrier. */ + if (nm_device_activate_ip4_state_in_wait(self)) + nm_device_activate_stage3_ip4_start(self); + if (nm_device_activate_ip6_state_in_wait(self)) + nm_device_activate_stage3_ip6_start(self); + return; + } + /* fall-through and change state of device */ + } else if (priv->is_enslaved && !carrier) { + /* Slaves don't deactivate when they lose carrier; for + * bonds/teams in particular that would be actively + * counterproductive. + */ + return; + } + + if (carrier) { + if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { + nm_device_queue_state(self, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_CARRIER); + } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { + /* If the device is already in DISCONNECTED state without a carrier + * (probably because it is tagged for carrier ignore) ensure that + * when the carrier appears, auto connections are rechecked for + * the device. + */ + nm_device_emit_recheck_auto_activate(self); + } else if (priv->state == NM_DEVICE_STATE_ACTIVATED) { + /* If the device is active without a carrier (probably because it is + * tagged for carrier ignore) ensure that when the carrier appears we + * renew DHCP leases and such. + */ + nm_device_update_dynamic_ip_setup(self); + } + } else { + if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { + if (priv->queued_state.id && priv->queued_state.state >= NM_DEVICE_STATE_DISCONNECTED) + queued_state_clear(self); + } else { + nm_device_queue_state(self, + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_CARRIER); + } + } } static gboolean -carrier_disconnected_action_cb (gpointer user_data) +carrier_disconnected_action_cb(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - _LOGD (LOGD_DEVICE, "carrier: link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id); + _LOGD(LOGD_DEVICE, + "carrier: link disconnected (calling deferred action) (id=%u)", + priv->carrier_defer_id); - priv->carrier_defer_id = 0; - carrier_changed (self, FALSE); - return FALSE; + priv->carrier_defer_id = 0; + carrier_changed(self, FALSE); + return FALSE; } static void -carrier_disconnected_action_cancel (NMDevice *self) +carrier_disconnected_action_cancel(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - guint id = priv->carrier_defer_id; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + guint id = priv->carrier_defer_id; - if (nm_clear_g_source (&priv->carrier_defer_id)) { - _LOGD (LOGD_DEVICE, "carrier: link disconnected (canceling deferred action) (id=%u)", - id); - } + if (nm_clear_g_source(&priv->carrier_defer_id)) { + _LOGD(LOGD_DEVICE, "carrier: link disconnected (canceling deferred action) (id=%u)", id); + } } void -nm_device_set_carrier (NMDevice *self, gboolean carrier) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceState state = nm_device_get_state (self); - gboolean notify_flags = FALSE; - - if (priv->carrier == carrier) - return; - - if (NM_FLAGS_ALL (priv->capabilities, - NM_DEVICE_CAP_CARRIER_DETECT - | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { - if (carrier) - priv->interface_flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; - else - priv->interface_flags &= ~NM_DEVICE_INTERFACE_FLAG_CARRIER; - notify_flags = TRUE; - } - - priv->carrier = carrier; - if (notify_flags) - nm_gobject_notify_together (self, PROP_CARRIER, PROP_INTERFACE_FLAGS); - else - _notify (self, PROP_CARRIER); - - if (priv->carrier) { - _LOGI (LOGD_DEVICE, "carrier: link connected"); - carrier_disconnected_action_cancel (self); - NM_DEVICE_GET_CLASS (self)->carrier_changed_notify (self, carrier); - carrier_changed (self, TRUE); - - if (priv->carrier_wait_id) { - nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); - _carrier_wait_check_queued_act_request (self); - } - } else { - if (priv->carrier_wait_id) - nm_device_add_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); - NM_DEVICE_GET_CLASS (self)->carrier_changed_notify (self, carrier); - if ( state <= NM_DEVICE_STATE_DISCONNECTED - && !priv->queued_act_request) { - _LOGD (LOGD_DEVICE, "carrier: link disconnected"); - carrier_changed (self, FALSE); - } else { - gint64 now_ms, until_ms; - - now_ms = nm_utils_get_monotonic_timestamp_msec (); - until_ms = NM_MAX (now_ms + _get_carrier_wait_ms (self), priv->carrier_wait_until_ms); - priv->carrier_defer_id = g_timeout_add (until_ms - now_ms, carrier_disconnected_action_cb, self); - _LOGD (LOGD_DEVICE, "carrier: link disconnected (deferring action for %ld milliseconds) (id=%u)", - (long) (until_ms - now_ms), priv->carrier_defer_id); - } - } +nm_device_set_carrier(NMDevice *self, gboolean carrier) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceState state = nm_device_get_state(self); + gboolean notify_flags = FALSE; + + if (priv->carrier == carrier) + return; + + if (NM_FLAGS_ALL(priv->capabilities, + NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { + if (carrier) + priv->interface_flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; + else + priv->interface_flags &= ~NM_DEVICE_INTERFACE_FLAG_CARRIER; + notify_flags = TRUE; + } + + priv->carrier = carrier; + if (notify_flags) + nm_gobject_notify_together(self, PROP_CARRIER, PROP_INTERFACE_FLAGS); + else + _notify(self, PROP_CARRIER); + + if (priv->carrier) { + _LOGI(LOGD_DEVICE, "carrier: link connected"); + carrier_disconnected_action_cancel(self); + NM_DEVICE_GET_CLASS(self)->carrier_changed_notify(self, carrier); + carrier_changed(self, TRUE); + + if (priv->carrier_wait_id) { + nm_device_remove_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); + _carrier_wait_check_queued_act_request(self); + } + } else { + if (priv->carrier_wait_id) + nm_device_add_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); + NM_DEVICE_GET_CLASS(self)->carrier_changed_notify(self, carrier); + if (state <= NM_DEVICE_STATE_DISCONNECTED && !priv->queued_act_request) { + _LOGD(LOGD_DEVICE, "carrier: link disconnected"); + carrier_changed(self, FALSE); + } else { + gint64 now_ms, until_ms; + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + until_ms = NM_MAX(now_ms + _get_carrier_wait_ms(self), priv->carrier_wait_until_ms); + priv->carrier_defer_id = + g_timeout_add(until_ms - now_ms, carrier_disconnected_action_cb, self); + _LOGD(LOGD_DEVICE, + "carrier: link disconnected (deferring action for %ld milliseconds) (id=%u)", + (long) (until_ms - now_ms), + priv->carrier_defer_id); + } + } } static void -nm_device_set_carrier_from_platform (NMDevice *self) +nm_device_set_carrier_from_platform(NMDevice *self) { - int ifindex; + int ifindex; - if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - if ( !nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER) - && (ifindex = nm_device_get_ip_ifindex (self)) > 0) { - nm_device_set_carrier (self, - nm_platform_link_is_connected (nm_device_get_platform (self), - ifindex)); - } - } else { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + if (nm_device_has_capability(self, NM_DEVICE_CAP_CARRIER_DETECT)) { + if (!nm_device_has_capability(self, NM_DEVICE_CAP_NONSTANDARD_CARRIER) + && (ifindex = nm_device_get_ip_ifindex(self)) > 0) { + nm_device_set_carrier( + self, + nm_platform_link_is_connected(nm_device_get_platform(self), ifindex)); + } + } else { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - /* Fake online link when carrier detection is not available. */ - if (!priv->carrier) { - priv->carrier = TRUE; - _notify (self, PROP_CARRIER); - } - } + /* Fake online link when carrier detection is not available. */ + if (!priv->carrier) { + priv->carrier = TRUE; + _notify(self, PROP_CARRIER); + } + } } /*****************************************************************************/ static void -device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDevice *master; - nm_auto_nmpobj const NMPObject *plink_master_keep_alive = NULL; - const NMPlatformLink *plink_master; - - g_return_if_fail (plink); - - if (plink->master <= 0) - return; - - master = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, plink->master); - plink_master = nm_platform_link_get (nm_device_get_platform (self), plink->master); - plink_master_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink_master)); - - if ( master == NULL - && plink_master - && g_strcmp0 (plink_master->name, "ovs-system") == 0 - && plink_master->type == NM_LINK_TYPE_OPENVSWITCH) { - _LOGD (LOGD_DEVICE, "the device claimed by openvswitch"); - return; - } - - if (priv->master) { - if ( plink->master > 0 - && plink->master == nm_device_get_ifindex (priv->master)) { - /* call add-slave again. We expect @self already to be added to - * the master, but this also triggers a recheck-assume. */ - nm_device_master_add_slave (priv->master, self, FALSE); - return; - } - - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - } - - if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) - nm_device_master_add_slave (master, self, FALSE); - else if (master) { - _LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring", - nm_device_get_iface (master)); - } else { - _LOGW (LOGD_DEVICE, "enslaved to unknown device %d (%s%s%s)", - plink->master, - NM_PRINT_FMT_QUOTED (plink_master, "\"", plink_master->name, "\"", "??")); - } +device_recheck_slave_status(NMDevice *self, const NMPlatformLink *plink) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDevice * master; + nm_auto_nmpobj const NMPObject *plink_master_keep_alive = NULL; + const NMPlatformLink * plink_master; + + g_return_if_fail(plink); + + if (plink->master <= 0) + return; + + master = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, plink->master); + plink_master = nm_platform_link_get(nm_device_get_platform(self), plink->master); + plink_master_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(plink_master)); + + if (master == NULL && plink_master && nm_streq0(plink_master->name, "ovs-system") + && plink_master->type == NM_LINK_TYPE_OPENVSWITCH) { + _LOGD(LOGD_DEVICE, "the device claimed by openvswitch"); + return; + } + + if (priv->master) { + if (plink->master > 0 && plink->master == nm_device_get_ifindex(priv->master)) { + /* call add-slave again. We expect @self already to be added to + * the master, but this also triggers a recheck-assume. */ + nm_device_master_add_slave(priv->master, self, FALSE); + return; + } + + nm_device_master_release_one_slave(priv->master, + self, + FALSE, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } + + if (master && NM_DEVICE_GET_CLASS(master)->enslave_slave) + nm_device_master_add_slave(master, self, FALSE); + else if (master) { + _LOGI(LOGD_DEVICE, + "enslaved to non-master-type device %s; ignoring", + nm_device_get_iface(master)); + } else { + _LOGW(LOGD_DEVICE, + "enslaved to unknown device %d (%s%s%s)", + plink->master, + NM_PRINT_FMT_QUOTED(plink_master, "\"", plink_master->name, "\"", "??")); + } } static void -ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gint32 now; - GArray *addresses, *dns_servers, *dns_domains; - guint len, i; - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter ipconf_iter; - - if (nm_ndisc_get_node_type (ndisc) != NM_NDISC_NODE_TYPE_ROUTER) - return; - - now = nm_utils_get_monotonic_timestamp_sec (); - - head_entry = nm_ip6_config_lookup_addresses (priv->ip_config_6); - addresses = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscAddress), - head_entry ? head_entry->len : 0); - nm_dedup_multi_iter_for_each (&ipconf_iter, head_entry) { - const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS (ipconf_iter.current->obj); - NMNDiscAddress *ndisc_addr; - guint32 lifetime, preferred; - gint32 base; - - if ( IN6_IS_ADDR_UNSPECIFIED (&addr->address) - || IN6_IS_ADDR_LINKLOCAL (&addr->address)) - continue; - - if ( addr->n_ifa_flags & IFA_F_TENTATIVE - || addr->n_ifa_flags & IFA_F_DADFAILED) - continue; - - if (addr->plen != 64) - continue; - - /* resolve the timestamps relative to a new base. - * - * Note that for convenience, platform @addr might have timestamp and/or - * lifetime unset. We don't allow that flexibility for ndisc and require - * well defined timestamps. */ - if (addr->timestamp) { - nm_assert (addr->timestamp < G_MAXINT32); - base = addr->timestamp; - } else - base = now; - - lifetime = nm_utils_lifetime_get (addr->timestamp, addr->lifetime, addr->preferred, - base, &preferred); - if (!lifetime) - continue; - - g_array_set_size (addresses, addresses->len+1); - ndisc_addr = &g_array_index (addresses, NMNDiscAddress, addresses->len-1); - ndisc_addr->address = addr->address; - ndisc_addr->timestamp = base; - ndisc_addr->lifetime = lifetime; - ndisc_addr->preferred = preferred; - } - - len = nm_ip6_config_get_num_nameservers (priv->ip_config_6); - dns_servers = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscDNSServer), len); - g_array_set_size (dns_servers, len); - for (i = 0; i < len; i++) { - const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (priv->ip_config_6, i); - NMNDiscDNSServer *ndisc_nameserver; - - ndisc_nameserver = &g_array_index (dns_servers, NMNDiscDNSServer, i); - ndisc_nameserver->address = *nameserver; - ndisc_nameserver->timestamp = now; - ndisc_nameserver->lifetime = NM_NDISC_ROUTER_LIFETIME; - } - - len = nm_ip6_config_get_num_searches (priv->ip_config_6); - dns_domains = g_array_sized_new (FALSE, TRUE, sizeof (NMNDiscDNSDomain), len); - g_array_set_size (dns_domains, len); - for (i = 0; i < len; i++) { - const char *search = nm_ip6_config_get_search (priv->ip_config_6, i); - NMNDiscDNSDomain *ndisc_search; - - ndisc_search = &g_array_index (dns_domains, NMNDiscDNSDomain, i); - ndisc_search->domain = (char *) search; - ndisc_search->timestamp = now; - ndisc_search->lifetime = NM_NDISC_ROUTER_LIFETIME; - } - - nm_ndisc_set_config (ndisc, addresses, dns_servers, dns_domains); - g_array_unref (addresses); - g_array_unref (dns_servers); - g_array_unref (dns_domains); +ndisc_set_router_config(NMNDisc *ndisc, NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gint32 now; + GArray * addresses, *dns_servers, *dns_domains; + guint len, i; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter ipconf_iter; + + if (nm_ndisc_get_node_type(ndisc) != NM_NDISC_NODE_TYPE_ROUTER) + return; + + now = nm_utils_get_monotonic_timestamp_sec(); + + head_entry = nm_ip6_config_lookup_addresses(priv->ip_config_6); + addresses = + g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscAddress), head_entry ? head_entry->len : 0); + nm_dedup_multi_iter_for_each (&ipconf_iter, head_entry) { + const NMPlatformIP6Address *addr = NMP_OBJECT_CAST_IP6_ADDRESS(ipconf_iter.current->obj); + NMNDiscAddress * ndisc_addr; + guint32 lifetime, preferred; + gint32 base; + + if (IN6_IS_ADDR_UNSPECIFIED(&addr->address) || IN6_IS_ADDR_LINKLOCAL(&addr->address)) + continue; + + if (addr->n_ifa_flags & IFA_F_TENTATIVE || addr->n_ifa_flags & IFA_F_DADFAILED) + continue; + + if (addr->plen != 64) + continue; + + /* resolve the timestamps relative to a new base. + * + * Note that for convenience, platform @addr might have timestamp and/or + * lifetime unset. We don't allow that flexibility for ndisc and require + * well defined timestamps. */ + if (addr->timestamp) { + nm_assert(addr->timestamp < G_MAXINT32); + base = addr->timestamp; + } else + base = now; + + lifetime = nm_utils_lifetime_get(addr->timestamp, + addr->lifetime, + addr->preferred, + base, + &preferred); + if (!lifetime) + continue; + + g_array_set_size(addresses, addresses->len + 1); + ndisc_addr = &g_array_index(addresses, NMNDiscAddress, addresses->len - 1); + ndisc_addr->address = addr->address; + ndisc_addr->timestamp = base; + ndisc_addr->lifetime = lifetime; + ndisc_addr->preferred = preferred; + } + + len = nm_ip6_config_get_num_nameservers(priv->ip_config_6); + dns_servers = g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscDNSServer), len); + g_array_set_size(dns_servers, len); + for (i = 0; i < len; i++) { + const struct in6_addr *nameserver = nm_ip6_config_get_nameserver(priv->ip_config_6, i); + NMNDiscDNSServer * ndisc_nameserver; + + ndisc_nameserver = &g_array_index(dns_servers, NMNDiscDNSServer, i); + ndisc_nameserver->address = *nameserver; + ndisc_nameserver->timestamp = now; + ndisc_nameserver->lifetime = NM_NDISC_ROUTER_LIFETIME; + } + + len = nm_ip6_config_get_num_searches(priv->ip_config_6); + dns_domains = g_array_sized_new(FALSE, TRUE, sizeof(NMNDiscDNSDomain), len); + g_array_set_size(dns_domains, len); + for (i = 0; i < len; i++) { + const char * search = nm_ip6_config_get_search(priv->ip_config_6, i); + NMNDiscDNSDomain *ndisc_search; + + ndisc_search = &g_array_index(dns_domains, NMNDiscDNSDomain, i); + ndisc_search->domain = (char *) search; + ndisc_search->timestamp = now; + ndisc_search->lifetime = NM_NDISC_ROUTER_LIFETIME; + } + + nm_ndisc_set_config(ndisc, addresses, dns_servers, dns_domains); + g_array_unref(addresses); + g_array_unref(dns_servers); + g_array_unref(dns_domains); } static void -device_update_interface_flags (NMDevice *self, const NMPlatformLink *plink) +device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceInterfaceFlags flags = NM_DEVICE_INTERFACE_FLAG_NONE; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceInterfaceFlags flags = NM_DEVICE_INTERFACE_FLAG_NONE; - if (plink && NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP)) - flags |= NM_DEVICE_INTERFACE_FLAG_UP; - if (plink && NM_FLAGS_HAS (plink->n_ifi_flags, IFF_LOWER_UP)) - flags |= NM_DEVICE_INTERFACE_FLAG_LOWER_UP; + if (plink && NM_FLAGS_HAS(plink->n_ifi_flags, IFF_UP)) + flags |= NM_DEVICE_INTERFACE_FLAG_UP; + if (plink && NM_FLAGS_HAS(plink->n_ifi_flags, IFF_LOWER_UP)) + flags |= NM_DEVICE_INTERFACE_FLAG_LOWER_UP; - if (NM_FLAGS_ALL (priv->capabilities, - NM_DEVICE_CAP_CARRIER_DETECT - | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { - if (priv->carrier) - flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; - } else { - if (plink && NM_FLAGS_HAS (plink->n_ifi_flags, IFF_LOWER_UP)) - flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; - } + if (NM_FLAGS_ALL(priv->capabilities, + NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { + if (priv->carrier) + flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; + } else { + if (plink && NM_FLAGS_HAS(plink->n_ifi_flags, IFF_LOWER_UP)) + flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; + } - if (flags != priv->interface_flags) { - priv->interface_flags = flags; - _notify (self, PROP_INTERFACE_FLAGS); - } + if (flags != priv->interface_flags) { + priv->interface_flags = flags; + _notify(self, PROP_INTERFACE_FLAGS); + } } static gboolean -device_link_changed (NMDevice *self) -{ - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean ip_ifname_changed = FALSE; - nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL; - const NMPlatformLink *pllink; - const char *str; - int ifindex; - gboolean was_up; - gboolean update_unmanaged_specs = FALSE; - gboolean got_hw_addr = FALSE, had_hw_addr; - gboolean seen_down = priv->device_link_changed_down; - - priv->device_link_changed_id = 0; - priv->device_link_changed_down = FALSE; - - ifindex = nm_device_get_ifindex (self); - if (ifindex <= 0) - return G_SOURCE_REMOVE; - pllink = nm_platform_link_get (nm_device_get_platform (self), ifindex); - if (!pllink) - return G_SOURCE_REMOVE; - - pllink_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (pllink)); - - str = nm_platform_link_get_udi (nm_device_get_platform (self), pllink->ifindex); - if (!nm_streq0 (str, priv->udi)) { - g_free (priv->udi); - priv->udi = g_strdup (str); - _notify (self, PROP_UDI); - } - - str = nm_platform_link_get_path (nm_device_get_platform (self), pllink->ifindex); - if (!nm_streq0 (str, priv->path)) { - g_free (priv->path); - priv->path = g_strdup (str); - _notify (self, PROP_PATH); - } - - if (!nm_streq0 (pllink->driver, priv->driver)) { - g_free (priv->driver); - priv->driver = g_strdup (pllink->driver); - _notify (self, PROP_DRIVER); - } - - _set_mtu (self, pllink->mtu); - - if (ifindex == nm_device_get_ip_ifindex (self)) - _stats_update_counters_from_pllink (self, pllink); - - had_hw_addr = (priv->hw_addr != NULL); - nm_device_update_hw_address (self); - got_hw_addr = (!had_hw_addr && priv->hw_addr); - nm_device_update_permanent_hw_address (self, FALSE); - - if (pllink->name[0] && strcmp (priv->iface, pllink->name) != 0) { - _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'", - priv->ifindex, priv->iface, pllink->name); - g_free (priv->iface); - priv->iface = g_strdup (pllink->name); - - /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */ - ip_ifname_changed = !priv->ip_iface; - - if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) - nm_device_set_unmanaged_by_user_settings (self); - else - update_unmanaged_specs = TRUE; - - _notify (self, PROP_IFACE); - if (ip_ifname_changed) - _notify (self, PROP_IP_IFACE); - - /* Re-match available connections against the new interface name */ - nm_device_recheck_available_connections (self); - - /* Let any connections that use the new interface name have a chance - * to auto-activate on the device. - */ - nm_device_emit_recheck_auto_activate (self); - } - - if (priv->ndisc && pllink->inet6_token.id) { - if (nm_ndisc_set_iid (priv->ndisc, pllink->inet6_token)) - _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); - } - - /* Update carrier from link event if applicable. */ - if ( nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT) - && !nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) - nm_device_set_carrier (self, pllink->connected); - - device_update_interface_flags (self, pllink); - - klass->link_changed (self, pllink); - - /* Update DHCP, etc, if needed */ - if (ip_ifname_changed) - nm_device_update_dynamic_ip_setup (self); - - was_up = priv->up; - priv->up = NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP); - - if ( pllink->initialized - && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - NMDeviceStateReason reason; - - nm_device_set_unmanaged_by_user_udev (self); - nm_device_set_unmanaged_by_user_conf (self); - - reason = NM_DEVICE_STATE_REASON_NOW_MANAGED; - - /* If the device is a external-down candidated but no longer has external - * down set, we must clear the platform-unmanaged flag with reason - * "assumed". */ - if ( nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN) - && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) { - /* actually, user-udev overwrites external-down. So we only assume the device, - * when it is a external-down candidate, which is not managed via udev. */ - if (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_UDEV)) { - /* Ensure the assume check is queued before any queued state changes - * from the transition to UNAVAILABLE. - */ - nm_device_queue_recheck_assume (self); - reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; - } - } - - nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason); - } - - set_unmanaged_external_down (self, FALSE); - - device_recheck_slave_status (self, pllink); - - if (priv->up && (!was_up || seen_down)) { - /* the link was down and just came up. That happens for example, while changing MTU. - * We must restore IP configuration. */ - if (NM_IN_SET (priv->ip_state_4, NM_DEVICE_IP_STATE_CONF, - NM_DEVICE_IP_STATE_DONE)) { - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "failed applying IP4 config after link comes up again"); - } - - priv->linklocal6_dad_counter = 0; - if (NM_IN_SET (priv->ip_state_6, NM_DEVICE_IP_STATE_CONF, - NM_DEVICE_IP_STATE_DONE)) { - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "failed applying IP6 config after link comes up again"); - } - } - - if (update_unmanaged_specs) - nm_device_set_unmanaged_by_user_settings (self); - - if ( got_hw_addr - && !priv->up - && nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE) { - /* - * If the device is UNAVAILABLE, any previous try to - * bring it up probably has failed because of the - * invalid hardware address; try again. - */ - nm_device_bring_up (self, TRUE, NULL); - nm_device_queue_recheck_available (self, - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_NONE); - } - - return G_SOURCE_REMOVE; +device_link_changed(NMDevice *self) +{ + NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gboolean ip_ifname_changed = FALSE; + nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL; + const NMPlatformLink * pllink; + const char * str; + int ifindex; + gboolean was_up; + gboolean update_unmanaged_specs = FALSE; + gboolean got_hw_addr = FALSE, had_hw_addr; + gboolean seen_down = priv->device_link_changed_down; + + priv->device_link_changed_id = 0; + priv->device_link_changed_down = FALSE; + + ifindex = nm_device_get_ifindex(self); + if (ifindex <= 0) + return G_SOURCE_REMOVE; + pllink = nm_platform_link_get(nm_device_get_platform(self), ifindex); + if (!pllink) + return G_SOURCE_REMOVE; + + pllink_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(pllink)); + + str = nm_platform_link_get_udi(nm_device_get_platform(self), pllink->ifindex); + if (!nm_streq0(str, priv->udi)) { + g_free(priv->udi); + priv->udi = g_strdup(str); + _notify(self, PROP_UDI); + } + + str = nm_platform_link_get_path(nm_device_get_platform(self), pllink->ifindex); + if (!nm_streq0(str, priv->path)) { + g_free(priv->path); + priv->path = g_strdup(str); + _notify(self, PROP_PATH); + } + + if (!nm_streq0(pllink->driver, priv->driver)) { + g_free(priv->driver); + priv->driver = g_strdup(pllink->driver); + _notify(self, PROP_DRIVER); + } + + _set_mtu(self, pllink->mtu); + + if (ifindex == nm_device_get_ip_ifindex(self)) + _stats_update_counters_from_pllink(self, pllink); + + had_hw_addr = (priv->hw_addr != NULL); + nm_device_update_hw_address(self); + got_hw_addr = (!had_hw_addr && priv->hw_addr); + nm_device_update_permanent_hw_address(self, FALSE); + + if (pllink->name[0] && !nm_streq(priv->iface, pllink->name)) { + _LOGI(LOGD_DEVICE, + "interface index %d renamed iface from '%s' to '%s'", + priv->ifindex, + priv->iface, + pllink->name); + g_free(priv->iface_); + priv->iface_ = g_strdup(pllink->name); + + /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */ + ip_ifname_changed = !priv->ip_iface; + + if (nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) + nm_device_set_unmanaged_by_user_settings(self); + else + update_unmanaged_specs = TRUE; + + _notify(self, PROP_IFACE); + if (ip_ifname_changed) + _notify(self, PROP_IP_IFACE); + + /* Re-match available connections against the new interface name */ + nm_device_recheck_available_connections(self); + + /* Let any connections that use the new interface name have a chance + * to auto-activate on the device. + */ + nm_device_emit_recheck_auto_activate(self); + } + + if (priv->ndisc && pllink->inet6_token.id) { + if (nm_ndisc_set_iid(priv->ndisc, pllink->inet6_token)) + _LOGD(LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); + } + + /* Update carrier from link event if applicable. */ + if (nm_device_has_capability(self, NM_DEVICE_CAP_CARRIER_DETECT) + && !nm_device_has_capability(self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) + nm_device_set_carrier(self, pllink->connected); + + device_update_interface_flags(self, pllink); + + klass->link_changed(self, pllink); + + /* Update DHCP, etc, if needed */ + if (ip_ifname_changed) + nm_device_update_dynamic_ip_setup(self); + + was_up = priv->up; + priv->up = NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP); + + if (pllink->initialized && nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) { + NMDeviceStateReason reason; + + nm_device_set_unmanaged_by_user_udev(self); + nm_device_set_unmanaged_by_user_conf(self); + + reason = NM_DEVICE_STATE_REASON_NOW_MANAGED; + + /* If the device is a external-down candidated but no longer has external + * down set, we must clear the platform-unmanaged flag with reason + * "assumed". */ + if (nm_device_get_unmanaged_mask(self, NM_UNMANAGED_EXTERNAL_DOWN) + && !nm_device_get_unmanaged_flags(self, NM_UNMANAGED_EXTERNAL_DOWN)) { + /* actually, user-udev overwrites external-down. So we only assume the device, + * when it is a external-down candidate, which is not managed via udev. */ + if (!nm_device_get_unmanaged_mask(self, NM_UNMANAGED_USER_UDEV)) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume(self); + reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; + } + } + + nm_device_set_unmanaged_by_flags(self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason); + } + + set_unmanaged_external_down(self, FALSE); + + device_recheck_slave_status(self, pllink); + + if (priv->up && (!was_up || seen_down)) { + /* the link was down and just came up. That happens for example, while changing MTU. + * We must restore IP configuration. */ + if (NM_IN_SET(priv->ip_state_4, NM_DEVICE_IP_STATE_CONF, NM_DEVICE_IP_STATE_DONE)) { + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) + _LOGW(LOGD_IP4, "failed applying IP4 config after link comes up again"); + } + + priv->linklocal6_dad_counter = 0; + if (NM_IN_SET(priv->ip_state_6, NM_DEVICE_IP_STATE_CONF, NM_DEVICE_IP_STATE_DONE)) { + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed applying IP6 config after link comes up again"); + } + } + + if (update_unmanaged_specs) + nm_device_set_unmanaged_by_user_settings(self); + + if (got_hw_addr && !priv->up && nm_device_get_state(self) == NM_DEVICE_STATE_UNAVAILABLE) { + /* + * If the device is UNAVAILABLE, any previous try to + * bring it up probably has failed because of the + * invalid hardware address; try again. + */ + nm_device_bring_up(self, TRUE, NULL); + nm_device_queue_recheck_available(self, + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_NONE); + } + + return G_SOURCE_REMOVE; } static gboolean -device_ip_link_changed (NMDevice *self) +device_ip_link_changed(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformLink *pllink; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const NMPlatformLink *pllink; + const char * ip_iface; + + priv->device_ip_link_changed_id = 0; + + if (priv->ip_ifindex <= 0) + return G_SOURCE_REMOVE; + + nm_assert(priv->ip_iface); - priv->device_ip_link_changed_id = 0; + pllink = nm_platform_link_get(nm_device_get_platform(self), priv->ip_ifindex); + if (!pllink) + return G_SOURCE_REMOVE; - if (!priv->ip_ifindex) - return G_SOURCE_REMOVE; + if (priv->ifindex <= 0 && pllink->mtu) + _set_mtu(self, pllink->mtu); - pllink = nm_platform_link_get (nm_device_get_platform (self), priv->ip_ifindex); - if (!pllink) - return G_SOURCE_REMOVE; + _stats_update_counters_from_pllink(self, pllink); - if (priv->ifindex <= 0 && pllink->mtu) - _set_mtu (self, pllink->mtu); + ip_iface = pllink->name; - _stats_update_counters_from_pllink (self, pllink); + if (!ip_iface[0]) + return FALSE; - if (_ip_iface_update (self, pllink->name)) - nm_device_update_dynamic_ip_setup (self); + if (!nm_streq(priv->ip_iface, ip_iface)) { + _LOGI(LOGD_DEVICE, + "ip-ifname: interface index %d renamed ip_iface (%d) from '%s' to '%s'", + priv->ifindex, + priv->ip_ifindex, + priv->ip_iface, + ip_iface); + g_free(priv->ip_iface_); + priv->ip_iface_ = g_strdup(ip_iface); + _notify(self, PROP_IP_IFACE); - return G_SOURCE_REMOVE; + nm_device_update_dynamic_ip_setup(self); + } + + return G_SOURCE_REMOVE; } static void -link_changed_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *info, - int change_type_i, - NMDevice *self) -{ - const NMPlatformSignalChangeType change_type = change_type_i; - NMDevicePrivate *priv; - - if (change_type != NM_PLATFORM_SIGNAL_CHANGED) - return; - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (ifindex == nm_device_get_ifindex (self)) { - if (!(info->n_ifi_flags & IFF_UP)) - priv->device_link_changed_down = TRUE; - if (!priv->device_link_changed_id) { - priv->device_link_changed_id = g_idle_add ((GSourceFunc) device_link_changed, self); - _LOGD (LOGD_DEVICE, "queued link change for ifindex %d", ifindex); - } - } else if (ifindex == nm_device_get_ip_ifindex (self)) { - if (!priv->device_ip_link_changed_id) { - priv->device_ip_link_changed_id = g_idle_add ((GSourceFunc) device_ip_link_changed, self); - _LOGD (LOGD_DEVICE, "queued link change for ip-ifindex %d", ifindex); - } - } +link_changed_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *info, + int change_type_i, + NMDevice * self) +{ + const NMPlatformSignalChangeType change_type = change_type_i; + NMDevicePrivate * priv; + + if (change_type != NM_PLATFORM_SIGNAL_CHANGED) + return; + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (ifindex == nm_device_get_ifindex(self)) { + if (!(info->n_ifi_flags & IFF_UP)) + priv->device_link_changed_down = TRUE; + if (!priv->device_link_changed_id) { + priv->device_link_changed_id = g_idle_add((GSourceFunc) device_link_changed, self); + _LOGD(LOGD_DEVICE, "queued link change for ifindex %d", ifindex); + } + } else if (ifindex == nm_device_get_ip_ifindex(self)) { + if (!priv->device_ip_link_changed_id) { + priv->device_ip_link_changed_id = + g_idle_add((GSourceFunc) device_ip_link_changed, self); + _LOGD(LOGD_DEVICE, "queued link change for ip-ifindex %d", ifindex); + } + } } /*****************************************************************************/ static void -link_changed (NMDevice *self, const NMPlatformLink *pllink) +link_changed(NMDevice *self, const NMPlatformLink *pllink) { - /* stub implementation of virtual function to allow subclasses to chain up. */ + /* stub implementation of virtual function to allow subclasses to chain up. */ } static gboolean -link_type_compatible (NMDevice *self, - NMLinkType link_type, - gboolean *out_compatible, - GError **error) -{ - NMDeviceClass *klass; - NMLinkType device_type; - guint i = 0; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - klass = NM_DEVICE_GET_CLASS (self); - - if (!klass->link_types) { - NM_SET_OUT (out_compatible, FALSE); - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Device does not support platform links"); - return FALSE; - } - - device_type = self->_priv->link_type; - if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Needed link type 0x%x does not match the platform link type 0x%X", - device_type, link_type); - return FALSE; - } - - for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) { - if (klass->link_types[i] == link_type) - return TRUE; - if (klass->link_types[i] == NM_LINK_TYPE_ANY) - return TRUE; - } - - NM_SET_OUT (out_compatible, FALSE); - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Device does not support platform link type 0x%X", - link_type); - return FALSE; +link_type_compatible(NMDevice *self, NMLinkType link_type, gboolean *out_compatible, GError **error) +{ + NMDeviceClass *klass; + NMLinkType device_type; + guint i = 0; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + klass = NM_DEVICE_GET_CLASS(self); + + if (!klass->link_types) { + NM_SET_OUT(out_compatible, FALSE); + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Device does not support platform links"); + return FALSE; + } + + device_type = self->_priv->link_type; + if (device_type > NM_LINK_TYPE_UNKNOWN && device_type != link_type) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Needed link type 0x%x does not match the platform link type 0x%X", + device_type, + link_type); + return FALSE; + } + + for (i = 0; klass->link_types[i] > NM_LINK_TYPE_UNKNOWN; i++) { + if (klass->link_types[i] == link_type) + return TRUE; + if (klass->link_types[i] == NM_LINK_TYPE_ANY) + return TRUE; + } + + NM_SET_OUT(out_compatible, FALSE); + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Device does not support platform link type 0x%X", + link_type); + return FALSE; } /** @@ -4572,43 +5534,45 @@ link_type_compatible (NMDevice *self, * Returns: %TRUE on success, %FALSE on error */ gboolean -nm_device_realize_start (NMDevice *self, - const NMPlatformLink *plink, - gboolean assume_state_guess_assume, - const char *assume_state_connection_uuid, - gboolean set_nm_owned, - NMUnmanFlagOp unmanaged_user_explicit, - gboolean *out_compatible, - GError **error) -{ - nm_auto_nmpobj const NMPObject *plink_keep_alive = NULL; - - nm_assert (!plink || NMP_OBJECT_GET_TYPE (NMP_OBJECT_UP_CAST (plink)) == NMP_OBJECT_TYPE_LINK); - - NM_SET_OUT (out_compatible, TRUE); - - if (plink) { - if (g_strcmp0 (nm_device_get_iface (self), plink->name) != 0) { - NM_SET_OUT (out_compatible, FALSE); - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "Device interface name does not match platform link"); - return FALSE; - } - - if (!link_type_compatible (self, plink->type, out_compatible, error)) - return FALSE; - - plink_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink)); - } - - realize_start_setup (self, - plink, - assume_state_guess_assume, - assume_state_connection_uuid, - set_nm_owned, - unmanaged_user_explicit, - FALSE); - return TRUE; +nm_device_realize_start(NMDevice * self, + const NMPlatformLink *plink, + gboolean assume_state_guess_assume, + const char * assume_state_connection_uuid, + gboolean set_nm_owned, + NMUnmanFlagOp unmanaged_user_explicit, + gboolean * out_compatible, + GError ** error) +{ + nm_auto_nmpobj const NMPObject *plink_keep_alive = NULL; + + nm_assert(!plink || NMP_OBJECT_GET_TYPE(NMP_OBJECT_UP_CAST(plink)) == NMP_OBJECT_TYPE_LINK); + + NM_SET_OUT(out_compatible, TRUE); + + if (plink) { + if (!nm_streq0(nm_device_get_iface(self), plink->name)) { + NM_SET_OUT(out_compatible, FALSE); + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Device interface name does not match platform link"); + return FALSE; + } + + if (!link_type_compatible(self, plink->type, out_compatible, error)) + return FALSE; + + plink_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(plink)); + } + + realize_start_setup(self, + plink, + assume_state_guess_assume, + assume_state_connection_uuid, + set_nm_owned, + unmanaged_user_explicit, + FALSE); + return TRUE; } /** @@ -4624,277 +5588,267 @@ nm_device_realize_start (NMDevice *self, * Returns: %TRUE on success, %FALSE on error */ gboolean -nm_device_create_and_realize (NMDevice *self, - NMConnection *connection, - NMDevice *parent, - GError **error) -{ - nm_auto_nmpobj const NMPObject *plink_keep_alive = NULL; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformLink *plink; - gboolean nm_owned; - - /* Must be set before device is realized */ - plink = nm_platform_link_get_by_ifname (nm_device_get_platform (self), priv->iface); - nm_owned = !plink || !link_type_compatible (self, plink->type, NULL, NULL); - _LOGD (LOGD_DEVICE, "create (is %snm-owned)", nm_owned ? "" : "not "); - - plink = NULL; - /* Create any resources the device needs */ - if (NM_DEVICE_GET_CLASS (self)->create_and_realize) { - if (!NM_DEVICE_GET_CLASS (self)->create_and_realize (self, connection, parent, &plink, error)) - return FALSE; - if (plink) { - nm_assert (NMP_OBJECT_GET_TYPE (NMP_OBJECT_UP_CAST (plink)) == NMP_OBJECT_TYPE_LINK); - plink_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink)); - } - } - - priv->nm_owned = nm_owned; - - realize_start_setup (self, - plink, - FALSE, /* assume_state_guess_assume */ - NULL, /* assume_state_connection_uuid */ - FALSE, NM_UNMAN_FLAG_OP_FORGET, - TRUE); - nm_device_realize_finish (self, plink); - - if (nm_device_get_managed (self, FALSE)) { - nm_device_state_changed (self, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_NOW_MANAGED); - } - return TRUE; +nm_device_create_and_realize(NMDevice * self, + NMConnection *connection, + NMDevice * parent, + GError ** error) +{ + nm_auto_nmpobj const NMPObject *plink_keep_alive = NULL; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const NMPlatformLink * plink; + gboolean nm_owned; + + /* Must be set before device is realized */ + plink = nm_platform_link_get_by_ifname(nm_device_get_platform(self), priv->iface); + nm_owned = !plink || !link_type_compatible(self, plink->type, NULL, NULL); + _LOGD(LOGD_DEVICE, "create (is %snm-owned)", nm_owned ? "" : "not "); + + plink = NULL; + /* Create any resources the device needs */ + if (NM_DEVICE_GET_CLASS(self)->create_and_realize) { + if (!NM_DEVICE_GET_CLASS(self)->create_and_realize(self, connection, parent, &plink, error)) + return FALSE; + if (plink) { + nm_assert(NMP_OBJECT_GET_TYPE(NMP_OBJECT_UP_CAST(plink)) == NMP_OBJECT_TYPE_LINK); + plink_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(plink)); + } + } + + priv->nm_owned = nm_owned; + + realize_start_setup(self, + plink, + FALSE, /* assume_state_guess_assume */ + NULL, /* assume_state_connection_uuid */ + FALSE, + NM_UNMAN_FLAG_OP_FORGET, + TRUE); + nm_device_realize_finish(self, plink); + + if (nm_device_get_managed(self, FALSE)) { + nm_device_state_changed(self, + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_NOW_MANAGED); + } + return TRUE; } static gboolean -can_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) +can_update_from_platform_link(NMDevice *self, const NMPlatformLink *plink) { - return TRUE; + return TRUE; } void -nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *str; - int ifindex; - guint32 mtu; - - if (!NM_DEVICE_GET_CLASS (self)->can_update_from_platform_link (self, plink)) - return; - - g_return_if_fail (plink == NULL || link_type_compatible (self, plink->type, NULL, NULL)); - - str = plink ? nm_platform_link_get_udi (nm_device_get_platform (self), plink->ifindex) : NULL; - if (g_strcmp0 (str, priv->udi)) { - g_free (priv->udi); - priv->udi = g_strdup (str); - _notify (self, PROP_UDI); - } - - str = plink ? nm_platform_link_get_path (nm_device_get_platform (self), plink->ifindex) : NULL; - if (g_strcmp0 (str, priv->path)) { - g_free (priv->path); - priv->path = g_strdup (str); - _notify (self, PROP_PATH); - } - - str = plink ? plink->name : NULL; - if (str && g_strcmp0 (str, priv->iface)) { - g_free (priv->iface); - priv->iface = g_strdup (str); - _notify (self, PROP_IFACE); - } - - str = plink ? plink->driver : NULL; - if (g_strcmp0 (str, priv->driver) != 0) { - g_free (priv->driver); - priv->driver = g_strdup (str); - _notify (self, PROP_DRIVER); - } - - if (plink) { - priv->up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP); - if (plink->ifindex == nm_device_get_ip_ifindex (self)) - _stats_update_counters_from_pllink (self, plink); - } else { - priv->up = FALSE; - } - - mtu = plink ? plink->mtu : 0; - _set_mtu (self, mtu); - - ifindex = plink ? plink->ifindex : 0; - if (priv->ifindex != ifindex) { - priv->ifindex = ifindex; - _notify (self, PROP_IFINDEX); - NM_DEVICE_GET_CLASS (self)->link_changed (self, plink); - } - - device_update_interface_flags (self, plink); +nm_device_update_from_platform_link(NMDevice *self, const NMPlatformLink *plink) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const char * str; + gboolean ifindex_changed; + guint32 mtu; + + if (!NM_DEVICE_GET_CLASS(self)->can_update_from_platform_link(self, plink)) + return; + + g_return_if_fail(plink == NULL || link_type_compatible(self, plink->type, NULL, NULL)); + + str = plink ? nm_platform_link_get_udi(nm_device_get_platform(self), plink->ifindex) : NULL; + if (!nm_streq0(str, priv->udi)) { + g_free(priv->udi); + priv->udi = g_strdup(str); + _notify(self, PROP_UDI); + } + + str = plink ? nm_platform_link_get_path(nm_device_get_platform(self), plink->ifindex) : NULL; + if (!nm_streq0(str, priv->path)) { + g_free(priv->path); + priv->path = g_strdup(str); + _notify(self, PROP_PATH); + } + + if (plink && !nm_str_is_empty(plink->name) && nm_utils_strdup_reset(&priv->iface_, plink->name)) + _notify(self, PROP_IFACE); + + str = plink ? plink->driver : NULL; + if (!nm_streq0(str, priv->driver)) { + g_free(priv->driver); + priv->driver = g_strdup(str); + _notify(self, PROP_DRIVER); + } + + if (plink) { + priv->up = NM_FLAGS_HAS(plink->n_ifi_flags, IFF_UP); + if (plink->ifindex == nm_device_get_ip_ifindex(self)) + _stats_update_counters_from_pllink(self, plink); + } else { + priv->up = FALSE; + } + + mtu = plink ? plink->mtu : 0; + _set_mtu(self, mtu); + + ifindex_changed = _set_ifindex(self, plink ? plink->ifindex : 0, FALSE); + + if (ifindex_changed) + NM_DEVICE_GET_CLASS(self)->link_changed(self, plink); + + device_update_interface_flags(self, plink); } /*****************************************************************************/ static void -sriov_op_start (NMDevice *self, SriovOp *op) +sriov_op_start(NMDevice *self, SriovOp *op) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (!priv->sriov.pending); + nm_assert(!priv->sriov.pending); - op->cancellable = g_cancellable_new (); - op->device = g_object_ref (self); - priv->sriov.pending = op; + op->cancellable = g_cancellable_new(); + op->device = g_object_ref(self); + priv->sriov.pending = op; - nm_platform_link_set_sriov_params_async (nm_device_get_platform (self), - priv->ifindex, - op->num_vfs, - op->autoprobe, - sriov_op_cb, - op, - op->cancellable); + nm_platform_link_set_sriov_params_async(nm_device_get_platform(self), + priv->ifindex, + op->num_vfs, + op->autoprobe, + sriov_op_cb, + op, + op->cancellable); } static void -sriov_op_cb (GError *error, gpointer user_data) +sriov_op_cb(GError *error, gpointer user_data) { - SriovOp *op = user_data; - gs_unref_object NMDevice *self = op->device; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + SriovOp * op = user_data; + gs_unref_object NMDevice *self = op->device; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (op == priv->sriov.pending); + nm_assert(op == priv->sriov.pending); - g_clear_object (&op->cancellable); + g_clear_object(&op->cancellable); - if (op->callback) - op->callback (error, op->callback_data); + if (op->callback) + op->callback(error, op->callback_data); - priv->sriov.pending = NULL; - nm_g_slice_free (op); + priv->sriov.pending = NULL; + nm_g_slice_free(op); - if (priv->sriov.next) { - sriov_op_start (self, - g_steal_pointer (&priv->sriov.next)); - } + if (priv->sriov.next) { + sriov_op_start(self, g_steal_pointer(&priv->sriov.next)); + } } static void -sriov_op_queue_op (NMDevice *self, - SriovOp *op) +sriov_op_queue_op(NMDevice *self, SriovOp *op) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->sriov.next) { - SriovOp *op_next = g_steal_pointer (&priv->sriov.next); + if (priv->sriov.next) { + SriovOp *op_next = g_steal_pointer(&priv->sriov.next); - priv->sriov.next = op; + priv->sriov.next = op; - /* Cancel the next operation immediately */ - if (op_next->callback) { - gs_free_error GError *error = NULL; + /* Cancel the next operation immediately */ + if (op_next->callback) { + gs_free_error GError *error = NULL; - nm_utils_error_set_cancelled (&error, FALSE, NULL); - op_next->callback (error, op_next->callback_data); - } + nm_utils_error_set_cancelled(&error, FALSE, NULL); + op_next->callback(error, op_next->callback_data); + } - nm_g_slice_free (op_next); - return; - } + nm_g_slice_free(op_next); + return; + } - if (priv->sriov.pending) { - priv->sriov.next = op; - g_cancellable_cancel (priv->sriov.pending->cancellable); - return; - } + if (priv->sriov.pending) { + priv->sriov.next = op; + g_cancellable_cancel(priv->sriov.pending->cancellable); + return; + } - if (op) - sriov_op_start (self, op); + if (op) + sriov_op_start(self, op); } static void -sriov_op_queue (NMDevice *self, - guint num_vfs, - NMTernary autoprobe, - NMPlatformAsyncCallback callback, - gpointer callback_data) -{ - SriovOp *op; - - /* We usually never want to cancel an async write operation, unless it's superseded - * by a newer operation (that resets the state). That is, because we need to ensure - * that we never end up doing two concurrent writes (since we write on a background - * thread, that would be unordered/racy). - * Of course, since we queue requests only per-device, when devices get renamed we - * might end up writing the same sysctl concurrently still. But that's really - * unlikely, and don't rename after udev completes! - * - * The "next" operation is not yet even started. It can be replaced/canceled right away - * when a newer request comes. - * The "pending" operation is currently ongoing, and we may cancel it if - * we have a follow-up operation (queued in "next"). Unless we have a such - * a newer request, we cannot cancel it! - * - * FIXME(shutdown): However, during shutdown we don't have a follow-up write request to cancel - * this operation and we have to give it at least some time to complete. The solution is that - * we register a way to abort the last call during shutdown, and after NM_SHUTDOWN_TIMEOUT_MS - * grace period we pull the plug and cancel it. */ - - op = g_slice_new (SriovOp); - *op = (SriovOp) { - .num_vfs = num_vfs, - .autoprobe = autoprobe, - .callback = callback, - .callback_data = callback_data, - }; - sriov_op_queue_op (self, op); +sriov_op_queue(NMDevice * self, + guint num_vfs, + NMTernary autoprobe, + NMPlatformAsyncCallback callback, + gpointer callback_data) +{ + SriovOp *op; + + /* We usually never want to cancel an async write operation, unless it's superseded + * by a newer operation (that resets the state). That is, because we need to ensure + * that we never end up doing two concurrent writes (since we write on a background + * thread, that would be unordered/racy). + * Of course, since we queue requests only per-device, when devices get renamed we + * might end up writing the same sysctl concurrently still. But that's really + * unlikely, and don't rename after udev completes! + * + * The "next" operation is not yet even started. It can be replaced/canceled right away + * when a newer request comes. + * The "pending" operation is currently ongoing, and we may cancel it if + * we have a follow-up operation (queued in "next"). Unless we have a such + * a newer request, we cannot cancel it! + * + * FIXME(shutdown): However, during shutdown we don't have a follow-up write request to cancel + * this operation and we have to give it at least some time to complete. The solution is that + * we register a way to abort the last call during shutdown, and after NM_SHUTDOWN_TIMEOUT_MS + * grace period we pull the plug and cancel it. */ + + op = g_slice_new(SriovOp); + *op = (SriovOp){ + .num_vfs = num_vfs, + .autoprobe = autoprobe, + .callback = callback, + .callback_data = callback_data, + }; + sriov_op_queue_op(self, op); } static void -device_init_static_sriov_num_vfs (NMDevice *self) +device_init_static_sriov_num_vfs(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free char *value = NULL; - int num_vfs; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free char * value = NULL; + int num_vfs; - if ( priv->ifindex > 0 - && nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV)) { - value = nm_config_data_get_device_config (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS, - self, - NULL); - num_vfs = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32, -1); - if (num_vfs >= 0) - sriov_op_queue (self, num_vfs, NM_TERNARY_DEFAULT, NULL, NULL); - } + if (priv->ifindex > 0 && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) { + value = nm_config_data_get_device_config(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS, + self, + NULL); + num_vfs = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT32, -1); + if (num_vfs >= 0) + sriov_op_queue(self, num_vfs, NM_TERNARY_DEFAULT, NULL, NULL); + } } static void -config_changed (NMConfig *config, - NMConfigData *config_data, - NMConfigChangeFlags changes, - NMConfigData *old_data, - NMDevice *self) +config_changed(NMConfig * config, + NMConfigData * config_data, + NMConfigChangeFlags changes, + NMConfigData * old_data, + NMDevice * self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( priv->state <= NM_DEVICE_STATE_DISCONNECTED - || priv->state > NM_DEVICE_STATE_ACTIVATED) { - priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self); - if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_VALUES)) - device_init_static_sriov_num_vfs (self); - } + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED || priv->state > NM_DEVICE_STATE_ACTIVATED) { + priv->ignore_carrier = nm_config_data_get_ignore_carrier(config_data, self); + if (NM_FLAGS_HAS(changes, NM_CONFIG_CHANGE_VALUES)) + device_init_static_sriov_num_vfs(self); + } } static void -realize_start_notify (NMDevice *self, - const NMPlatformLink *pllink) +realize_start_notify(NMDevice *self, const NMPlatformLink *pllink) { - /* the default implementation of realize_start_notify() just calls - * link_changed() -- which by default does nothing. */ - NM_DEVICE_GET_CLASS (self)->link_changed (self, pllink); + /* the default implementation of realize_start_notify() just calls + * link_changed() -- which by default does nothing. */ + NM_DEVICE_GET_CLASS(self)->link_changed(self, pllink); } /** @@ -4916,158 +5870,150 @@ realize_start_notify (NMDevice *self, * stuff). */ static void -realize_start_setup (NMDevice *self, - const NMPlatformLink *plink, - gboolean assume_state_guess_assume, - const char *assume_state_connection_uuid, - gboolean set_nm_owned, - NMUnmanFlagOp unmanaged_user_explicit, - gboolean force_platform_init) -{ - NMDevicePrivate *priv; - NMDeviceClass *klass; - NMPlatform *platform; - static guint32 id = 0; - NMDeviceCapabilities capabilities = 0; - NMConfig *config; - guint real_rate; - gboolean unmanaged; - - /* plink is a NMPlatformLink type, however, we require it to come from the platform - * cache (where else would it come from?). */ - nm_assert (!plink || NMP_OBJECT_GET_TYPE (NMP_OBJECT_UP_CAST (plink)) == NMP_OBJECT_TYPE_LINK); - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - - /* The device should not be realized */ - g_return_if_fail (!priv->real); - g_return_if_fail (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)); - g_return_if_fail (priv->ip_ifindex <= 0); - g_return_if_fail (priv->ip_iface == NULL); - g_return_if_fail (!priv->queued_ip_config_id_4); - g_return_if_fail (!priv->queued_ip_config_id_6); - - _LOGD (LOGD_DEVICE, "start setup of %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), plink ? plink->ifindex : 0); - - klass = NM_DEVICE_GET_CLASS (self); - platform = nm_device_get_platform (self); - - /* Balanced by a thaw in nm_device_realize_finish() */ - g_object_freeze_notify (G_OBJECT (self)); - - priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; - priv->mtu_initial = 0; - priv->ip6_mtu_initial = 0; - priv->ip6_mtu = 0; - _set_mtu (self, 0); - - _assume_state_set (self, assume_state_guess_assume, assume_state_connection_uuid); - - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); - - if (plink) - nm_device_update_from_platform_link (self, plink); - - if (priv->ifindex > 0) { - priv->physical_port_id = nm_platform_link_get_physical_port_id (platform, priv->ifindex); - _notify (self, PROP_PHYSICAL_PORT_ID); - - priv->dev_id = nm_platform_link_get_dev_id (platform, priv->ifindex); - - if (nm_platform_link_is_software (platform, priv->ifindex)) - capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; - - _set_mtu (self, - nm_platform_link_get_mtu (platform, - priv->ifindex)); - - nm_platform_link_get_driver_info (platform, - priv->ifindex, - NULL, - &priv->driver_version, - &priv->firmware_version); - if (priv->driver_version) - _notify (self, PROP_DRIVER_VERSION); - if (priv->firmware_version) - _notify (self, PROP_FIRMWARE_VERSION); - - if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled (platform, priv->ifindex); - - if (nm_platform_link_supports_sriov (platform, priv->ifindex)) - capabilities |= NM_DEVICE_CAP_SRIOV; - } - - if (klass->get_generic_capabilities) - capabilities |= klass->get_generic_capabilities (self); - - _add_capabilities (self, capabilities); - - if ( !priv->nm_owned - && set_nm_owned - && nm_device_is_software (self)) { - priv->nm_owned = TRUE; - _LOGD (LOGD_DEVICE, "set nm-owned from state file"); - } - - if (!priv->udi) { - /* Use a placeholder UDI until we get a real one */ - priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++); - _notify (self, PROP_UDI); - } - - nm_device_update_hw_address (self); - nm_device_update_initial_hw_address (self); - nm_device_update_permanent_hw_address (self, FALSE); - - /* Note: initial hardware address must be read before calling get_ignore_carrier() */ - config = nm_config_get (); - priv->ignore_carrier = nm_config_data_get_ignore_carrier (nm_config_get_data (config), self); - if (!priv->config_changed_id) { - priv->config_changed_id = g_signal_connect (config, - NM_CONFIG_SIGNAL_CONFIG_CHANGED, - G_CALLBACK (config_changed), - self); - } +realize_start_setup(NMDevice * self, + const NMPlatformLink *plink, + gboolean assume_state_guess_assume, + const char * assume_state_connection_uuid, + gboolean set_nm_owned, + NMUnmanFlagOp unmanaged_user_explicit, + gboolean force_platform_init) +{ + NMDevicePrivate * priv; + NMDeviceClass * klass; + NMPlatform * platform; + static guint32 id = 0; + NMDeviceCapabilities capabilities = 0; + NMConfig * config; + guint real_rate; + gboolean unmanaged; + + /* plink is a NMPlatformLink type, however, we require it to come from the platform + * cache (where else would it come from?). */ + nm_assert(!plink || NMP_OBJECT_GET_TYPE(NMP_OBJECT_UP_CAST(plink)) == NMP_OBJECT_TYPE_LINK); + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + /* The device should not be realized */ + g_return_if_fail(!priv->real); + g_return_if_fail(nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)); + g_return_if_fail(priv->ip_ifindex <= 0); + g_return_if_fail(priv->ip_iface == NULL); + g_return_if_fail(!priv->queued_ip_config_id_4); + g_return_if_fail(!priv->queued_ip_config_id_6); + + _LOGD(LOGD_DEVICE, + "start setup of %s, kernel ifindex %d", + G_OBJECT_TYPE_NAME(self), + plink ? plink->ifindex : 0); + + klass = NM_DEVICE_GET_CLASS(self); + platform = nm_device_get_platform(self); + + /* Balanced by a thaw in nm_device_realize_finish() */ + g_object_freeze_notify(G_OBJECT(self)); + + priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; + priv->mtu_initial = 0; + priv->ip6_mtu_initial = 0; + priv->ip6_mtu = 0; + _set_mtu(self, 0); + + _assume_state_set(self, assume_state_guess_assume, assume_state_connection_uuid); + + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); + + if (plink) + nm_device_update_from_platform_link(self, plink); + + if (priv->ifindex > 0) { + priv->physical_port_id = nm_platform_link_get_physical_port_id(platform, priv->ifindex); + _notify(self, PROP_PHYSICAL_PORT_ID); + + priv->dev_id = nm_platform_link_get_dev_id(platform, priv->ifindex); + + if (nm_platform_link_is_software(platform, priv->ifindex)) + capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; + + _set_mtu(self, nm_platform_link_get_mtu(platform, priv->ifindex)); + + nm_platform_link_get_driver_info(platform, + priv->ifindex, + NULL, + &priv->driver_version, + &priv->firmware_version); + if (priv->driver_version) + _notify(self, PROP_DRIVER_VERSION); + if (priv->firmware_version) + _notify(self, PROP_FIRMWARE_VERSION); + + if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) + priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled(platform, priv->ifindex); + + if (nm_platform_link_supports_sriov(platform, priv->ifindex)) + capabilities |= NM_DEVICE_CAP_SRIOV; + } + + if (klass->get_generic_capabilities) + capabilities |= klass->get_generic_capabilities(self); + + _add_capabilities(self, capabilities); + + if (!priv->nm_owned && set_nm_owned && nm_device_is_software(self)) { + priv->nm_owned = TRUE; + _LOGD(LOGD_DEVICE, "set nm-owned from state file"); + } + + if (!priv->udi) { + /* Use a placeholder UDI until we get a real one */ + priv->udi = g_strdup_printf("/virtual/device/placeholder/%d", id++); + _notify(self, PROP_UDI); + } + + nm_device_update_hw_address(self); + nm_device_update_initial_hw_address(self); + nm_device_update_permanent_hw_address(self, FALSE); + + /* Note: initial hardware address must be read before calling get_ignore_carrier() */ + config = nm_config_get(); + priv->ignore_carrier = nm_config_data_get_ignore_carrier(nm_config_get_data(config), self); + if (!priv->config_changed_id) { + priv->config_changed_id = g_signal_connect(config, + NM_CONFIG_SIGNAL_CONFIG_CHANGED, + G_CALLBACK(config_changed), + self); + } - nm_device_set_carrier_from_platform (self); + nm_device_set_carrier_from_platform(self); - nm_assert (!priv->stats.timeout_id); - real_rate = _stats_refresh_rate_real (priv->stats.refresh_rate_ms); - if (real_rate) - priv->stats.timeout_id = g_timeout_add (real_rate, _stats_timeout_cb, self); + nm_assert(!priv->stats.timeout_id); + real_rate = _stats_refresh_rate_real(priv->stats.refresh_rate_ms); + if (real_rate) + priv->stats.timeout_id = g_timeout_add(real_rate, _stats_timeout_cb, self); - klass->realize_start_notify (self, plink); + klass->realize_start_notify(self, plink); - nm_assert (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_EXPLICIT)); - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_USER_EXPLICIT, - unmanaged_user_explicit); + nm_assert(!nm_device_get_unmanaged_mask(self, NM_UNMANAGED_USER_EXPLICIT)); + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_USER_EXPLICIT, unmanaged_user_explicit); - /* Do not manage externally created software devices until they are IFF_UP - * or have IP addressing */ - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_EXTERNAL_DOWN, - is_unmanaged_external_down (self, TRUE)); + /* Do not manage externally created software devices until they are IFF_UP + * or have IP addressing */ + nm_device_set_unmanaged_flags(self, + NM_UNMANAGED_EXTERNAL_DOWN, + is_unmanaged_external_down(self, TRUE)); - /* Unmanaged the loopback device with an explicit NM_UNMANAGED_BY_TYPE flag. - * Later we might want to manage 'lo' too. Currently that doesn't work because - * NetworkManager might down the interface or remove the 127.0.0.1 address. */ - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_BY_TYPE, - is_loopback (self)); - - nm_device_set_unmanaged_by_user_udev (self); - nm_device_set_unmanaged_by_user_conf (self); + /* Unmanaged the loopback device with an explicit NM_UNMANAGED_BY_TYPE flag. + * Later we might want to manage 'lo' too. Currently, that doesn't work because + * NetworkManager might down the interface or remove the 127.0.0.1 address. */ + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_BY_TYPE, is_loopback(self)); - unmanaged = plink - && !plink->initialized - && !force_platform_init; - - nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT, - unmanaged); + nm_device_set_unmanaged_by_user_udev(self); + nm_device_set_unmanaged_by_user_conf(self); + + unmanaged = plink && !plink->initialized && !force_platform_init; + + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT, unmanaged); } /** @@ -5080,70 +6026,69 @@ realize_start_setup (NMDevice *self, * is ready for network connectivity. */ void -nm_device_realize_finish (NMDevice *self, const NMPlatformLink *plink) +nm_device_realize_finish(NMDevice *self, const NMPlatformLink *plink) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (!plink || link_type_compatible (self, plink->type, NULL, NULL)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(!plink || link_type_compatible(self, plink->type, NULL, NULL)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - g_return_if_fail (!priv->real); + g_return_if_fail(!priv->real); - if (plink) - device_recheck_slave_status (self, plink); + if (plink) + device_recheck_slave_status(self, plink); - priv->update_ip_config_completed_v4 = FALSE; - priv->update_ip_config_completed_v6 = FALSE; + priv->update_ip_config_completed_v4 = FALSE; + priv->update_ip_config_completed_v6 = FALSE; - priv->real = TRUE; - _notify (self, PROP_REAL); + priv->real = TRUE; + _notify(self, PROP_REAL); - nm_device_recheck_available_connections (self); + nm_device_recheck_available_connections(self); - /* Balanced by a freeze in realize_start_setup(). */ - g_object_thaw_notify (G_OBJECT (self)); + /* Balanced by a freeze in realize_start_setup(). */ + g_object_thaw_notify(G_OBJECT(self)); } static void -unrealize_notify (NMDevice *self) +unrealize_notify(NMDevice *self) { - /* Stub implementation for unrealize_notify(). It does nothing, - * but allows derived classes to uniformly invoke the parent - * implementation. */ + /* Stub implementation for unrealize_notify(). It does nothing, + * but allows derived classes to uniformly invoke the parent + * implementation. */ } static gboolean -available_connections_check_delete_unrealized_on_idle (gpointer user_data) +available_connections_check_delete_unrealized_on_idle(gpointer user_data) { - NMDevice *self = user_data; - NMDevicePrivate *priv; + NMDevice * self = user_data; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); + g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - priv->check_delete_unrealized_id = 0; + priv->check_delete_unrealized_id = 0; - if ( g_hash_table_size (priv->available_connections) == 0 - && !nm_device_is_real (self)) - g_signal_emit (self, signals[REMOVED], 0); + if (g_hash_table_size(priv->available_connections) == 0 && !nm_device_is_real(self)) + g_signal_emit(self, signals[REMOVED], 0); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -available_connections_check_delete_unrealized (NMDevice *self) +available_connections_check_delete_unrealized(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - /* always rescheadule the remove signal. */ - nm_clear_g_source (&priv->check_delete_unrealized_id); + /* always rescheadule the remove signal. */ + nm_clear_g_source(&priv->check_delete_unrealized_id); - if ( g_hash_table_size (priv->available_connections) == 0 - && !nm_device_is_real (self)) - priv->check_delete_unrealized_id = g_idle_add (available_connections_check_delete_unrealized_on_idle, self); + if (g_hash_table_size(priv->available_connections) == 0 && !nm_device_is_real(self)) + priv->check_delete_unrealized_id = + g_idle_add(available_connections_check_delete_unrealized_on_idle, self); } /** @@ -5158,145 +6103,137 @@ available_connections_check_delete_unrealized (NMDevice *self) * Returns: %TRUE on success, %FALSE on error */ gboolean -nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) -{ - NMDevicePrivate *priv; - int ifindex; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - if (!nm_device_is_software (self) || !nm_device_is_real (self)) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_SOFTWARE, - "This device is not a software device or is not realized"); - return FALSE; - } - - priv = NM_DEVICE_GET_PRIVATE (self); - - g_return_val_if_fail (priv->iface != NULL, FALSE); - g_return_val_if_fail (priv->real, FALSE); - - ifindex = nm_device_get_ifindex (self); - - _LOGD (LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0); - - nm_device_assume_state_reset (self); - - if (remove_resources) { - if (NM_DEVICE_GET_CLASS (self)->unrealize) { - if (!NM_DEVICE_GET_CLASS (self)->unrealize (self, error)) - return FALSE; - } else if (ifindex > 0) { - nm_platform_link_delete (nm_device_get_platform (self), ifindex); - } - } - - nm_clear_g_source (&priv->queued_ip_config_id_4); - nm_clear_g_source (&priv->queued_ip_config_id_6); - - g_object_freeze_notify (G_OBJECT (self)); - NM_DEVICE_GET_CLASS (self)->unrealize_notify (self); - - _parent_set_ifindex (self, 0, FALSE); - - if (priv->ifindex > 0) { - priv->ifindex = 0; - _notify (self, PROP_IFINDEX); - } - priv->ip_ifindex = 0; - if (nm_clear_g_free (&priv->ip_iface)) - _notify (self, PROP_IP_IFACE); - - _set_mtu (self, 0); - - if (priv->driver_version) { - nm_clear_g_free (&priv->driver_version); - _notify (self, PROP_DRIVER_VERSION); - } - if (priv->firmware_version) { - nm_clear_g_free (&priv->firmware_version); - _notify (self, PROP_FIRMWARE_VERSION); - } - if (priv->udi) { - nm_clear_g_free (&priv->udi); - _notify (self, PROP_UDI); - } - if (priv->path) { - nm_clear_g_free (&priv->path); - _notify (self, PROP_PATH); - } - if (priv->physical_port_id) { - nm_clear_g_free (&priv->physical_port_id); - _notify (self, PROP_PHYSICAL_PORT_ID); - } - - nm_clear_g_source (&priv->stats.timeout_id); - _stats_update_counters (self, 0, 0); - - priv->hw_addr_len_ = 0; - if (nm_clear_g_free (&priv->hw_addr)) - _notify (self, PROP_HW_ADDRESS); - priv->hw_addr_type = HW_ADDR_TYPE_UNSET; - if (nm_clear_g_free (&priv->hw_addr_perm)) - _notify (self, PROP_PERM_HW_ADDRESS); - nm_clear_g_free (&priv->hw_addr_initial); - - priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; - if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) - priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); - _notify (self, PROP_CAPABILITIES); - - nm_clear_g_signal_handler (nm_config_get (), &priv->config_changed_id); - - priv->real = FALSE; - _notify (self, PROP_REAL); - - g_object_thaw_notify (G_OBJECT (self)); - - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_PLATFORM_INIT, - TRUE); - - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_PARENT | - NM_UNMANAGED_BY_TYPE | - NM_UNMANAGED_USER_UDEV | - NM_UNMANAGED_USER_EXPLICIT | - NM_UNMANAGED_EXTERNAL_DOWN | - NM_UNMANAGED_IS_SLAVE, - NM_UNMAN_FLAG_OP_FORGET); - - nm_device_state_changed (self, - NM_DEVICE_STATE_UNMANAGED, - remove_resources ? - NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED); - - /* Garbage-collect unneeded unrealized devices. */ - nm_device_recheck_available_connections (self); - - return TRUE; +nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error) +{ + NMDevicePrivate *priv; + int ifindex; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + if (!nm_device_is_software(self) || !nm_device_is_real(self)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device or is not realized"); + return FALSE; + } + + priv = NM_DEVICE_GET_PRIVATE(self); + + g_return_val_if_fail(priv->iface != NULL, FALSE); + g_return_val_if_fail(priv->real, FALSE); + + ifindex = nm_device_get_ifindex(self); + + _LOGD(LOGD_DEVICE, "unrealize (ifindex %d)", ifindex > 0 ? ifindex : 0); + + nm_device_assume_state_reset(self); + + if (remove_resources) { + if (NM_DEVICE_GET_CLASS(self)->unrealize) { + if (!NM_DEVICE_GET_CLASS(self)->unrealize(self, error)) + return FALSE; + } else if (ifindex > 0) { + nm_platform_link_delete(nm_device_get_platform(self), ifindex); + } + } + + nm_clear_g_source(&priv->queued_ip_config_id_4); + nm_clear_g_source(&priv->queued_ip_config_id_6); + + g_object_freeze_notify(G_OBJECT(self)); + NM_DEVICE_GET_CLASS(self)->unrealize_notify(self); + + _parent_set_ifindex(self, 0, FALSE); + + _set_ifindex(self, 0, FALSE); + _set_ifindex(self, 0, TRUE); + if (nm_clear_g_free(&priv->ip_iface_)) + _notify(self, PROP_IP_IFACE); + + _set_mtu(self, 0); + + if (priv->driver_version) { + nm_clear_g_free(&priv->driver_version); + _notify(self, PROP_DRIVER_VERSION); + } + if (priv->firmware_version) { + nm_clear_g_free(&priv->firmware_version); + _notify(self, PROP_FIRMWARE_VERSION); + } + if (priv->udi) { + nm_clear_g_free(&priv->udi); + _notify(self, PROP_UDI); + } + if (priv->path) { + nm_clear_g_free(&priv->path); + _notify(self, PROP_PATH); + } + if (priv->physical_port_id) { + nm_clear_g_free(&priv->physical_port_id); + _notify(self, PROP_PHYSICAL_PORT_ID); + } + + nm_clear_g_source(&priv->stats.timeout_id); + _stats_update_counters(self, 0, 0); + + priv->hw_addr_len_ = 0; + if (nm_clear_g_free(&priv->hw_addr)) + _notify(self, PROP_HW_ADDRESS); + priv->hw_addr_type = HW_ADDR_TYPE_UNSET; + if (nm_clear_g_free(&priv->hw_addr_perm)) + _notify(self, PROP_PERM_HW_ADDRESS); + nm_clear_g_free(&priv->hw_addr_initial); + + priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; + if (NM_DEVICE_GET_CLASS(self)->get_generic_capabilities) + priv->capabilities |= NM_DEVICE_GET_CLASS(self)->get_generic_capabilities(self); + _notify(self, PROP_CAPABILITIES); + + nm_clear_g_signal_handler(nm_config_get(), &priv->config_changed_id); + + priv->real = FALSE; + _notify(self, PROP_REAL); + + g_object_thaw_notify(G_OBJECT(self)); + + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT, TRUE); + + nm_device_set_unmanaged_flags(self, + NM_UNMANAGED_PARENT | NM_UNMANAGED_BY_TYPE + | NM_UNMANAGED_USER_UDEV | NM_UNMANAGED_USER_EXPLICIT + | NM_UNMANAGED_EXTERNAL_DOWN | NM_UNMANAGED_IS_SLAVE, + NM_UNMAN_FLAG_OP_FORGET); + + nm_device_state_changed(self, + NM_DEVICE_STATE_UNMANAGED, + remove_resources ? NM_DEVICE_STATE_REASON_USER_REQUESTED + : NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + + /* Garbage-collect unneeded unrealized devices. */ + nm_device_recheck_available_connections(self); + + return TRUE; } void -nm_device_notify_availability_maybe_changed (NMDevice *self) +nm_device_notify_availability_maybe_changed(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->state != NM_DEVICE_STATE_DISCONNECTED) - return; + if (priv->state != NM_DEVICE_STATE_DISCONNECTED) + return; - /* A device could have stayed disconnected because it would - * want to register with a network server that now become - * available. */ - nm_device_recheck_available_connections (self); - if (g_hash_table_size (priv->available_connections) > 0) - nm_device_emit_recheck_auto_activate (self); + /* A device could have stayed disconnected because it would + * want to register with a network server that now become + * available. */ + nm_device_recheck_available_connections(self); + if (g_hash_table_size(priv->available_connections) > 0) + nm_device_emit_recheck_auto_activate(self); } /** @@ -5314,79 +6251,77 @@ nm_device_notify_availability_maybe_changed (NMDevice *self) * %FALSE if not */ gboolean -nm_device_owns_iface (NMDevice *self, const char *iface) +nm_device_owns_iface(NMDevice *self, const char *iface) { - if (NM_DEVICE_GET_CLASS (self)->owns_iface) - return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface); - return FALSE; + if (NM_DEVICE_GET_CLASS(self)->owns_iface) + return NM_DEVICE_GET_CLASS(self)->owns_iface(self, iface); + return FALSE; } NMConnection * -nm_device_new_default_connection (NMDevice *self) +nm_device_new_default_connection(NMDevice *self) { - NMConnection *connection; - GError *error = NULL; + NMConnection *connection; + GError * error = NULL; - if (!NM_DEVICE_GET_CLASS (self)->new_default_connection) - return NULL; + if (!NM_DEVICE_GET_CLASS(self)->new_default_connection) + return NULL; - connection = NM_DEVICE_GET_CLASS (self)->new_default_connection (self); - if (!connection) - return NULL; + connection = NM_DEVICE_GET_CLASS(self)->new_default_connection(self); + if (!connection) + return NULL; - if (!nm_connection_normalize (connection, NULL, NULL, &error)) { - _LOGD (LOGD_DEVICE, "device generated an invalid default connection: %s", error->message); - g_error_free (error); - g_return_val_if_reached (NULL); - } + if (!nm_connection_normalize(connection, NULL, NULL, &error)) { + _LOGD(LOGD_DEVICE, "device generated an invalid default connection: %s", error->message); + g_error_free(error); + g_return_val_if_reached(NULL); + } - return connection; + return connection; } static void -slave_state_changed (NMDevice *slave, - NMDeviceState slave_new_state, - NMDeviceState slave_old_state, - NMDeviceStateReason reason, - NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean release = FALSE; - gboolean configure; - - _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)", - nm_device_get_iface (slave), - slave_old_state, - nm_device_state_to_str (slave_old_state), - slave_new_state, - nm_device_state_to_str (slave_new_state)); - - /* Don't try to enslave slaves until the master is ready */ - if (priv->state < NM_DEVICE_STATE_CONFIG) - return; - - if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG) - nm_device_master_enslave_slave (self, slave, nm_device_get_applied_connection (slave)); - else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED) - release = TRUE; - else if ( slave_new_state <= NM_DEVICE_STATE_DISCONNECTED - && slave_old_state > NM_DEVICE_STATE_DISCONNECTED) { - /* Catch failures due to unavailable or unmanaged */ - release = TRUE; - } - - if (release) { - configure = priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED - && nm_device_sys_iface_state_get (slave) != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; - - nm_device_master_release_one_slave (self, slave, - configure, - reason); - /* Bridge/bond/team interfaces are left up until manually deactivated */ - if ( c_list_is_empty (&priv->slaves) - && priv->state == NM_DEVICE_STATE_ACTIVATED) - _LOGD (LOGD_DEVICE, "last slave removed; remaining activated"); - } +slave_state_changed(NMDevice * slave, + NMDeviceState slave_new_state, + NMDeviceState slave_old_state, + NMDeviceStateReason reason, + NMDevice * self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean release = FALSE; + gboolean configure; + + _LOGD(LOGD_DEVICE, + "slave %s state change %d (%s) -> %d (%s)", + nm_device_get_iface(slave), + slave_old_state, + nm_device_state_to_str(slave_old_state), + slave_new_state, + nm_device_state_to_str(slave_new_state)); + + /* Don't try to enslave slaves until the master is ready */ + if (priv->state < NM_DEVICE_STATE_CONFIG) + return; + + if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG) + nm_device_master_enslave_slave(self, slave, nm_device_get_applied_connection(slave)); + else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED) + release = TRUE; + else if (slave_new_state <= NM_DEVICE_STATE_DISCONNECTED + && slave_old_state > NM_DEVICE_STATE_DISCONNECTED) { + /* Catch failures due to unavailable or unmanaged */ + release = TRUE; + } + + if (release) { + configure = priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED + && nm_device_sys_iface_state_get(slave) != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; + + nm_device_master_release_one_slave(self, slave, configure, FALSE, reason); + /* Bridge/bond/team interfaces are left up until manually deactivated */ + if (c_list_is_empty(&priv->slaves) && priv->state == NM_DEVICE_STATE_ACTIVATED) + _LOGD(LOGD_DEVICE, "last slave removed; remaining activated"); + } } /** @@ -5403,61 +6338,65 @@ slave_state_changed (NMDevice *slave, * enslaved and nothing was done. */ static gboolean -nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) +nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure) { - NMDevicePrivate *priv; - NMDevicePrivate *slave_priv; - SlaveInfo *info; - gboolean changed = FALSE; + NMDevicePrivate *priv; + NMDevicePrivate *slave_priv; + SlaveInfo * info; + gboolean changed = FALSE; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(slave), FALSE); + g_return_val_if_fail(NM_DEVICE_GET_CLASS(self)->enslave_slave != NULL, FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); - slave_priv = NM_DEVICE_GET_PRIVATE (slave); + priv = NM_DEVICE_GET_PRIVATE(self); + slave_priv = NM_DEVICE_GET_PRIVATE(slave); - info = find_slave_info (self, slave); + info = find_slave_info(self, slave); - _LOGT (LOGD_CORE, "master: add one slave %p/%s%s", slave, nm_device_get_iface (slave), - info ? " (already registered)" : ""); + _LOGT(LOGD_CORE, + "master: add one slave %p/%s%s", + slave, + nm_device_get_iface(slave), + info ? " (already registered)" : ""); - if (configure) - g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); + if (configure) + g_return_val_if_fail(nm_device_get_state(slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - if (!info) { - g_return_val_if_fail (!slave_priv->master, FALSE); - g_return_val_if_fail (!slave_priv->is_enslaved, FALSE); + if (!info) { + g_return_val_if_fail(!slave_priv->master, FALSE); + g_return_val_if_fail(!slave_priv->is_enslaved, FALSE); - info = g_slice_new0 (SlaveInfo); - info->slave = g_object_ref (slave); - info->configure = configure; - info->watch_id = g_signal_connect (slave, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (slave_state_changed), self); - c_list_link_tail (&priv->slaves, &info->lst_slave); - slave_priv->master = g_object_ref (self); + info = g_slice_new0(SlaveInfo); + info->slave = g_object_ref(slave); + info->configure = configure; + info->watch_id = + g_signal_connect(slave, NM_DEVICE_STATE_CHANGED, G_CALLBACK(slave_state_changed), self); + c_list_link_tail(&priv->slaves, &info->lst_slave); + slave_priv->master = g_object_ref(self); - _active_connection_set_state_flags (self, - NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES); + _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES); - /* no need to emit - * - * _notify (slave, PROP_MASTER); - * - * because slave_priv->is_enslaved is not true, thus the value - * didn't change yet. */ + /* no need to emit + * + * _notify (slave, PROP_MASTER); + * + * because slave_priv->is_enslaved is not true, thus the value + * didn't change yet. */ - g_warn_if_fail (!NM_FLAGS_HAS (slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE)); - nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - changed = TRUE; - } else - g_return_val_if_fail (slave_priv->master == self, FALSE); + g_warn_if_fail(!NM_FLAGS_HAS(slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE)); + nm_device_set_unmanaged_by_flags(slave, + NM_UNMANAGED_IS_SLAVE, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + changed = TRUE; + } else + g_return_val_if_fail(slave_priv->master == self, FALSE); - nm_device_queue_recheck_assume (self); - nm_device_queue_recheck_assume (slave); + nm_device_queue_recheck_assume(self); + nm_device_queue_recheck_assume(slave); - return changed; + return changed; } /** @@ -5470,59 +6409,59 @@ nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) * as @slave, and logs a warning if so. */ void -nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, - NMLogDomain log_domain) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *slave_physical_port_id, *existing_physical_port_id; - SlaveInfo *info; - CList *iter; - - slave_physical_port_id = nm_device_get_physical_port_id (slave); - if (!slave_physical_port_id) - return; - - c_list_for_each (iter, &priv->slaves) { - info = c_list_entry (iter, SlaveInfo, lst_slave); - if (info->slave == slave) - continue; - - existing_physical_port_id = nm_device_get_physical_port_id (info->slave); - if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) { - _LOGW (log_domain, "slave %s shares a physical port with existing slave %s", - nm_device_get_ip_iface (slave), - nm_device_get_ip_iface (info->slave)); - /* Since this function will get called for every slave, we only have - * to warn about the first match we find; if there are other matches - * later in the list, we will have already warned about them matching - * @existing earlier. - */ - return; - } - } +nm_device_master_check_slave_physical_port(NMDevice *self, NMDevice *slave, NMLogDomain log_domain) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const char * slave_physical_port_id, *existing_physical_port_id; + SlaveInfo * info; + CList * iter; + + slave_physical_port_id = nm_device_get_physical_port_id(slave); + if (!slave_physical_port_id) + return; + + c_list_for_each (iter, &priv->slaves) { + info = c_list_entry(iter, SlaveInfo, lst_slave); + if (info->slave == slave) + continue; + + existing_physical_port_id = nm_device_get_physical_port_id(info->slave); + if (nm_streq0(slave_physical_port_id, existing_physical_port_id)) { + _LOGW(log_domain, + "slave %s shares a physical port with existing slave %s", + nm_device_get_ip_iface(slave), + nm_device_get_ip_iface(info->slave)); + /* Since this function will get called for every slave, we only have + * to warn about the first match we find; if there are other matches + * later in the list, we will have already warned about them matching + * @existing earlier. + */ + return; + } + } } /* release all slaves */ static void -nm_device_master_release_slaves (NMDevice *self) +nm_device_master_release_slaves(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceStateReason reason; - CList *iter, *safe; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceStateReason reason; + CList * iter, *safe; - /* Don't release the slaves if this connection doesn't belong to NM. */ - if (nm_device_sys_iface_state_is_external (self)) - return; + /* Don't release the slaves if this connection doesn't belong to NM. */ + if (nm_device_sys_iface_state_is_external(self)) + return; - reason = priv->state_reason; - if (priv->state == NM_DEVICE_STATE_FAILED) - reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; + reason = priv->state_reason; + if (priv->state == NM_DEVICE_STATE_FAILED) + reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; - c_list_for_each_safe (iter, safe, &priv->slaves) { - SlaveInfo *info = c_list_entry (iter, SlaveInfo, lst_slave); + c_list_for_each_safe (iter, safe, &priv->slaves) { + SlaveInfo *info = c_list_entry(iter, SlaveInfo, lst_slave); - nm_device_master_release_one_slave (self, info->slave, TRUE, reason); - } + nm_device_master_release_one_slave(self, info->slave, TRUE, FALSE, reason); + } } /** @@ -5532,11 +6471,11 @@ nm_device_master_release_slaves (NMDevice *self) * Returns: %TRUE if the device can have slaves */ gboolean -nm_device_is_master (NMDevice *self) +nm_device_is_master(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return NM_DEVICE_GET_CLASS (self)->is_master; + return NM_DEVICE_GET_CLASS(self)->is_master; } /** @@ -5544,35 +6483,35 @@ nm_device_is_master (NMDevice *self) * @self: the device * * If @self has been enslaved by another device, this returns that - * device. Otherwise it returns %NULL. (In particular, note that if + * device. Otherwise, it returns %NULL. (In particular, note that if * @self is in the process of activating as a slave, but has not yet * been enslaved by its master, this will return %NULL.) * * Returns: (transfer none): @self's master, or %NULL */ NMDevice * -nm_device_get_master (NMDevice *self) +nm_device_get_master(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->is_enslaved) { - g_return_val_if_fail (priv->master, NULL); - return priv->master; - } - return NULL; + if (priv->is_enslaved) { + g_return_val_if_fail(priv->master, NULL); + return priv->master; + } + return NULL; } static gboolean -get_ip_config_may_fail (NMDevice *self, int addr_family) +get_ip_config_may_fail(NMDevice *self, int addr_family) { - NMConnection *connection; - NMSettingIPConfig *s_ip; + NMConnection * connection; + NMSettingIPConfig *s_ip; - connection = nm_device_get_applied_connection (self); + connection = nm_device_get_applied_connection(self); - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); - return !s_ip || nm_setting_ip_config_get_may_fail (s_ip); + return !s_ip || nm_setting_ip_config_get_may_fail(s_ip); } /* @@ -5587,84 +6526,82 @@ get_ip_config_may_fail (NMDevice *self, int addr_family) * due to the state of both ip families and the ipvx.may-fail settings. */ static void -check_ip_state (NMDevice *self, gboolean may_fail, gboolean full_state_update) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean ip4_disabled = FALSE, ip6_disabled = FALSE; - NMSettingIPConfig *s_ip4, *s_ip6; - NMDeviceState state; - - if ( full_state_update - && nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG) - return; - - /* Don't progress into IP_CHECK or SECONDARIES if we're waiting for the - * master to enslave us. */ - if ( nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request.obj)) - && !priv->is_enslaved) - return; - - s_ip4 = nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP4_CONFIG); - if (s_ip4 && nm_streq0 (nm_setting_ip_config_get_method (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - ip4_disabled = TRUE; - - s_ip6 = nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG); - if (s_ip6 && NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) - ip6_disabled = TRUE; - - if ( priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE - && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { - /* Both method completed (or disabled), proceed with activation */ - nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); - return; - } - - if ( (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL || (ip4_disabled && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE)) - && (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL || (ip6_disabled && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE))) { - /* Either both methods failed, or only one failed and the other is - * disabled */ - if (nm_device_sys_iface_state_is_external_or_assume (self)) { - /* We have assumed configuration, but couldn't redo it. No problem, - * move to check state. */ - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_DONE); - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_DONE); - state = NM_DEVICE_STATE_IP_CHECK; - } else if ( may_fail - && get_ip_config_may_fail (self, AF_INET) - && get_ip_config_may_fail (self, AF_INET6)) { - /* Couldn't start either IPv6 and IPv4 autoconfiguration, - * but both are allowed to fail. */ - state = NM_DEVICE_STATE_SECONDARIES; - } else { - /* Autoconfiguration attempted without success. */ - state = NM_DEVICE_STATE_FAILED; - } - - if ( full_state_update - || state == NM_DEVICE_STATE_FAILED) { - nm_device_state_changed (self, - state, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } - return; - } - - /* If a method is still pending but required, wait */ - if (priv->ip_state_4 != NM_DEVICE_IP_STATE_DONE && !get_ip_config_may_fail (self, AF_INET)) - return; - if (priv->ip_state_6 != NM_DEVICE_IP_STATE_DONE && !get_ip_config_may_fail (self, AF_INET6)) - return; - - /* If at least a method has completed, proceed with activation */ - if ( (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !ip4_disabled) - || (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE && !ip6_disabled)) { - if (full_state_update) - nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); - return; - } +check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gboolean ip4_disabled = FALSE, ip6_disabled = FALSE; + NMSettingIPConfig *s_ip4, *s_ip6; + NMDeviceState state; + + if (full_state_update && nm_device_get_state(self) != NM_DEVICE_STATE_IP_CONFIG) + return; + + /* Don't progress into IP_CHECK or SECONDARIES if we're waiting for the + * master to enslave us. */ + if (nm_active_connection_get_master(NM_ACTIVE_CONNECTION(priv->act_request.obj)) + && !priv->is_enslaved) + return; + + s_ip4 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG); + if (s_ip4 + && nm_streq0(nm_setting_ip_config_get_method(s_ip4), NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + ip4_disabled = TRUE; + + s_ip6 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG); + if (s_ip6 + && NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip6), + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) + ip6_disabled = TRUE; + + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE + && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { + /* Both method completed (or disabled), proceed with activation */ + nm_device_state_changed(self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); + return; + } + + if ((priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL + || (ip4_disabled && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE)) + && (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL + || (ip6_disabled && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE))) { + /* Either both methods failed, or only one failed and the other is + * disabled */ + if (nm_device_sys_iface_state_is_external_or_assume(self)) { + /* We have assumed configuration, but couldn't redo it. No problem, + * move to check state. */ + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_DONE); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_DONE); + state = NM_DEVICE_STATE_IP_CHECK; + } else if (may_fail && get_ip_config_may_fail(self, AF_INET) + && get_ip_config_may_fail(self, AF_INET6)) { + /* Couldn't start either IPv6 and IPv4 autoconfiguration, + * but both are allowed to fail. */ + state = NM_DEVICE_STATE_SECONDARIES; + } else { + /* Autoconfiguration attempted without success. */ + state = NM_DEVICE_STATE_FAILED; + } + + if (full_state_update || state == NM_DEVICE_STATE_FAILED) { + nm_device_state_changed(self, state, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + return; + } + + /* If a method is still pending but required, wait */ + if (priv->ip_state_4 != NM_DEVICE_IP_STATE_DONE && !get_ip_config_may_fail(self, AF_INET)) + return; + if (priv->ip_state_6 != NM_DEVICE_IP_STATE_DONE && !get_ip_config_may_fail(self, AF_INET6)) + return; + + /* If at least a method has completed, proceed with activation */ + if ((priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !ip4_disabled) + || (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE && !ip6_disabled)) { + if (full_state_update) + nm_device_state_changed(self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); + return; + } } /** @@ -5676,39 +6613,41 @@ check_ip_state (NMDevice *self, gboolean may_fail, gboolean full_state_update) * to enslave it and failed. */ static void -nm_device_slave_notify_enslave (NMDevice *self, gboolean success) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection = nm_device_get_applied_connection (self); - gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); - - g_return_if_fail (priv->master); - - if (!priv->is_enslaved) { - if (success) { - if (activating) { - _LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation", - nm_connection_get_id (connection)); - } else - _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master)); - - priv->is_enslaved = TRUE; - - _notify (self, PROP_MASTER); - _notify (priv->master, PROP_SLAVES); - } else if (activating) { - _LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved", - nm_connection_get_id (connection)); - } - } - - if (activating) { - if (success) - check_ip_state (self, FALSE, TRUE); - else - nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); - } else - nm_device_queue_recheck_assume (self); +nm_device_slave_notify_enslave(NMDevice *self, gboolean success) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection = nm_device_get_applied_connection(self); + gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); + + g_return_if_fail(priv->master); + + if (!priv->is_enslaved) { + if (success) { + if (activating) { + _LOGI(LOGD_DEVICE, + "Activation: connection '%s' enslaved, continuing activation", + nm_connection_get_id(connection)); + } else + _LOGI(LOGD_DEVICE, "enslaved to %s", nm_device_get_iface(priv->master)); + + priv->is_enslaved = TRUE; + + _notify(self, PROP_MASTER); + _notify(priv->master, PROP_SLAVES); + } else if (activating) { + _LOGW(LOGD_DEVICE, + "Activation: connection '%s' could not be enslaved", + nm_connection_get_id(connection)); + } + } + + if (activating) { + if (success) + check_ip_state(self, FALSE, TRUE); + else + nm_device_queue_state(self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); + } else + nm_device_queue_recheck_assume(self); } /** @@ -5719,48 +6658,48 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success) * Notifies a slave that it has been released, and why. */ static void -nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection = nm_device_get_applied_connection (self); - const char *master_status; - - g_return_if_fail (priv->master); - - if ( priv->state > NM_DEVICE_STATE_DISCONNECTED - && priv->state <= NM_DEVICE_STATE_ACTIVATED) { - switch (nm_device_state_reason_check (reason)) { - case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - master_status = "failed"; - break; - case NM_DEVICE_STATE_REASON_USER_REQUESTED: - reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; - master_status = "deactivated by user request"; - break; - case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: - reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; - master_status = "deactivated because master was removed"; - break; - default: - master_status = "deactivated"; - break; - } - - _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s", - nm_connection_get_id (connection), - master_status); - - /* Cancel any pending activation sources */ - _cancel_activation (self); - nm_device_queue_state (self, NM_DEVICE_STATE_DEACTIVATING, reason); - } else - _LOGI (LOGD_DEVICE, "released from master device %s", nm_device_get_iface (priv->master)); - - if (priv->is_enslaved) { - priv->is_enslaved = FALSE; - _notify (self, PROP_MASTER); - _notify (priv->master, PROP_SLAVES); - } +nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection = nm_device_get_applied_connection(self); + const char * master_status; + + g_return_if_fail(priv->master); + + if (priv->state > NM_DEVICE_STATE_DISCONNECTED && priv->state <= NM_DEVICE_STATE_ACTIVATED) { + switch (nm_device_state_reason_check(reason)) { + case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: + master_status = "failed"; + break; + case NM_DEVICE_STATE_REASON_USER_REQUESTED: + reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; + master_status = "deactivated by user request"; + break; + case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: + reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; + master_status = "deactivated because master was removed"; + break; + default: + master_status = "deactivated"; + break; + } + + _LOGD(LOGD_DEVICE, + "Activation: connection '%s' master %s", + nm_connection_get_id(connection), + master_status); + + /* Cancel any pending activation sources */ + _cancel_activation(self); + nm_device_queue_state(self, NM_DEVICE_STATE_DEACTIVATING, reason); + } else + _LOGI(LOGD_DEVICE, "released from master device %s", nm_device_get_iface(priv->master)); + + if (priv->is_enslaved) { + priv->is_enslaved = FALSE; + _notify(self, PROP_MASTER); + _notify(priv->master, PROP_SLAVES); + } } /** @@ -5770,50 +6709,53 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) * of the device (provided, it is still not cleared at this point). * * Called by the manager when the device was removed. Releases the device from - * the master in case it's enslaved. - */ -void -nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config) -{ - NMDevicePrivate *priv; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->master) { - /* this is called when something externally messes with the slave or during shut-down. - * Release the slave from master, but don't touch the device. */ - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - } - - if (unconfigure_ip_config) { - nm_device_set_ip_config (self, AF_INET, NULL, FALSE, NULL); - nm_device_set_ip_config (self, AF_INET6, NULL, FALSE, NULL); - } else { - if (priv->dhcp_data_4.client) - nm_dhcp_client_stop (priv->dhcp_data_4.client, FALSE); - if (priv->dhcp_data_6.client) - nm_dhcp_client_stop (priv->dhcp_data_6.client, FALSE); - } + * the master in case it's enslaved. + */ +void +nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config) +{ + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + if (priv->master) { + /* this is called when something externally messes with the slave or during shut-down. + * Release the slave from master, but don't touch the device. */ + nm_device_master_release_one_slave(priv->master, + self, + FALSE, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } + + if (unconfigure_ip_config) { + nm_device_set_ip_config(self, AF_INET, NULL, FALSE, NULL); + nm_device_set_ip_config(self, AF_INET6, NULL, FALSE, NULL); + } else { + if (priv->dhcp_data_4.client) + nm_dhcp_client_stop(priv->dhcp_data_4.client, FALSE); + if (priv->dhcp_data_6.client) + nm_dhcp_client_stop(priv->dhcp_data_6.client, FALSE); + } } static gboolean -is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *self, NMDeviceCheckDevAvailableFlags flags) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( priv->carrier - || priv->ignore_carrier) - return TRUE; + if (priv->carrier || priv->ignore_carrier) + return TRUE; - if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER)) - return TRUE; + if (NM_FLAGS_HAS(flags, _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER)) + return TRUE; - /* master types are always available even without carrier. */ - if (nm_device_is_master (self)) - return TRUE; + /* master types are always available even without carrier. */ + if (nm_device_is_master(self)) + return TRUE; - return FALSE; + return FALSE; } /** @@ -5836,102 +6778,108 @@ is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) * Returns: %TRUE or %FALSE */ gboolean -nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) +nm_device_is_available(NMDevice *self, NMDeviceCheckDevAvailableFlags flags) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->firmware_missing) - return FALSE; + if (priv->firmware_missing) + return FALSE; - return NM_DEVICE_GET_CLASS (self)->is_available (self, flags); + return NM_DEVICE_GET_CLASS(self)->is_available(self, flags); } gboolean -nm_device_ignore_carrier_by_default (NMDevice *self) +nm_device_ignore_carrier_by_default(NMDevice *self) { - /* master types ignore-carrier by default. */ - return nm_device_is_master (self); + /* master types ignore-carrier by default. */ + return nm_device_is_master(self); } gboolean -nm_device_get_enabled (NMDevice *self) +nm_device_get_enabled(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - if (NM_DEVICE_GET_CLASS (self)->get_enabled) - return NM_DEVICE_GET_CLASS (self)->get_enabled (self); - return TRUE; + if (NM_DEVICE_GET_CLASS(self)->get_enabled) + return NM_DEVICE_GET_CLASS(self)->get_enabled(self); + return TRUE; } void -nm_device_set_enabled (NMDevice *self, gboolean enabled) +nm_device_set_enabled(NMDevice *self, gboolean enabled) { - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - if (NM_DEVICE_GET_CLASS (self)->set_enabled) - NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled); + if (NM_DEVICE_GET_CLASS(self)->set_enabled) + NM_DEVICE_GET_CLASS(self)->set_enabled(self, enabled); } -static -NM_UTILS_FLAGS2STR_DEFINE (_autoconnect_blocked_flags_to_string, NMDeviceAutoconnectBlockedFlags, - NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_NONE, "none"), - NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_USER, "user"), - NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN, "wrong-pin"), - NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT, "manual-disconnect"), -); +static NM_UTILS_FLAGS2STR_DEFINE(_autoconnect_blocked_flags_to_string, + NMDeviceAutoconnectBlockedFlags, + NM_UTILS_FLAGS2STR(NM_DEVICE_AUTOCONNECT_BLOCKED_NONE, "none"), + NM_UTILS_FLAGS2STR(NM_DEVICE_AUTOCONNECT_BLOCKED_USER, "user"), + NM_UTILS_FLAGS2STR(NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN, + "wrong-pin"), + NM_UTILS_FLAGS2STR(NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT, + "manual-disconnect"), ); NMDeviceAutoconnectBlockedFlags -nm_device_autoconnect_blocked_get (NMDevice *self, NMDeviceAutoconnectBlockedFlags mask) +nm_device_autoconnect_blocked_get(NMDevice *self, NMDeviceAutoconnectBlockedFlags mask) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - if (mask == 0) - mask = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL; + if (mask == 0) + mask = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL; - priv = NM_DEVICE_GET_PRIVATE (self); - return priv->autoconnect_blocked_flags & mask; + priv = NM_DEVICE_GET_PRIVATE(self); + return priv->autoconnect_blocked_flags & mask; } void -nm_device_autoconnect_blocked_set_full (NMDevice *self, NMDeviceAutoconnectBlockedFlags mask, NMDeviceAutoconnectBlockedFlags value) +nm_device_autoconnect_blocked_set_full(NMDevice * self, + NMDeviceAutoconnectBlockedFlags mask, + NMDeviceAutoconnectBlockedFlags value) { - NMDevicePrivate *priv; - gboolean changed; - char buf1[128], buf2[128]; + NMDevicePrivate *priv; + gboolean changed; + char buf1[128], buf2[128]; - g_return_if_fail (NM_IS_DEVICE (self)); - nm_assert (mask); - nm_assert (!NM_FLAGS_ANY (mask, ~NM_DEVICE_AUTOCONNECT_BLOCKED_ALL)); - nm_assert (!NM_FLAGS_ANY (value, ~mask)); + g_return_if_fail(NM_IS_DEVICE(self)); + nm_assert(mask); + nm_assert(!NM_FLAGS_ANY(mask, ~NM_DEVICE_AUTOCONNECT_BLOCKED_ALL)); + nm_assert(!NM_FLAGS_ANY(value, ~mask)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - value = (priv->autoconnect_blocked_flags & ~mask) | (mask & value); - if (value == priv->autoconnect_blocked_flags) - return; + value = (priv->autoconnect_blocked_flags & ~mask) | (mask & value); + if (value == priv->autoconnect_blocked_flags) + return; - changed = ((!value) != (!priv->autoconnect_blocked_flags)); + changed = ((!value) != (!priv->autoconnect_blocked_flags)); - _LOGT (LOGD_DEVICE, "autoconnect-blocked: set \"%s\" (was \"%s\")", - _autoconnect_blocked_flags_to_string (value, buf1, sizeof (buf1)), - _autoconnect_blocked_flags_to_string (priv->autoconnect_blocked_flags, buf2, sizeof (buf2))); + _LOGT( + LOGD_DEVICE, + "autoconnect-blocked: set \"%s\" (was \"%s\")", + _autoconnect_blocked_flags_to_string(value, buf1, sizeof(buf1)), + _autoconnect_blocked_flags_to_string(priv->autoconnect_blocked_flags, buf2, sizeof(buf2))); - priv->autoconnect_blocked_flags = value; - nm_assert (priv->autoconnect_blocked_flags == value); - if (changed) - _notify (self, PROP_AUTOCONNECT); + priv->autoconnect_blocked_flags = value; + nm_assert(priv->autoconnect_blocked_flags == value); + if (changed) + _notify(self, PROP_AUTOCONNECT); } static gboolean -autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, gpointer data) +autoconnect_allowed_accumulator(GSignalInvocationHint *ihint, + GValue * return_accu, + const GValue * handler_return, + gpointer data) { - if (!g_value_get_boolean (handler_return)) - g_value_set_boolean (return_accu, FALSE); - return TRUE; + if (!g_value_get_boolean(handler_return)) + g_value_set_boolean(return_accu, FALSE); + return TRUE; } /** @@ -5943,59 +6891,59 @@ autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, * block autoconnect for a time). */ gboolean -nm_device_autoconnect_allowed (NMDevice *self) +nm_device_autoconnect_allowed(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); - GValue instance = G_VALUE_INIT; - GValue retval = G_VALUE_INIT; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self); + GValue instance = G_VALUE_INIT; + GValue retval = G_VALUE_INIT; + + if (nm_device_autoconnect_blocked_get(self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL)) + return FALSE; - if (nm_device_autoconnect_blocked_get (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL)) - return FALSE; + if (klass->get_autoconnect_allowed && !klass->get_autoconnect_allowed(self)) + return FALSE; - if ( klass->get_autoconnect_allowed - && !klass->get_autoconnect_allowed (self)) - return FALSE; + if (!nm_device_get_enabled(self)) + return FALSE; - if (!nm_device_get_enabled (self)) - return FALSE; + if (nm_device_is_real(self)) { + if (priv->state < NM_DEVICE_STATE_DISCONNECTED) + return FALSE; + } else { + if (!nm_device_check_unrealized_device_managed(self)) + return FALSE; + } - if (nm_device_is_real (self)) { - if (priv->state < NM_DEVICE_STATE_DISCONNECTED) - return FALSE; - } else { - if (!nm_device_check_unrealized_device_managed (self)) - return FALSE; - } + if (priv->delete_on_deactivate_data) + return FALSE; - /* The 'autoconnect-allowed' signal is emitted on a device to allow - * other listeners to block autoconnect on the device if they wish. - * This is mainly used by the OLPC Mesh devices to block autoconnect - * on their companion Wi-Fi device as they share radio resources and - * cannot be connected at the same time. - */ + /* The 'autoconnect-allowed' signal is emitted on a device to allow + * other listeners to block autoconnect on the device if they wish. + * This is mainly used by the OLPC Mesh devices to block autoconnect + * on their companion Wi-Fi device as they share radio resources and + * cannot be connected at the same time. + */ - g_value_init (&instance, G_TYPE_OBJECT); - g_value_set_object (&instance, self); + g_value_init(&instance, G_TYPE_OBJECT); + g_value_set_object(&instance, self); - g_value_init (&retval, G_TYPE_BOOLEAN); - g_value_set_boolean (&retval, TRUE); + g_value_init(&retval, G_TYPE_BOOLEAN); + g_value_set_boolean(&retval, TRUE); - /* Use g_signal_emitv() rather than g_signal_emit() to avoid the return - * value being changed if no handlers are connected */ - g_signal_emitv (&instance, signals[AUTOCONNECT_ALLOWED], 0, &retval); - g_value_unset (&instance); + /* Use g_signal_emitv() rather than g_signal_emit() to avoid the return + * value being changed if no handlers are connected */ + g_signal_emitv(&instance, signals[AUTOCONNECT_ALLOWED], 0, &retval); + g_value_unset(&instance); - return g_value_get_boolean (&retval); + return g_value_get_boolean(&retval); } static gboolean -can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, - char **specific_object) +can_auto_connect(NMDevice *self, NMSettingsConnection *sett_conn, char **specific_object) { - nm_assert (!specific_object || !*specific_object); - return TRUE; + nm_assert(!specific_object || !*specific_object); + return TRUE; } /** @@ -6016,57 +6964,55 @@ can_auto_connect (NMDevice *self, * Returns: %TRUE, if the @sett_conn can be auto-activated. **/ gboolean -nm_device_can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, - char **specific_object) +nm_device_can_auto_connect(NMDevice *self, NMSettingsConnection *sett_conn, char **specific_object) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), FALSE); - g_return_val_if_fail (!specific_object || !*specific_object, FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn), FALSE); + g_return_val_if_fail(!specific_object || !*specific_object, FALSE); - /* the caller must ensure that nm_device_autoconnect_allowed() returns - * TRUE as well. This is done, because nm_device_can_auto_connect() - * has only one caller, and it iterates over a list of available - * connections. - * - * Hence, we don't need to re-check nm_device_autoconnect_allowed() - * over and over again. The caller is supposed to do that. */ - nm_assert (nm_device_autoconnect_allowed (self)); + /* the caller must ensure that nm_device_autoconnect_allowed() returns + * TRUE as well. This is done, because nm_device_can_auto_connect() + * has only one caller, and it iterates over a list of available + * connections. + * + * Hence, we don't need to re-check nm_device_autoconnect_allowed() + * over and over again. The caller is supposed to do that. */ + nm_assert(nm_device_autoconnect_allowed(self)); - if (!nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), - NM_DEVICE_CHECK_CON_AVAILABLE_NONE, - NULL, - NULL)) - return FALSE; + if (!nm_device_check_connection_available(self, + nm_settings_connection_get_connection(sett_conn), + NM_DEVICE_CHECK_CON_AVAILABLE_NONE, + NULL, + NULL)) + return FALSE; - if (!NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, sett_conn, specific_object)) - return FALSE; + if (!NM_DEVICE_GET_CLASS(self)->can_auto_connect(self, sett_conn, specific_object)) + return FALSE; - return TRUE; + return TRUE; } static gboolean -device_has_config (NMDevice *self) +device_has_config(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - /* Check for IP configuration. */ - if (priv->ip_config_4 && nm_ip4_config_get_num_addresses (priv->ip_config_4)) - return TRUE; - if (priv->ip_config_6 && nm_ip6_config_get_num_addresses (priv->ip_config_6)) - return TRUE; + /* Check for IP configuration. */ + if (priv->ip_config_4 && nm_ip4_config_get_num_addresses(priv->ip_config_4)) + return TRUE; + if (priv->ip_config_6 && nm_ip6_config_get_num_addresses(priv->ip_config_6)) + return TRUE; - /* The existence of a software device is good enough. */ - if (nm_device_is_software (self) && nm_device_is_real (self)) - return TRUE; + /* The existence of a software device is good enough. */ + if (nm_device_is_software(self) && nm_device_is_real(self)) + return TRUE; - /* Master-slave relationship is also a configuration */ - if ( !c_list_is_empty (&priv->slaves) - || nm_platform_link_get_master (nm_device_get_platform (self), priv->ifindex) > 0) - return TRUE; + /* Master-slave relationship is also a configuration */ + if (!c_list_is_empty(&priv->slaves) + || nm_platform_link_get_master(nm_device_get_platform(self), priv->ifindex) > 0) + return TRUE; - return FALSE; + return FALSE; } /** @@ -6083,166 +7029,208 @@ device_has_config (NMDevice *self) * %FALSE on failure. */ gboolean -nm_device_master_update_slave_connection (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - GError **error) +nm_device_master_update_slave_connection(NMDevice * self, + NMDevice * slave, + NMConnection *connection, + GError ** error) { - NMDeviceClass *klass; - gboolean success; + NMDeviceClass *klass; + gboolean success; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(slave, FALSE); + g_return_val_if_fail(connection, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + g_return_val_if_fail(nm_connection_get_setting_connection(connection), FALSE); + + g_return_val_if_fail(nm_device_get_iface(self), FALSE); + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->master_update_slave_connection) { + success = klass->master_update_slave_connection(self, slave, connection, error); + + g_return_val_if_fail(!error || (success && !*error) || *error, success); + return success; + } - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (slave, FALSE); - g_return_val_if_fail (connection, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE); + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "master device '%s' cannot update a slave connection for slave device '%s' (master " + "type not supported?)", + nm_device_get_iface(self), + nm_device_get_iface(slave)); + return FALSE; +} - g_return_val_if_fail (nm_device_get_iface (self), FALSE); +static gboolean +_get_maybe_ipv6_disabled(NMDevice *self) +{ + NMPlatform *platform; + int ifindex; + const char *path; + char ifname[IFNAMSIZ]; - klass = NM_DEVICE_GET_CLASS (self); - if (klass->master_update_slave_connection) { - success = klass->master_update_slave_connection (self, slave, connection, error); + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + return FALSE; - g_return_val_if_fail (!error || (success && !*error) || *error, success); - return success; - } + platform = nm_device_get_platform(self); + if (!nm_platform_if_indextoname(platform, ifindex, ifname)) + return FALSE; - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)", - nm_device_get_iface (self), nm_device_get_iface (slave)); - return FALSE; + path = nm_sprintf_bufa(128, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname); + return (nm_platform_sysctl_get_int32(platform, NMP_SYSCTL_PATHID_ABSOLUTE(path), 0) == 0); } NMConnection * -nm_device_generate_connection (NMDevice *self, - NMDevice *master, - gboolean *out_maybe_later, - GError **error) -{ - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *ifname = nm_device_get_iface (self); - gs_unref_object NMConnection *connection = NULL; - NMSetting *s_con; - NMSetting *s_ip4; - NMSetting *s_ip6; - char uuid[37]; - const char *ip4_method, *ip6_method; - GError *local = NULL; - const NMPlatformLink *pllink; - - NM_SET_OUT (out_maybe_later, FALSE); - - /* If update_connection() is not implemented, just fail. */ - if (!klass->update_connection) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "device class %s does not support generating a connection", - G_OBJECT_TYPE_NAME (self)); - return NULL; - } - - /* Return NULL if device is unconfigured. */ - if (!device_has_config (self)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "device has no existing configuration"); - return NULL; - } - - connection = nm_simple_connection_new (); - s_con = nm_setting_connection_new (); - - g_object_set (s_con, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf (uuid), - NM_SETTING_CONNECTION_ID, ifname, - NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, - NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, - NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), - NULL); - - if (klass->connection_type_supported) - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type_supported, NULL); - - nm_connection_add_setting (connection, s_con); - - /* If the device is a slave, update various slave settings */ - if (master) { - if (!nm_device_master_update_slave_connection (master, - self, - connection, - &local)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "master device '%s' failed to update slave connection: %s", - nm_device_get_iface (master), local->message); - g_error_free (local); - return NULL; - } - } else { - /* Only regular and master devices get IP configuration; slaves do not */ - s_ip4 = nm_ip4_config_create_setting (priv->ip_config_4); - nm_connection_add_setting (connection, s_ip4); - - s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6); - nm_connection_add_setting (connection, s_ip6); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - pllink = nm_platform_link_get (nm_device_get_platform (self), priv->ifindex); - if ( pllink - && pllink->inet6_token.id) { - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64, - NM_SETTING_IP6_CONFIG_TOKEN, nm_utils_inet6_interface_identifier_to_token (pllink->inet6_token, sbuf), - NULL); - } - } - - klass->update_connection (self, connection); - - if (!nm_connection_normalize (connection, NULL, NULL, &local)) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "generated connection does not verify: %s", - local->message); - g_error_free (local); - return NULL; - } - - /* Ignore the connection if it has no IP configuration, - * no slave configuration, and is not a master interface. - */ - ip4_method = nm_utils_get_ip_config_method (connection, AF_INET); - ip6_method = nm_utils_get_ip_config_method (connection, AF_INET6); - if ( nm_streq0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) - && NM_IN_STRSET (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED) - && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con)) - && c_list_is_empty (&priv->slaves)) { - NM_SET_OUT (out_maybe_later, TRUE); - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "ignoring generated connection (no IP and not in master-slave relationship)"); - return NULL; - } - - /* Ignore any IPv6LL-only, not master connections without slaves, - * unless they are in the assume-ipv6ll-only list. - */ - if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0 - && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 - && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con)) - && c_list_is_empty (&priv->slaves) - && !nm_config_data_get_assume_ipv6ll_only (NM_CONFIG_GET_DATA, self)) { - _LOGD (LOGD_DEVICE, "ignoring generated connection (IPv6LL-only and not in master-slave relationship)"); - NM_SET_OUT (out_maybe_later, TRUE); - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "ignoring generated connection (IPv6LL-only and not in master-slave relationship)"); - return NULL; - } - - return g_steal_pointer (&connection); +nm_device_generate_connection(NMDevice *self, + NMDevice *master, + gboolean *out_maybe_later, + GError ** error) +{ + NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const char * ifname = nm_device_get_iface(self); + gs_unref_object NMConnection *connection = NULL; + NMSetting * s_con; + NMSetting * s_ip4; + NMSetting * s_ip6; + char uuid[37]; + const char * ip4_method, *ip6_method; + GError * local = NULL; + const NMPlatformLink * pllink; + + NM_SET_OUT(out_maybe_later, FALSE); + + /* If update_connection() is not implemented, just fail. */ + if (!klass->update_connection) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "device class %s does not support generating a connection", + G_OBJECT_TYPE_NAME(self)); + return NULL; + } + + /* Return NULL if device is unconfigured. */ + if (!device_has_config(self)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "device has no existing configuration"); + return NULL; + } + + connection = nm_simple_connection_new(); + s_con = nm_setting_connection_new(); + + g_object_set(s_con, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_buf(uuid), + NM_SETTING_CONNECTION_ID, + ifname, + NM_SETTING_CONNECTION_AUTOCONNECT, + FALSE, + NM_SETTING_CONNECTION_INTERFACE_NAME, + ifname, + NM_SETTING_CONNECTION_TIMESTAMP, + (guint64) time(NULL), + NULL); + + if (klass->connection_type_supported) + g_object_set(s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type_supported, NULL); + + nm_connection_add_setting(connection, s_con); + + /* If the device is a slave, update various slave settings */ + if (master) { + if (!nm_device_master_update_slave_connection(master, self, connection, &local)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "master device '%s' failed to update slave connection: %s", + nm_device_get_iface(master), + local->message); + g_error_free(local); + return NULL; + } + } else { + /* Only regular and master devices get IP configuration; slaves do not */ + s_ip4 = nm_ip4_config_create_setting(priv->ip_config_4); + nm_connection_add_setting(connection, s_ip4); + + s_ip6 = nm_ip6_config_create_setting(priv->ip_config_6, _get_maybe_ipv6_disabled(self)); + nm_connection_add_setting(connection, s_ip6); + + nm_connection_add_setting(connection, nm_setting_proxy_new()); + + pllink = nm_platform_link_get(nm_device_get_platform(self), priv->ifindex); + if (pllink && pllink->inet6_token.id) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_object_set(s_ip6, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, + NM_IN6_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP6_CONFIG_TOKEN, + nm_utils_inet6_interface_identifier_to_token(pllink->inet6_token, sbuf), + NULL); + } + } + + klass->update_connection(self, connection); + + if (!nm_connection_normalize(connection, NULL, NULL, &local)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "generated connection does not verify: %s", + local->message); + g_error_free(local); + return NULL; + } + + /* Ignore the connection if it has no IP configuration, + * no slave configuration, and is not a master interface. + */ + ip4_method = nm_utils_get_ip_config_method(connection, AF_INET); + ip6_method = nm_utils_get_ip_config_method(connection, AF_INET6); + if (nm_streq0(ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && NM_IN_STRSET(ip6_method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED) + && !nm_setting_connection_get_master(NM_SETTING_CONNECTION(s_con)) + && c_list_is_empty(&priv->slaves)) { + NM_SET_OUT(out_maybe_later, TRUE); + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "ignoring generated connection (no IP and not in master-slave relationship)"); + return NULL; + } + + /* Ignore any IPv6LL-only, not master connections without slaves, + * unless they are in the assume-ipv6ll-only list. + */ + if (nm_streq0(ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && nm_streq0(ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) + && !nm_setting_connection_get_master(NM_SETTING_CONNECTION(s_con)) + && c_list_is_empty(&priv->slaves) + && !nm_config_data_get_assume_ipv6ll_only(NM_CONFIG_GET_DATA, self)) { + _LOGD(LOGD_DEVICE, + "ignoring generated connection (IPv6LL-only and not in master-slave relationship)"); + NM_SET_OUT(out_maybe_later, TRUE); + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "ignoring generated connection (IPv6LL-only and not in master-slave relationship)"); + return NULL; + } + + return g_steal_pointer(&connection); } /** @@ -6256,182 +7244,180 @@ nm_device_generate_connection (NMDevice *self, * Returns: success or failure. */ gboolean -nm_device_complete_connection (NMDevice *self, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +nm_device_complete_connection(NMDevice * self, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMDeviceClass *klass; + NMDeviceClass *klass; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); - klass = NM_DEVICE_GET_CLASS (self); + klass = NM_DEVICE_GET_CLASS(self); - if (!klass->complete_connection) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "Device class %s had no complete_connection method", - G_OBJECT_TYPE_NAME (self)); - return FALSE; - } + if (!klass->complete_connection) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "Device class %s had no complete_connection method", + G_OBJECT_TYPE_NAME(self)); + return FALSE; + } - if (!klass->complete_connection (self, - connection, - specific_object, - existing_connections, - error)) - return FALSE; + if (!klass->complete_connection(self, connection, specific_object, existing_connections, error)) + return FALSE; - if (!nm_connection_normalize (connection, NULL, NULL, error)) - return FALSE; + if (!nm_connection_normalize(connection, NULL, NULL, error)) + return FALSE; - return nm_device_check_connection_compatible (self, connection, error); + return nm_device_check_connection_compatible(self, connection, error); } gboolean -nm_device_match_parent (NMDevice *self, const char *parent) +nm_device_match_parent(NMDevice *self, const char *parent) { - NMDevice *parent_device; + NMDevice *parent_device; - g_return_val_if_fail (parent, FALSE); + g_return_val_if_fail(parent, FALSE); - parent_device = nm_device_parent_get_device (self); - if (!parent_device) - return FALSE; + parent_device = nm_device_parent_get_device(self); + if (!parent_device) + return FALSE; - if (nm_utils_is_uuid (parent)) { - NMConnection *connection; + if (nm_utils_is_uuid(parent)) { + NMConnection *connection; - /* If the parent is a UUID, the connection matches when there is - * no connection active on the device or when a connection with - * that UUID is active. - */ - connection = nm_device_get_applied_connection (parent_device); - if ( connection - && !nm_streq0 (parent, nm_connection_get_uuid (connection))) - return FALSE; - } else { - /* Interface name */ - if (!nm_streq0 (parent, nm_device_get_ip_iface (parent_device))) - return FALSE; - } + /* If the parent is a UUID, the connection matches when there is + * no connection active on the device or when a connection with + * that UUID is active. + */ + connection = nm_device_get_applied_connection(parent_device); + if (connection && !nm_streq0(parent, nm_connection_get_uuid(connection))) + return FALSE; + } else { + /* Interface name */ + if (!nm_streq0(parent, nm_device_get_ip_iface(parent_device))) + return FALSE; + } - return TRUE; + return TRUE; } gboolean -nm_device_match_parent_hwaddr (NMDevice *device, - NMConnection *connection, - gboolean fail_if_no_hwaddr) +nm_device_match_parent_hwaddr(NMDevice * device, + NMConnection *connection, + gboolean fail_if_no_hwaddr) { - NMSettingWired *s_wired; - NMDevice *parent_device; - const char *setting_mac; - const char *parent_mac; + NMSettingWired *s_wired; + NMDevice * parent_device; + const char * setting_mac; + const char * parent_mac; - s_wired = nm_connection_get_setting_wired (connection); - if (!s_wired) - return !fail_if_no_hwaddr; + s_wired = nm_connection_get_setting_wired(connection); + if (!s_wired) + return !fail_if_no_hwaddr; - setting_mac = nm_setting_wired_get_mac_address (s_wired); - if (!setting_mac) - return !fail_if_no_hwaddr; + setting_mac = nm_setting_wired_get_mac_address(s_wired); + if (!setting_mac) + return !fail_if_no_hwaddr; - parent_device = nm_device_parent_get_device (device); - if (!parent_device) - return !fail_if_no_hwaddr; + parent_device = nm_device_parent_get_device(device); + if (!parent_device) + return !fail_if_no_hwaddr; - parent_mac = nm_device_get_permanent_hw_address (parent_device); - return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); + parent_mac = nm_device_get_permanent_hw_address(parent_device); + return parent_mac && nm_utils_hwaddr_matches(setting_mac, -1, parent_mac, -1); } static gboolean -check_connection_compatible (NMDevice *self, NMConnection *connection, GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *device_iface = nm_device_get_iface (self); - gs_free_error GError *local = NULL; - gs_free char *conn_iface = NULL; - NMDeviceClass *klass; - NMSettingMatch *s_match; - - klass = NM_DEVICE_GET_CLASS (self); - if (klass->connection_type_check_compatible) { - if (!_nm_connection_check_main_setting (connection, - klass->connection_type_check_compatible, - error)) - return FALSE; - } else if (klass->check_connection_compatible == check_connection_compatible) { - /* the device class does not implement check_connection_compatible nor set - * connection_type_check_compatible. That means, it is by default not compatible - * with any connection type. */ - nm_utils_error_set_literal (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "device does not support any connections"); - return FALSE; - } - - conn_iface = nm_manager_get_connection_iface (NM_MANAGER_GET, - connection, - NULL, - NULL, - &local); - - /* We always need a interface name for virtual devices, but for - * physical ones a connection without interface name is fine for - * any device. */ - if (!conn_iface) { - if (nm_connection_is_virtual (connection)) { - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "cannot get interface name due to %s", local->message); - return FALSE; - } - } else if (!nm_streq0 (conn_iface, device_iface)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "mismatching interface name"); - return FALSE; - } - - s_match = (NMSettingMatch *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_MATCH); - if (s_match) { - const char *const *patterns; - const char *device_driver; - guint num_patterns = 0; - - patterns = nm_setting_match_get_interface_names (s_match, &num_patterns); - if (!nm_wildcard_match_check (device_iface, patterns, num_patterns)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not satisfy match.interface-name property"); - return FALSE; - } - - patterns = nm_setting_match_get_kernel_command_lines (s_match, &num_patterns); - if ( num_patterns > 0 - && !nm_utils_kernel_cmdline_match_check (nm_utils_proc_cmdline_split (), - patterns, - num_patterns, - error)) - return FALSE; - - device_driver = nm_device_get_driver (self); - patterns = nm_setting_match_get_drivers (s_match, &num_patterns); - if (!nm_wildcard_match_check (device_driver, patterns, num_patterns)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not satisfy match.driver property"); - return FALSE; - } - - patterns = nm_setting_match_get_paths (s_match, &num_patterns); - if (!nm_wildcard_match_check (priv->path, patterns, num_patterns)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "device does not satisfy match.path property"); - return FALSE; - } - } - - return TRUE; +check_connection_compatible(NMDevice *self, NMConnection *connection, GError **error) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const char * device_iface = nm_device_get_iface(self); + gs_free_error GError *local = NULL; + gs_free char * conn_iface = NULL; + NMDeviceClass * klass; + NMSettingMatch * s_match; + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->connection_type_check_compatible) { + if (!_nm_connection_check_main_setting(connection, + klass->connection_type_check_compatible, + error)) + return FALSE; + } else if (klass->check_connection_compatible == check_connection_compatible) { + /* the device class does not implement check_connection_compatible nor set + * connection_type_check_compatible. That means, it is by default not compatible + * with any connection type. */ + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "device does not support any connections"); + return FALSE; + } + + conn_iface = nm_manager_get_connection_iface(NM_MANAGER_GET, connection, NULL, NULL, &local); + + /* We always need a interface name for virtual devices, but for + * physical ones a connection without interface name is fine for + * any device. */ + if (!conn_iface) { + if (nm_connection_is_virtual(connection)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "cannot get interface name due to %s", + local->message); + return FALSE; + } + } else if (!nm_streq0(conn_iface, device_iface)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "mismatching interface name"); + return FALSE; + } + + s_match = (NMSettingMatch *) nm_connection_get_setting(connection, NM_TYPE_SETTING_MATCH); + if (s_match) { + const char *const *patterns; + const char * device_driver; + guint num_patterns = 0; + + patterns = nm_setting_match_get_interface_names(s_match, &num_patterns); + if (!nm_wildcard_match_check(device_iface, patterns, num_patterns)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not satisfy match.interface-name property"); + return FALSE; + } + + patterns = nm_setting_match_get_kernel_command_lines(s_match, &num_patterns); + if (num_patterns > 0 + && !nm_utils_kernel_cmdline_match_check(nm_utils_proc_cmdline_split(), + patterns, + num_patterns, + error)) + return FALSE; + + device_driver = nm_device_get_driver(self); + patterns = nm_setting_match_get_drivers(s_match, &num_patterns); + if (!nm_wildcard_match_check(device_driver, patterns, num_patterns)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not satisfy match.driver property"); + return FALSE; + } + + patterns = nm_setting_match_get_paths(s_match, &num_patterns); + if (!nm_wildcard_match_check(priv->path, patterns, num_patterns)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "device does not satisfy match.path property"); + return FALSE; + } + } + + return TRUE; } /** @@ -6455,37 +7441,37 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** * @self. */ gboolean -nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection, GError **error) +nm_device_check_connection_compatible(NMDevice *self, NMConnection *connection, GError **error) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); - return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection, error); + return NM_DEVICE_GET_CLASS(self)->check_connection_compatible(self, connection, error); } gboolean -nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave) +nm_device_check_slave_connection_compatible(NMDevice *self, NMConnection *slave) { - NMSettingConnection *s_con; - const char *connection_type, *slave_type; + NMSettingConnection *s_con; + const char * connection_type, *slave_type; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (slave), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(slave), FALSE); - if (!nm_device_is_master (self)) - return FALSE; + if (!nm_device_is_master(self)) + return FALSE; - /* All masters should have connection type set */ - connection_type = NM_DEVICE_GET_CLASS (self)->connection_type_supported; - g_return_val_if_fail (connection_type, FALSE); + /* All masters should have connection type set */ + connection_type = NM_DEVICE_GET_CLASS(self)->connection_type_supported; + g_return_val_if_fail(connection_type, FALSE); - s_con = nm_connection_get_setting_connection (slave); - g_assert (s_con); - slave_type = nm_setting_connection_get_slave_type (s_con); - if (!slave_type) - return FALSE; + s_con = nm_connection_get_setting_connection(slave); + g_assert(s_con); + slave_type = nm_setting_connection_get_slave_type(s_con); + if (!slave_type) + return FALSE; - return strcmp (connection_type, slave_type) == 0; + return nm_streq(connection_type, slave_type); } /** @@ -6498,500 +7484,477 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not */ static gboolean -nm_device_can_assume_connections (NMDevice *self) +nm_device_can_assume_connections(NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (self)->update_connection; + return !!NM_DEVICE_GET_CLASS(self)->update_connection; } static gboolean -unmanaged_on_quit (NMDevice *self) -{ - NMConnection *connection; - - /* NMDeviceWifi overwrites this function to always unmanage wifi devices. - * - * For all other types, if the device type can assume connections, we leave - * it up on quit. - * - * Originally, we would only keep devices up that can be assumed afterwards. - * However, that meant we unmanged layer-2 only devices. So, this was step - * by step refined to unmanage less (commit 25aaaab3, rh#1311988, rh#1333983). - * But there are more scenarios where we also want to keep the device up - * (rh#1378418, rh#1371126). */ - if (!nm_device_can_assume_connections (self)) - return TRUE; - - /* the only exception are IPv4 shared connections. We unmanage them on quit. */ - connection = nm_device_get_applied_connection (self); - if (connection) { - if (NM_IN_STRSET (nm_utils_get_ip_config_method (connection, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - /* shared connections are to be unmangaed. */ - return TRUE; - } - } - - return FALSE; +unmanaged_on_quit(NMDevice *self) +{ + NMConnection *connection; + + /* NMDeviceWifi overwrites this function to always unmanage wifi devices. + * + * For all other types, if the device type can assume connections, we leave + * it up on quit. + * + * Originally, we would only keep devices up that can be assumed afterwards. + * However, that meant we unmanged layer-2 only devices. So, this was step + * by step refined to unmanage less (commit 25aaaab3, rh#1311988, rh#1333983). + * But there are more scenarios where we also want to keep the device up + * (rh#1378418, rh#1371126). */ + if (!nm_device_can_assume_connections(self)) + return TRUE; + + /* the only exception are IPv4 shared connections. We unmanage them on quit. */ + connection = nm_device_get_applied_connection(self); + if (connection) { + if (NM_IN_STRSET(nm_utils_get_ip_config_method(connection, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + /* shared connections are to be unmangaed. */ + return TRUE; + } + } + + return FALSE; } gboolean -nm_device_unmanage_on_quit (NMDevice *self) +nm_device_unmanage_on_quit(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self); + return NM_DEVICE_GET_CLASS(self)->unmanaged_on_quit(self); } static gboolean -nm_device_emit_recheck_assume (gpointer user_data) +nm_device_emit_recheck_assume(gpointer user_data) { - NMDevice *self = user_data; - NMDevicePrivate *priv; + NMDevice * self = user_data; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); + g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - priv->recheck_assume_id = 0; - if (!nm_device_get_act_request (self)) - g_signal_emit (self, signals[RECHECK_ASSUME], 0); + priv->recheck_assume_id = 0; + if (!nm_device_get_act_request(self)) + g_signal_emit(self, signals[RECHECK_ASSUME], 0); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } void -nm_device_queue_recheck_assume (NMDevice *self) +nm_device_queue_recheck_assume(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( !priv->recheck_assume_id - && nm_device_can_assume_connections (self)) - priv->recheck_assume_id = g_idle_add (nm_device_emit_recheck_assume, self); + if (!priv->recheck_assume_id && nm_device_can_assume_connections(self)) + priv->recheck_assume_id = g_idle_add(nm_device_emit_recheck_assume, self); } static gboolean -recheck_available (gpointer user_data) +recheck_available(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean now_available; - NMDeviceState state = nm_device_get_state (self); - NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN; + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean now_available; + NMDeviceState state = nm_device_get_state(self); + NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN; - priv->recheck_available.call_id = 0; + priv->recheck_available.call_id = 0; - now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); + now_available = nm_device_is_available(self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE); - if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) { - new_state = NM_DEVICE_STATE_DISCONNECTED; - nm_device_queue_state (self, new_state, priv->recheck_available.available_reason); - } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) { - new_state = NM_DEVICE_STATE_UNAVAILABLE; - nm_device_queue_state (self, new_state, priv->recheck_available.unavailable_reason); - } + if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) { + new_state = NM_DEVICE_STATE_DISCONNECTED; + nm_device_queue_state(self, new_state, priv->recheck_available.available_reason); + } else if (state >= NM_DEVICE_STATE_DISCONNECTED && !now_available) { + new_state = NM_DEVICE_STATE_UNAVAILABLE; + nm_device_queue_state(self, new_state, priv->recheck_available.unavailable_reason); + } - if (new_state > NM_DEVICE_STATE_UNKNOWN) { - _LOGD (LOGD_DEVICE, "is %savailable, %s %s", - now_available ? "" : "not ", - new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" : "will transition to", - nm_device_state_to_str (new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state)); + if (new_state > NM_DEVICE_STATE_UNKNOWN) { + _LOGD(LOGD_DEVICE, + "is %savailable, %s %s", + now_available ? "" : "not ", + new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" + : "will transition to", + nm_device_state_to_str(new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state)); - priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE; - priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE; - } + priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE; + priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE; + } - if (priv->recheck_available.call_id == 0) - nm_device_remove_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, TRUE); + if (priv->recheck_available.call_id == 0) + nm_device_remove_pending_action(self, NM_PENDING_ACTION_RECHECK_AVAILABLE, TRUE); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } void -nm_device_queue_recheck_available (NMDevice *self, - NMDeviceStateReason available_reason, - NMDeviceStateReason unavailable_reason) +nm_device_queue_recheck_available(NMDevice * self, + NMDeviceStateReason available_reason, + NMDeviceStateReason unavailable_reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->recheck_available.available_reason = available_reason; - priv->recheck_available.unavailable_reason = unavailable_reason; - if (!priv->recheck_available.call_id) { - priv->recheck_available.call_id = g_idle_add (recheck_available, self); - nm_device_add_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, - FALSE /* cannot assert, because of how recheck_available() first clears - the call-id and postpones removing the pending-action. */); - } + priv->recheck_available.available_reason = available_reason; + priv->recheck_available.unavailable_reason = unavailable_reason; + if (!priv->recheck_available.call_id) { + priv->recheck_available.call_id = g_idle_add(recheck_available, self); + nm_device_add_pending_action (self, NM_PENDING_ACTION_RECHECK_AVAILABLE, + FALSE /* cannot assert, because of how recheck_available() first clears + * the call-id and postpones removing the pending-action. */); + } } void -nm_device_emit_recheck_auto_activate (NMDevice *self) +nm_device_emit_recheck_auto_activate(NMDevice *self) { - g_signal_emit (self, signals[RECHECK_AUTO_ACTIVATE], 0); + g_signal_emit(self, signals[RECHECK_AUTO_ACTIVATE], 0); } static void -dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data) +dnsmasq_state_changed_cb(NMDnsMasqManager *manager, guint32 status, gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); + NMDevice *self = NM_DEVICE(user_data); - switch (status) { - case NM_DNSMASQ_STATUS_DEAD: - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); - break; - default: - break; - } + switch (status) { + case NM_DNSMASQ_STATUS_DEAD: + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + break; + default: + break; + } } void -nm_device_auth_request (NMDevice *self, - GDBusMethodInvocation *context, - NMConnection *connection, - const char *permission, - gboolean allow_interaction, - GCancellable *cancellable, - NMManagerDeviceAuthRequestFunc callback, - gpointer user_data) -{ - nm_manager_device_auth_request (nm_device_get_manager (self), - self, - context, - connection, - permission, - allow_interaction, - cancellable, - callback, - user_data); +nm_device_auth_request(NMDevice * self, + GDBusMethodInvocation * context, + NMConnection * connection, + const char * permission, + gboolean allow_interaction, + GCancellable * cancellable, + NMManagerDeviceAuthRequestFunc callback, + gpointer user_data) +{ + nm_manager_device_auth_request(nm_device_get_manager(self), + self, + context, + connection, + permission, + allow_interaction, + cancellable, + callback, + user_data); } /*****************************************************************************/ static void -activation_source_clear (NMDevice *self, - int addr_family) +activation_source_clear(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); - if (priv->activation_source_id_x[IS_IPv4] != 0) { - _LOGD (LOGD_DEVICE, "activation-stage: clear %s,v%c (id %u)", - _activation_func_to_string (priv->activation_source_func_x[IS_IPv4]), - nm_utils_addr_family_to_char (addr_family), - priv->activation_source_id_x[IS_IPv4]); - nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]); - priv->activation_source_func_x[IS_IPv4] = NULL; - } + if (priv->activation_source_id_x[IS_IPv4] != 0) { + _LOGD(LOGD_DEVICE, + "activation-stage: clear %s,v%c (id %u)", + _activation_func_to_string(priv->activation_source_func_x[IS_IPv4]), + nm_utils_addr_family_to_char(addr_family), + priv->activation_source_id_x[IS_IPv4]); + nm_clear_g_source(&priv->activation_source_id_x[IS_IPv4]); + priv->activation_source_func_x[IS_IPv4] = NULL; + } } static gboolean -activation_source_handle_cb (NMDevice *self, - int addr_family) +activation_source_handle_cb(NMDevice *self, int addr_family) { - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); - ActivationHandleFunc activation_source_func; - guint activation_source_id; + NMDevicePrivate * priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); + ActivationHandleFunc activation_source_func; + guint activation_source_id; - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); + g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - activation_source_func = priv->activation_source_func_x[IS_IPv4]; - activation_source_id = priv->activation_source_id_x[IS_IPv4]; + activation_source_func = priv->activation_source_func_x[IS_IPv4]; + activation_source_id = priv->activation_source_id_x[IS_IPv4]; - g_return_val_if_fail (activation_source_id != 0, G_SOURCE_REMOVE); - nm_assert (activation_source_func); + g_return_val_if_fail(activation_source_id != 0, G_SOURCE_REMOVE); + nm_assert(activation_source_func); - priv->activation_source_func_x[IS_IPv4] = NULL; - priv->activation_source_id_x[IS_IPv4] = 0; + priv->activation_source_func_x[IS_IPv4] = NULL; + priv->activation_source_id_x[IS_IPv4] = 0; - _LOGD (LOGD_DEVICE, "activation-stage: invoke %s,v%c (id %u)", - _activation_func_to_string (activation_source_func), - nm_utils_addr_family_to_char (addr_family), - activation_source_id); + _LOGD(LOGD_DEVICE, + "activation-stage: invoke %s,v%c (id %u)", + _activation_func_to_string(activation_source_func), + nm_utils_addr_family_to_char(addr_family), + activation_source_id); - activation_source_func (self); + activation_source_func(self); - _LOGT (LOGD_DEVICE, "activation-stage: complete %s,v%c (id %u)", - _activation_func_to_string (activation_source_func), - nm_utils_addr_family_to_char (addr_family), - activation_source_id); + _LOGT(LOGD_DEVICE, + "activation-stage: complete %s,v%c (id %u)", + _activation_func_to_string(activation_source_func), + nm_utils_addr_family_to_char(addr_family), + activation_source_id); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean -activation_source_handle_cb_4 (gpointer user_data) +activation_source_handle_cb_4(gpointer user_data) { - return activation_source_handle_cb (user_data, AF_INET); + return activation_source_handle_cb(user_data, AF_INET); } static gboolean -activation_source_handle_cb_6 (gpointer user_data) +activation_source_handle_cb_6(gpointer user_data) { - return activation_source_handle_cb (user_data, AF_INET6); + return activation_source_handle_cb(user_data, AF_INET6); } static void -activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int addr_family) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - guint new_id = 0; - - if ( priv->activation_source_id_x[IS_IPv4] != 0 - && priv->activation_source_func_x[IS_IPv4] == func) { - /* Scheduling the same stage multiple times is fine. */ - _LOGT (LOGD_DEVICE, "activation-stage: already scheduled %s,v%c (id %u)", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family), - priv->activation_source_id_x[IS_IPv4]); - return; - } - - new_id = g_idle_add ( IS_IPv4 - ? activation_source_handle_cb_4 - : activation_source_handle_cb_6, - self); - - if (priv->activation_source_id_x[IS_IPv4] != 0) { - _LOGD (LOGD_DEVICE, "activation-stage: schedule %s,v%c which replaces %s,v%c (id %u -> %u)", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family), - _activation_func_to_string (priv->activation_source_func_x[IS_IPv4]), - nm_utils_addr_family_to_char (addr_family), - priv->activation_source_id_x[IS_IPv4], new_id); - nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]); - } else { - _LOGD (LOGD_DEVICE, "activation-stage: schedule %s,v%c (id %u)", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family), - new_id); - } - - priv->activation_source_func_x[IS_IPv4] = func; - priv->activation_source_id_x[IS_IPv4] = new_id; +activation_source_schedule(NMDevice *self, ActivationHandleFunc func, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + guint new_id = 0; + + if (priv->activation_source_id_x[IS_IPv4] != 0 + && priv->activation_source_func_x[IS_IPv4] == func) { + /* Scheduling the same stage multiple times is fine. */ + _LOGT(LOGD_DEVICE, + "activation-stage: already scheduled %s,v%c (id %u)", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family), + priv->activation_source_id_x[IS_IPv4]); + return; + } + + new_id = + g_idle_add(IS_IPv4 ? activation_source_handle_cb_4 : activation_source_handle_cb_6, self); + + if (priv->activation_source_id_x[IS_IPv4] != 0) { + _LOGD(LOGD_DEVICE, + "activation-stage: schedule %s,v%c which replaces %s,v%c (id %u -> %u)", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family), + _activation_func_to_string(priv->activation_source_func_x[IS_IPv4]), + nm_utils_addr_family_to_char(addr_family), + priv->activation_source_id_x[IS_IPv4], + new_id); + nm_clear_g_source(&priv->activation_source_id_x[IS_IPv4]); + } else { + _LOGD(LOGD_DEVICE, + "activation-stage: schedule %s,v%c (id %u)", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family), + new_id); + } + + priv->activation_source_func_x[IS_IPv4] = func; + priv->activation_source_id_x[IS_IPv4] = new_id; } static void -activation_source_invoke_sync (NMDevice *self, ActivationHandleFunc func, int addr_family) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - - if (priv->activation_source_id_x[IS_IPv4] == 0) { - _LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family)); - } else if (priv->activation_source_func_x[IS_IPv4] == func) { - _LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c which was already scheduled (id %u)", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family), - priv->activation_source_id_x[IS_IPv4]); - } else { - _LOGD (LOGD_DEVICE, "activation-stage: synchronously invoke %s,v%c which replaces %s,v%c (id %u)", - _activation_func_to_string (func), - nm_utils_addr_family_to_char (addr_family), - _activation_func_to_string (priv->activation_source_func_x[IS_IPv4]), - nm_utils_addr_family_to_char (addr_family), - priv->activation_source_id_x[IS_IPv4]); - } - - nm_clear_g_source (&priv->activation_source_id_x[IS_IPv4]); - priv->activation_source_func_x[IS_IPv4] = NULL; - - func (self); +activation_source_invoke_sync(NMDevice *self, ActivationHandleFunc func, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + + if (priv->activation_source_id_x[IS_IPv4] == 0) { + _LOGD(LOGD_DEVICE, + "activation-stage: synchronously invoke %s,v%c", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family)); + } else if (priv->activation_source_func_x[IS_IPv4] == func) { + _LOGD(LOGD_DEVICE, + "activation-stage: synchronously invoke %s,v%c which was already scheduled (id %u)", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family), + priv->activation_source_id_x[IS_IPv4]); + } else { + _LOGD(LOGD_DEVICE, + "activation-stage: synchronously invoke %s,v%c which replaces %s,v%c (id %u)", + _activation_func_to_string(func), + nm_utils_addr_family_to_char(addr_family), + _activation_func_to_string(priv->activation_source_func_x[IS_IPv4]), + nm_utils_addr_family_to_char(addr_family), + priv->activation_source_id_x[IS_IPv4]); + } + + nm_clear_g_source(&priv->activation_source_id_x[IS_IPv4]); + priv->activation_source_func_x[IS_IPv4] = NULL; + + func(self); } /*****************************************************************************/ static void -master_ready (NMDevice *self, - NMActiveConnection *active) +master_ready(NMDevice *self, NMActiveConnection *active) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActiveConnection *master_connection; - NMDevice *master; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMActiveConnection *master_connection; + NMDevice * master; - /* Notify a master device that it has a new slave */ - nm_assert (nm_active_connection_get_master_ready (active)); + /* Notify a master device that it has a new slave */ + nm_assert(nm_active_connection_get_master_ready(active)); - master_connection = nm_active_connection_get_master (active); + master_connection = nm_active_connection_get_master(active); - master = nm_active_connection_get_device (master_connection); + master = nm_active_connection_get_device(master_connection); - _LOGD (LOGD_DEVICE, "master connection ready; master device %s", - nm_device_get_iface (master)); + _LOGD(LOGD_DEVICE, "master connection ready; master device %s", nm_device_get_iface(master)); - if ( priv->master - && priv->master != master) - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + if (priv->master && priv->master != master) + nm_device_master_release_one_slave(priv->master, + self, + FALSE, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - /* If the master didn't change, add-slave only rechecks whether to assume a connection. */ - nm_device_master_add_slave (master, - self, - !nm_device_sys_iface_state_is_external_or_assume (self)); + /* If the master didn't change, add-slave only rechecks whether to assume a connection. */ + nm_device_master_add_slave(master, + self, + !nm_device_sys_iface_state_is_external_or_assume(self)); } static void -master_ready_cb (NMActiveConnection *active, - GParamSpec *pspec, - NMDevice *self) +master_ready_cb(NMActiveConnection *active, GParamSpec *pspec, NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (nm_active_connection_get_master_ready (active)); + nm_assert(nm_active_connection_get_master_ready(active)); - if (priv->state == NM_DEVICE_STATE_PREPARE) - nm_device_activate_schedule_stage1_device_prepare (self, FALSE); + if (priv->state == NM_DEVICE_STATE_PREPARE) + nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } static void -lldp_neighbors_changed (NMLldpListener *lldp_listener, GParamSpec *pspec, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - _notify (self, PROP_LLDP_NEIGHBORS); -} - -static gboolean -lldp_rx_enabled (NMDevice *self) +lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) { - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingConnectionLldp lldp = NM_SETTING_CONNECTION_LLDP_DEFAULT; - - connection = nm_device_get_applied_connection (self); - g_return_val_if_fail (connection, FALSE); + NMDevice *self = NM_DEVICE(user_data); - s_con = nm_connection_get_setting_connection (connection); - g_return_val_if_fail (s_con, FALSE); - - lldp = nm_setting_connection_get_lldp (s_con); - if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) { - lldp = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.lldp"), - self, - NM_SETTING_CONNECTION_LLDP_DEFAULT, - NM_SETTING_CONNECTION_LLDP_ENABLE_RX, - NM_SETTING_CONNECTION_LLDP_DEFAULT); - if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) - lldp = NM_SETTING_CONNECTION_LLDP_DISABLE; - } - return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX; + _notify(self, PROP_LLDP_NEIGHBORS); } static NMPlatformVF * -sriov_vf_config_to_platform (NMDevice *self, - NMSriovVF *vf, - GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free NMPlatformVF *plat_vf = NULL; - const guint *vlan_ids; - GVariant *variant; - guint i, num_vlans; - gsize length; - - g_return_val_if_fail (!error || !*error, FALSE); - - vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans); - plat_vf = g_malloc0 ( sizeof (NMPlatformVF) - + sizeof (NMPlatformVFVlan) * num_vlans); - - plat_vf->index = nm_sriov_vf_get_index (vf); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); - if (variant) - plat_vf->spoofchk = g_variant_get_boolean (variant); - else - plat_vf->spoofchk = -1; - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_TRUST); - if (variant) - plat_vf->trust = g_variant_get_boolean (variant); - else - plat_vf->trust = -1; - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC); - if (variant) { - if (!_nm_utils_hwaddr_aton (g_variant_get_string (variant, NULL), - plat_vf->mac.data, - sizeof (plat_vf->mac.data), - &length)) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "invalid MAC %s", - g_variant_get_string (variant, NULL)); - return NULL; - } - if (length != priv->hw_addr_len) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "wrong MAC length %" G_GSIZE_FORMAT ", should be %u", - length, priv->hw_addr_len); - return NULL; - } - plat_vf->mac.len = length; - } - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE); - if (variant) - plat_vf->min_tx_rate = g_variant_get_uint32 (variant); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE); - if (variant) - plat_vf->max_tx_rate = g_variant_get_uint32 (variant); - - plat_vf->num_vlans = num_vlans; - plat_vf->vlans = (NMPlatformVFVlan *) (&plat_vf[1]); - for (i = 0; i < num_vlans; i++) { - plat_vf->vlans[i].id = vlan_ids[i]; - plat_vf->vlans[i].qos = nm_sriov_vf_get_vlan_qos (vf, vlan_ids[i]); - plat_vf->vlans[i].proto_ad = nm_sriov_vf_get_vlan_protocol (vf, vlan_ids[i]) == NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD; - } - - return g_steal_pointer (&plat_vf); +sriov_vf_config_to_platform(NMDevice *self, NMSriovVF *vf, GError **error) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free NMPlatformVF *plat_vf = NULL; + const guint * vlan_ids; + GVariant * variant; + guint i, num_vlans; + gsize length; + + g_return_val_if_fail(!error || !*error, FALSE); + + vlan_ids = nm_sriov_vf_get_vlan_ids(vf, &num_vlans); + plat_vf = g_malloc0(sizeof(NMPlatformVF) + sizeof(NMPlatformVFVlan) * num_vlans); + + plat_vf->index = nm_sriov_vf_get_index(vf); + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); + if (variant) + plat_vf->spoofchk = g_variant_get_boolean(variant); + else + plat_vf->spoofchk = -1; + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_TRUST); + if (variant) + plat_vf->trust = g_variant_get_boolean(variant); + else + plat_vf->trust = -1; + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_MAC); + if (variant) { + if (!_nm_utils_hwaddr_aton(g_variant_get_string(variant, NULL), + plat_vf->mac.data, + sizeof(plat_vf->mac.data), + &length)) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "invalid MAC %s", + g_variant_get_string(variant, NULL)); + return NULL; + } + if (length != priv->hw_addr_len) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "wrong MAC length %" G_GSIZE_FORMAT ", should be %u", + length, + priv->hw_addr_len); + return NULL; + } + plat_vf->mac.len = length; + } + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE); + if (variant) + plat_vf->min_tx_rate = g_variant_get_uint32(variant); + + variant = nm_sriov_vf_get_attribute(vf, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE); + if (variant) + plat_vf->max_tx_rate = g_variant_get_uint32(variant); + + plat_vf->num_vlans = num_vlans; + plat_vf->vlans = (NMPlatformVFVlan *) (&plat_vf[1]); + for (i = 0; i < num_vlans; i++) { + plat_vf->vlans[i].id = vlan_ids[i]; + plat_vf->vlans[i].qos = nm_sriov_vf_get_vlan_qos(vf, vlan_ids[i]); + plat_vf->vlans[i].proto_ad = + nm_sriov_vf_get_vlan_protocol(vf, vlan_ids[i]) == NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD; + } + + return g_steal_pointer(&plat_vf); } static void -sriov_params_cb (GError *error, gpointer data) +sriov_params_cb(GError *error, gpointer data) { - NMDevice *self; - NMDevicePrivate *priv; - nm_auto_freev NMPlatformVF **plat_vfs = NULL; + NMDevice * self; + NMDevicePrivate *priv; + nm_auto_freev NMPlatformVF **plat_vfs = NULL; - nm_utils_user_data_unpack (data, &self, &plat_vfs); + nm_utils_user_data_unpack(data, &self, &plat_vfs); - if (nm_utils_error_is_cancelled_or_disposing (error)) - return; + if (nm_utils_error_is_cancelled_or_disposing(error)) + return; - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (error) { - _LOGE (LOGD_DEVICE, "failed to set SR-IOV parameters: %s", error->message); - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return; - } + if (error) { + _LOGE(LOGD_DEVICE, "failed to set SR-IOV parameters: %s", error->message); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); + return; + } - if (!nm_platform_link_set_sriov_vfs (nm_device_get_platform (self), - priv->ifindex, - (const NMPlatformVF *const *) plat_vfs)) { - _LOGE (LOGD_DEVICE, "failed to apply SR-IOV VFs"); - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return; - } + if (!nm_platform_link_set_sriov_vfs(nm_device_get_platform(self), + priv->ifindex, + (const NMPlatformVF *const *) plat_vfs)) { + _LOGE(LOGD_DEVICE, "failed to apply SR-IOV VFs"); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); + return; + } - priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED; + priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED; - nm_device_activate_schedule_stage1_device_prepare (self, FALSE); + nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } /* @@ -7001,196 +7964,206 @@ sriov_params_cb (GError *error, gpointer data) * */ static void -activate_stage1_device_prepare (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - NMActiveConnection *active; - NMActiveConnection *master; - NMDeviceClass *klass; - - priv->v4_route_table_initialized = FALSE; - priv->v6_route_table_initialized = FALSE; - - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_NONE); - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_NONE); - - /* Notify the new ActiveConnection along with the state change */ - nm_dbus_track_obj_path_set (&priv->act_request, - priv->act_request.obj, - TRUE); - - nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE); - - if (priv->stage1_sriov_state != NM_DEVICE_STAGE_STATE_COMPLETED) { - NMSettingSriov *s_sriov; - - if (nm_device_sys_iface_state_is_external_or_assume (self)) { - /* pass */ - } else if (priv->stage1_sriov_state == NM_DEVICE_STAGE_STATE_PENDING) - return; - else if ( priv->ifindex > 0 - && nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV) - && (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) { - nm_auto_freev NMPlatformVF **plat_vfs = NULL; - gs_free_error GError *error = NULL; - NMSriovVF *vf; - NMTernary autoprobe; - guint i, num; - - autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov); - if (autoprobe == NM_TERNARY_DEFAULT) { - autoprobe = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("sriov.autoprobe-drivers"), - self, - NM_TERNARY_FALSE, - NM_TERNARY_TRUE, - NM_TERNARY_TRUE); - } - - num = nm_setting_sriov_get_num_vfs (s_sriov); - plat_vfs = g_new0 (NMPlatformVF *, num + 1); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf (s_sriov, i); - plat_vfs[i] = sriov_vf_config_to_platform (self, vf, &error); - if (!plat_vfs[i]) { - _LOGE (LOGD_DEVICE, - "failed to apply SR-IOV VF '%s': %s", - nm_utils_sriov_vf_to_str (vf, FALSE, NULL), - error->message); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return; - } - } - - /* When changing the number of VFs the kernel can block - * for very long time in the write to sysfs, especially - * if autoprobe-drivers is enabled. Do it asynchronously - * to avoid blocking the entire NM process. - */ - sriov_op_queue (self, - nm_setting_sriov_get_total_vfs (s_sriov), - autoprobe, - sriov_params_cb, - nm_utils_user_data_pack (self, - g_steal_pointer (&plat_vfs))); - priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_PENDING; - return; - } - priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED; - } - - /* Assumed connections were already set up outside NetworkManager */ - klass = NM_DEVICE_GET_CLASS (self); - - if ( klass->act_stage1_prepare_set_hwaddr_ethernet - && !nm_device_sys_iface_state_is_external_or_assume (self)) { - if (!nm_device_hw_addr_set_cloned (self, - nm_device_get_applied_connection (self), - FALSE)) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return; - } - } - - if ( klass->act_stage1_prepare_also_for_external_or_assume - || !nm_device_sys_iface_state_is_external_or_assume (self)) { - nm_assert (!klass->act_stage1_prepare_also_for_external_or_assume || klass->act_stage1_prepare); - if (klass->act_stage1_prepare) { - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - - ret = klass->act_stage1_prepare (self, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return; - } - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - return; - - nm_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); - } - } - - active = NM_ACTIVE_CONNECTION (priv->act_request.obj); - master = nm_active_connection_get_master (active); - if (master) { - if (nm_active_connection_get_state (master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { - _LOGD (LOGD_DEVICE, "master connection is deactivating"); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); - return; - } - /* If the master connection is ready for slaves, attach ourselves */ - if (!nm_active_connection_get_master_ready (active)) { - if (priv->master_ready_id == 0) { - _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); - priv->master_ready_id = g_signal_connect (active, - "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, - (GCallback) master_ready_cb, - self); - } - return; - } - } - nm_clear_g_signal_handler (priv->act_request.obj, &priv->master_ready_id); - if (master) - master_ready (self, active); - - nm_device_activate_schedule_stage2_device_config (self, TRUE); +activate_stage1_device_prepare(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + NMActiveConnection *active; + NMActiveConnection *master; + NMDeviceClass * klass; + + priv->v4_route_table_initialized = FALSE; + priv->v6_route_table_initialized = FALSE; + + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_NONE); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_NONE); + + /* Notify the new ActiveConnection along with the state change */ + nm_dbus_track_obj_path_set(&priv->act_request, priv->act_request.obj, TRUE); + + nm_device_state_changed(self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE); + + if (priv->stage1_sriov_state != NM_DEVICE_STAGE_STATE_COMPLETED) { + NMSettingSriov *s_sriov; + + if (nm_device_sys_iface_state_is_external_or_assume(self)) { + /* pass */ + } else if (priv->stage1_sriov_state == NM_DEVICE_STAGE_STATE_PENDING) + return; + else if (priv->ifindex > 0 && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV) + && (s_sriov = nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV))) { + nm_auto_freev NMPlatformVF **plat_vfs = NULL; + gs_free_error GError *error = NULL; + NMSriovVF * vf; + NMTernary autoprobe; + guint i, num; + + autoprobe = nm_setting_sriov_get_autoprobe_drivers(s_sriov); + if (autoprobe == NM_TERNARY_DEFAULT) { + autoprobe = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("sriov.autoprobe-drivers"), + self, + NM_TERNARY_FALSE, + NM_TERNARY_TRUE, + NM_TERNARY_TRUE); + } + + num = nm_setting_sriov_get_num_vfs(s_sriov); + plat_vfs = g_new0(NMPlatformVF *, num + 1); + for (i = 0; i < num; i++) { + vf = nm_setting_sriov_get_vf(s_sriov, i); + plat_vfs[i] = sriov_vf_config_to_platform(self, vf, &error); + if (!plat_vfs[i]) { + _LOGE(LOGD_DEVICE, + "failed to apply SR-IOV VF '%s': %s", + nm_utils_sriov_vf_to_str(vf, FALSE, NULL), + error->message); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); + return; + } + } + + /* When changing the number of VFs the kernel can block + * for very long time in the write to sysfs, especially + * if autoprobe-drivers is enabled. Do it asynchronously + * to avoid blocking the entire NM process. + */ + sriov_op_queue(self, + nm_setting_sriov_get_total_vfs(s_sriov), + autoprobe, + sriov_params_cb, + nm_utils_user_data_pack(self, g_steal_pointer(&plat_vfs))); + priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_PENDING; + return; + } + priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_COMPLETED; + } + + /* Assumed connections were already set up outside NetworkManager */ + klass = NM_DEVICE_GET_CLASS(self); + + if (klass->act_stage1_prepare_set_hwaddr_ethernet + && !nm_device_sys_iface_state_is_external_or_assume(self)) { + if (!nm_device_hw_addr_set_cloned(self, nm_device_get_applied_connection(self), FALSE)) { + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + } + + if (klass->act_stage1_prepare_also_for_external_or_assume + || !nm_device_sys_iface_state_is_external_or_assume(self)) { + nm_assert(!klass->act_stage1_prepare_also_for_external_or_assume + || klass->act_stage1_prepare); + if (klass->act_stage1_prepare) { + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + + ret = klass->act_stage1_prepare(self, &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return; + } + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + return; + + nm_assert(ret == NM_ACT_STAGE_RETURN_SUCCESS); + } + } + + active = NM_ACTIVE_CONNECTION(priv->act_request.obj); + master = nm_active_connection_get_master(active); + if (master) { + if (nm_active_connection_get_state(master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { + _LOGD(LOGD_DEVICE, "master connection is deactivating"); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + return; + } + /* If the master connection is ready for slaves, attach ourselves */ + if (!nm_active_connection_get_master_ready(active)) { + if (priv->master_ready_id == 0) { + _LOGD(LOGD_DEVICE, "waiting for master connection to become ready"); + priv->master_ready_id = + g_signal_connect(active, + "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, + (GCallback) master_ready_cb, + self); + } + return; + } + } + nm_clear_g_signal_handler(priv->act_request.obj, &priv->master_ready_id); + if (master) + master_ready(self, active); + else if (priv->master) { + nm_device_master_release_one_slave(priv->master, + self, + TRUE, + TRUE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } + + nm_device_activate_schedule_stage2_device_config(self, TRUE); } void -nm_device_activate_schedule_stage1_device_prepare (NMDevice *self, - gboolean do_sync) +nm_device_activate_schedule_stage1_device_prepare(NMDevice *self, gboolean do_sync) { - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_DEVICE_GET_PRIVATE (self)->act_request.obj); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_DEVICE_GET_PRIVATE(self)->act_request.obj); - if (!do_sync) { - activation_source_schedule (self, activate_stage1_device_prepare, AF_INET); - return; - } + if (!do_sync) { + activation_source_schedule(self, activate_stage1_device_prepare, AF_INET); + return; + } - activation_source_invoke_sync (self, activate_stage1_device_prepare, AF_INET); + activation_source_invoke_sync(self, activate_stage1_device_prepare, AF_INET); } static NMActStageReturn -act_stage2_config (NMDevice *self, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *self, NMDeviceStateReason *out_failure_reason) { - return NM_ACT_STAGE_RETURN_SUCCESS; + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -lldp_init (NMDevice *self, gboolean restart) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->ifindex > 0 && lldp_rx_enabled (self)) { - gs_free_error GError *error = NULL; - - if (priv->lldp_listener) { - if ( restart - && nm_lldp_listener_is_running (priv->lldp_listener)) - nm_lldp_listener_stop (priv->lldp_listener); - } else { - priv->lldp_listener = nm_lldp_listener_new (); - g_signal_connect (priv->lldp_listener, - "notify::" NM_LLDP_LISTENER_NEIGHBORS, - G_CALLBACK (lldp_neighbors_changed), - self); - } - - if (!nm_lldp_listener_is_running (priv->lldp_listener)) { - if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error)) - _LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener); - else { - _LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s", - priv->lldp_listener, error->message); - } - } - } else { - if (priv->lldp_listener) - nm_lldp_listener_stop (priv->lldp_listener); - } +lldp_init(NMDevice *self, gboolean restart) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->ifindex > 0 && _prop_get_connection_lldp(self)) { + gs_free_error GError *error = NULL; + + if (priv->lldp_listener) { + if (restart && nm_lldp_listener_is_running(priv->lldp_listener)) + nm_lldp_listener_stop(priv->lldp_listener); + } else { + priv->lldp_listener = nm_lldp_listener_new(); + g_signal_connect(priv->lldp_listener, + "notify::" NM_LLDP_LISTENER_NEIGHBORS, + G_CALLBACK(lldp_neighbors_changed), + self); + } + + if (!nm_lldp_listener_is_running(priv->lldp_listener)) { + if (nm_lldp_listener_start(priv->lldp_listener, nm_device_get_ifindex(self), &error)) + _LOGD(LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener); + else { + _LOGD(LOGD_DEVICE, + "LLDP listener %p could not be started: %s", + priv->lldp_listener, + error->message); + } + } + } else { + if (priv->lldp_listener) + nm_lldp_listener_stop(priv->lldp_listener); + } } /* set-mode can be: @@ -7205,131 +8178,130 @@ lldp_init (NMDevice *self, gboolean restart) * you care about that. */ static void -_routing_rules_sync (NMDevice *self, - NMTernary set_mode) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPRulesManager *rules_manager = nm_netns_get_rules_manager (nm_device_get_netns (self)); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); - gboolean untrack_only_dirty = FALSE; - gboolean keep_deleted_rules; - gpointer user_tag_1; - gpointer user_tag_2; - - /* take two arbitrary user-tag pointers that belong to @self. */ - user_tag_1 = &priv->v4_route_table; - user_tag_2 = &priv->v6_route_table; - - if (set_mode == NM_TERNARY_TRUE) { - NMConnection *applied_connection; - NMSettingIPConfig *s_ip; - guint i, num; - int is_ipv4; - - untrack_only_dirty = TRUE; - nmp_rules_manager_set_dirty (rules_manager, user_tag_1); - if (klass->get_extra_rules) - nmp_rules_manager_set_dirty (rules_manager, user_tag_2); - - applied_connection = nm_device_get_applied_connection (self); - - for (is_ipv4 = 0; applied_connection && is_ipv4 < 2; is_ipv4++) { - int addr_family = is_ipv4 ? AF_INET : AF_INET6; - - s_ip = nm_connection_get_setting_ip_config (applied_connection, addr_family); - if (!s_ip) - continue; - - num = nm_setting_ip_config_get_num_routing_rules (s_ip); - for (i = 0; i < num; i++) { - NMPlatformRoutingRule plrule; - NMIPRoutingRule *rule; - - rule = nm_setting_ip_config_get_routing_rule (s_ip, i); - nm_ip_routing_rule_to_platform (rule, &plrule); - - /* We track this rule, but we also make it explicitly not weakly-tracked - * (meaning to untrack NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG at - * the same time). */ - nmp_rules_manager_track (rules_manager, - &plrule, - 10, - user_tag_1, - NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); - } - } - - if (klass->get_extra_rules) { - gs_unref_ptrarray GPtrArray *extra_rules = NULL; - - extra_rules = klass->get_extra_rules (self); - if (extra_rules) { - for (i = 0; i < extra_rules->len; i++) { - nmp_rules_manager_track (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (extra_rules->pdata[i]), - 10, - user_tag_2, - NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); - } - } - } - } - - nmp_rules_manager_untrack_all (rules_manager, user_tag_1, !untrack_only_dirty); - if (klass->get_extra_rules) - nmp_rules_manager_untrack_all (rules_manager, user_tag_2, !untrack_only_dirty); - - keep_deleted_rules = FALSE; - if (set_mode == NM_TERNARY_DEFAULT) { - /* when exiting NM, we leave the device up and the rules configured. - * We just all nmp_rules_manager_sync() to forget about the synced rules, - * but we don't actually delete them. - * - * FIXME: that is a problem after restart of NetworkManager, because these - * rules will look like externally added, and NM will no longer remove - * them. - * To fix that, we could during "assume" mark the rules of the profile - * as owned (and "added" by the device). The problem with that is that it - * wouldn't cover rules that devices add by internal decision (not because - * of a setting in the profile, e.g. WireGuard could setup policy routing). - * Maybe it would be better to remember these orphaned rules at exit in a - * file and track them after restart again. */ - keep_deleted_rules = TRUE; - } - nmp_rules_manager_sync (rules_manager, keep_deleted_rules); +_routing_rules_sync(NMDevice *self, NMTernary set_mode) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPRulesManager *rules_manager = nm_netns_get_rules_manager(nm_device_get_netns(self)); + NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self); + gboolean untrack_only_dirty = FALSE; + gboolean keep_deleted_rules; + gpointer user_tag_1; + gpointer user_tag_2; + + /* take two arbitrary user-tag pointers that belong to @self. */ + user_tag_1 = &priv->v4_route_table; + user_tag_2 = &priv->v6_route_table; + + if (set_mode == NM_TERNARY_TRUE) { + NMConnection * applied_connection; + NMSettingIPConfig *s_ip; + guint i, num; + int is_ipv4; + + untrack_only_dirty = TRUE; + nmp_rules_manager_set_dirty(rules_manager, user_tag_1); + if (klass->get_extra_rules) + nmp_rules_manager_set_dirty(rules_manager, user_tag_2); + + applied_connection = nm_device_get_applied_connection(self); + + for (is_ipv4 = 0; applied_connection && is_ipv4 < 2; is_ipv4++) { + int addr_family = is_ipv4 ? AF_INET : AF_INET6; + + s_ip = nm_connection_get_setting_ip_config(applied_connection, addr_family); + if (!s_ip) + continue; + + num = nm_setting_ip_config_get_num_routing_rules(s_ip); + for (i = 0; i < num; i++) { + NMPlatformRoutingRule plrule; + NMIPRoutingRule * rule; + + rule = nm_setting_ip_config_get_routing_rule(s_ip, i); + nm_ip_routing_rule_to_platform(rule, &plrule); + + /* We track this rule, but we also make it explicitly not weakly-tracked + * (meaning to untrack NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG at + * the same time). */ + nmp_rules_manager_track(rules_manager, + &plrule, + 10, + user_tag_1, + NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + } + } + + if (klass->get_extra_rules) { + gs_unref_ptrarray GPtrArray *extra_rules = NULL; + + extra_rules = klass->get_extra_rules(self); + if (extra_rules) { + for (i = 0; i < extra_rules->len; i++) { + nmp_rules_manager_track(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(extra_rules->pdata[i]), + 10, + user_tag_2, + NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + } + } + } + } + + nmp_rules_manager_untrack_all(rules_manager, user_tag_1, !untrack_only_dirty); + if (klass->get_extra_rules) + nmp_rules_manager_untrack_all(rules_manager, user_tag_2, !untrack_only_dirty); + + keep_deleted_rules = FALSE; + if (set_mode == NM_TERNARY_DEFAULT) { + /* when exiting NM, we leave the device up and the rules configured. + * We just all nmp_rules_manager_sync() to forget about the synced rules, + * but we don't actually delete them. + * + * FIXME: that is a problem after restart of NetworkManager, because these + * rules will look like externally added, and NM will no longer remove + * them. + * To fix that, we could during "assume" mark the rules of the profile + * as owned (and "added" by the device). The problem with that is that it + * wouldn't cover rules that devices add by internal decision (not because + * of a setting in the profile, e.g. WireGuard could setup policy routing). + * Maybe it would be better to remember these orphaned rules at exit in a + * file and track them after restart again. */ + keep_deleted_rules = TRUE; + } + nmp_rules_manager_sync(rules_manager, keep_deleted_rules); } static gboolean -tc_commit (NMDevice *self) +tc_commit(NMDevice *self) { - NMConnection *connection = NULL; - gs_unref_ptrarray GPtrArray *qdiscs = NULL; - gs_unref_ptrarray GPtrArray *tfilters = NULL; - NMSettingTCConfig *s_tc = NULL; - NMPlatform *platform; - int ip_ifindex; + NMConnection * connection = NULL; + gs_unref_ptrarray GPtrArray *qdiscs = NULL; + gs_unref_ptrarray GPtrArray *tfilters = NULL; + NMSettingTCConfig * s_tc = NULL; + NMPlatform * platform; + int ip_ifindex; - platform = nm_device_get_platform (self); - connection = nm_device_get_applied_connection (self); - if (connection) - s_tc = nm_connection_get_setting_tc_config (connection); + platform = nm_device_get_platform(self); + connection = nm_device_get_applied_connection(self); + if (connection) + s_tc = nm_connection_get_setting_tc_config(connection); - ip_ifindex = nm_device_get_ip_ifindex (self); - if (!ip_ifindex) - return s_tc == NULL; + ip_ifindex = nm_device_get_ip_ifindex(self); + if (!ip_ifindex) + return s_tc == NULL; - if (s_tc) { - qdiscs = nm_utils_qdiscs_from_tc_setting (platform, s_tc, ip_ifindex); - tfilters = nm_utils_tfilters_from_tc_setting (platform, s_tc, ip_ifindex); - } + if (s_tc) { + qdiscs = nm_utils_qdiscs_from_tc_setting(platform, s_tc, ip_ifindex); + tfilters = nm_utils_tfilters_from_tc_setting(platform, s_tc, ip_ifindex); + } - if (!nm_platform_qdisc_sync (platform, ip_ifindex, qdiscs)) - return FALSE; + if (!nm_platform_qdisc_sync(platform, ip_ifindex, qdiscs)) + return FALSE; - if (!nm_platform_tfilter_sync (platform, ip_ifindex, tfilters)) - return FALSE; + if (!nm_platform_tfilter_sync(platform, ip_ifindex, tfilters)) + return FALSE; - return TRUE; + return TRUE; } /* @@ -7340,202 +8312,176 @@ tc_commit (NMDevice *self) * */ static void -activate_stage2_device_config (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceClass *klass; - NMActStageReturn ret; - gboolean no_firmware = FALSE; - CList *iter; - - nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); - - if (!nm_device_sys_iface_state_is_external_or_assume (self)) - _ethtool_state_set (self); - - if (!nm_device_sys_iface_state_is_external_or_assume (self)) { - if (!tc_commit (self)) { - _LOGW (LOGD_IP6, "failed applying traffic control rules"); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return; - } - } - - _routing_rules_sync (self, NM_TERNARY_TRUE); - - if (!nm_device_sys_iface_state_is_external_or_assume (self)) { - if (!nm_device_bring_up (self, FALSE, &no_firmware)) { - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - no_firmware - ? NM_DEVICE_STATE_REASON_FIRMWARE_MISSING - : NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return; - } - } - - klass = NM_DEVICE_GET_CLASS (self); - if ( klass->act_stage2_config_also_for_external_or_assume - || !nm_device_sys_iface_state_is_external_or_assume (self)) { - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - - ret = klass->act_stage2_config (self, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - return; - if (ret != NM_ACT_STAGE_RETURN_SUCCESS) { - nm_assert (ret == NM_ACT_STAGE_RETURN_FAILURE); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return; - } - } - - /* If we have slaves that aren't yet enslaved, do that now */ - c_list_for_each (iter, &priv->slaves) { - SlaveInfo *info = c_list_entry (iter, SlaveInfo, lst_slave); - NMDeviceState slave_state = nm_device_get_state (info->slave); - - if (slave_state == NM_DEVICE_STATE_IP_CONFIG) - nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave)); - else if ( priv->act_request.obj - && nm_device_sys_iface_state_is_external (self) - && slave_state <= NM_DEVICE_STATE_DISCONNECTED) - nm_device_queue_recheck_assume (info->slave); - } - - lldp_init (self, TRUE); - - nm_device_activate_schedule_stage3_ip_config_start (self); +activate_stage2_device_config(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceClass * klass; + NMActStageReturn ret; + gboolean no_firmware = FALSE; + CList * iter; + + nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); + + if (!nm_device_sys_iface_state_is_external_or_assume(self)) + _ethtool_state_set(self); + + if (!nm_device_sys_iface_state_is_external_or_assume(self)) { + if (!tc_commit(self)) { + _LOGW(LOGD_IP6, "failed applying traffic control rules"); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + } + + _routing_rules_sync(self, NM_TERNARY_TRUE); + + if (!nm_device_sys_iface_state_is_external_or_assume(self)) { + if (!nm_device_bring_up(self, FALSE, &no_firmware)) { + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + no_firmware ? NM_DEVICE_STATE_REASON_FIRMWARE_MISSING + : NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + } + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->act_stage2_config_also_for_external_or_assume + || !nm_device_sys_iface_state_is_external_or_assume(self)) { + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + + ret = klass->act_stage2_config(self, &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + return; + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) { + nm_assert(ret == NM_ACT_STAGE_RETURN_FAILURE); + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return; + } + } + + /* If we have slaves that aren't yet enslaved, do that now */ + c_list_for_each (iter, &priv->slaves) { + SlaveInfo * info = c_list_entry(iter, SlaveInfo, lst_slave); + NMDeviceState slave_state = nm_device_get_state(info->slave); + + if (slave_state == NM_DEVICE_STATE_IP_CONFIG) + nm_device_master_enslave_slave(self, + info->slave, + nm_device_get_applied_connection(info->slave)); + else if (priv->act_request.obj && nm_device_sys_iface_state_is_external(self) + && slave_state <= NM_DEVICE_STATE_DISCONNECTED) + nm_device_queue_recheck_assume(info->slave); + } + + lldp_init(self, TRUE); + + nm_device_activate_schedule_stage3_ip_config_start(self); } void -nm_device_activate_schedule_stage2_device_config (NMDevice *self, - gboolean do_sync) +nm_device_activate_schedule_stage2_device_config(NMDevice *self, gboolean do_sync) { - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - if (!do_sync) { - activation_source_schedule (self, activate_stage2_device_config, AF_INET); - return; - } + if (!do_sync) { + activation_source_schedule(self, activate_stage2_device_config, AF_INET); + return; + } - activation_source_invoke_sync (self, activate_stage2_device_config, AF_INET); + activation_source_invoke_sync(self, activate_stage2_device_config, AF_INET); } void -nm_device_ip_method_failed (NMDevice *self, - int addr_family, - NMDeviceStateReason reason) +nm_device_ip_method_failed(NMDevice *self, int addr_family, NMDeviceStateReason reason) { - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); - _set_ip_state (self, addr_family, NM_DEVICE_IP_STATE_FAIL); + _set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_FAIL); - if (get_ip_config_may_fail (self, addr_family)) - check_ip_state (self, FALSE, (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)); - else - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); + if (get_ip_config_may_fail(self, addr_family)) + check_ip_state(self, FALSE, (nm_device_get_state(self) == NM_DEVICE_STATE_IP_CONFIG)); + else + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, reason); } /*****************************************************************************/ -/* IPv4 DAD stuff */ - -static guint -get_ipv4_dad_timeout (NMDevice *self) -{ - NMConnection *connection; - NMSettingIPConfig *s_ip4 = NULL; - int timeout = -1; - - connection = nm_device_get_applied_connection (self); - if (connection) - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4) - timeout = nm_setting_ip_config_get_dad_timeout (s_ip4); - if (timeout >= 0) - return timeout; - - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ipv4.dad-timeout"), - self, - 0, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, - 0); -} static void -acd_data_destroy (gpointer ptr) +acd_data_destroy(gpointer ptr) { - AcdData *data = ptr; - int i; + AcdData *data = ptr; + int i; - for (i = 0; data->configs && data->configs[i]; i++) - g_object_unref (data->configs[i]); - g_free (data->configs); - g_slice_free (AcdData, data); + for (i = 0; data->configs && data->configs[i]; i++) + g_object_unref(data->configs[i]); + g_free(data->configs); + g_slice_free(AcdData, data); } static void -ipv4_manual_method_apply (NMDevice *self, NMIP4Config **configs, gboolean success) +ipv4_manual_method_apply(NMDevice *self, NMIP4Config **configs, gboolean success) { - NMConnection *connection; - const char *method; + NMConnection *connection; + const char * method; - connection = nm_device_get_applied_connection (self); - nm_assert (connection); - method = nm_utils_get_ip_config_method (connection, AF_INET); - nm_assert (NM_IN_STRSET (method, - NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_METHOD_AUTO)); + connection = nm_device_get_applied_connection(self); + nm_assert(connection); + method = nm_utils_get_ip_config_method(connection, AF_INET); + nm_assert(NM_IN_STRSET(method, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_METHOD_AUTO)); - if (!success) { - nm_device_ip_method_failed (self, AF_INET, - NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); - return; - } + if (!success) { + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); + return; + } - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) - nm_device_activate_schedule_ip_config_result (self, AF_INET, NULL); - else { - if (NM_DEVICE_GET_PRIVATE (self)->ip_state_4 != NM_DEVICE_IP_STATE_DONE) - ip_config_merge_and_apply (self, AF_INET, TRUE); - } + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + nm_device_activate_schedule_ip_config_result(self, AF_INET, NULL); + else { + if (NM_DEVICE_GET_PRIVATE(self)->ip_state_4 != NM_DEVICE_IP_STATE_DONE) + ip_config_merge_and_apply(self, AF_INET, TRUE); + } } static void -acd_manager_probe_terminated (NMAcdManager *acd_manager, gpointer user_data) +acd_manager_probe_terminated(NMAcdManager *acd_manager, gpointer user_data) { - AcdData *data = user_data; - NMDevice *self; - NMDevicePrivate *priv; - NMDedupMultiIter ipconf_iter; - const NMPlatformIP4Address *address; - gboolean result, success = TRUE; - int i; + AcdData * data = user_data; + NMDevice * self; + NMDevicePrivate * priv; + NMDedupMultiIter ipconf_iter; + const NMPlatformIP4Address *address; + gboolean result, success = TRUE; + int i; - g_assert (data); - self = data->device; - priv = NM_DEVICE_GET_PRIVATE (self); + g_assert(data); + self = data->device; + priv = NM_DEVICE_GET_PRIVATE(self); - for (i = 0; data->configs && data->configs[i]; i++) { - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, data->configs[i], &address) { - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + for (i = 0; data->configs && data->configs[i]; i++) { + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, data->configs[i], &address) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - result = nm_acd_manager_check_address (acd_manager, address->address); - success &= result; + result = nm_acd_manager_check_address(acd_manager, address->address); + success &= result; - _NMLOG (result ? LOGL_DEBUG : LOGL_WARN, - LOGD_DEVICE, - "IPv4 DAD result: address %s is %s", - _nm_utils_inet4_ntop (address->address, sbuf), - result ? "unique" : "duplicate"); - } - } + _NMLOG(result ? LOGL_DEBUG : LOGL_WARN, + LOGD_DEVICE, + "IPv4 DAD result: address %s is %s", + _nm_utils_inet4_ntop(address->address, sbuf), + result ? "unique" : "duplicate"); + } + } - data->callback (self, data->configs, success); + data->callback(self, data->configs, success); - priv->acd.dad_list = g_slist_remove (priv->acd.dad_list, acd_manager); - nm_acd_manager_free (acd_manager); + priv->acd.dad_list = g_slist_remove(priv->acd.dad_list, acd_manager); + nm_acd_manager_free(acd_manager); } /** @@ -7549,2123 +8495,1381 @@ acd_manager_probe_terminated (NMAcdManager *acd_manager, gpointer user_data) * be started. @configs will be unreferenced after @cb has been called. */ static void -ipv4_dad_start (NMDevice *self, NMIP4Config **configs, AcdCallback cb) -{ - static const NMAcdCallbacks acd_callbacks = { - .probe_terminated_callback = acd_manager_probe_terminated, - .user_data_destroy = acd_data_destroy, - }; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMAcdManager *acd_manager; - const NMPlatformIP4Address *address; - NMDedupMultiIter ipconf_iter; - AcdData *data; - guint timeout; - gboolean addr_found; - int r; - const guint8 *hwaddr_arr; - size_t length; - guint i; - - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (configs); - g_return_if_fail (cb); - - for (i = 0, addr_found = FALSE; configs[i]; i++) { - if (nm_ip4_config_get_num_addresses (configs[i]) > 0) { - addr_found = TRUE; - break; - } - } - - timeout = get_ipv4_dad_timeout (self); - hwaddr_arr = nm_platform_link_get_address (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - &length); - - if ( !timeout - || !hwaddr_arr - || !addr_found - || length != ETH_ALEN - || nm_device_sys_iface_state_is_external_or_assume (self)) { - - /* DAD not needed, signal success */ - cb (self, configs, TRUE); - - for (i = 0; configs[i]; i++) - g_object_unref (configs[i]); - g_free (configs); - - return; - } - - data = g_slice_new0 (AcdData); - data->configs = configs; - data->callback = cb; - data->device = self; - - acd_manager = nm_acd_manager_new (nm_device_get_ip_ifindex (self), - hwaddr_arr, - length, - &acd_callbacks, - data); - priv->acd.dad_list = g_slist_append (priv->acd.dad_list, acd_manager); - - for (i = 0; configs[i]; i++) { - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, configs[i], &address) - nm_acd_manager_add_address (acd_manager, address->address); - } - - r = nm_acd_manager_start_probe (acd_manager, timeout); - if (r < 0) { - _LOGW (LOGD_DEVICE, "acd probe failed"); - - /* DAD could not be started, signal success */ - cb (self, configs, TRUE); - - priv->acd.dad_list = g_slist_remove (priv->acd.dad_list, acd_manager); - nm_acd_manager_free (acd_manager); - } +ipv4_dad_start(NMDevice *self, NMIP4Config **configs, AcdCallback cb) +{ + static const NMAcdCallbacks acd_callbacks = { + .probe_terminated_callback = acd_manager_probe_terminated, + .user_data_destroy = acd_data_destroy, + }; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMAcdManager * acd_manager; + const NMPlatformIP4Address *address; + NMDedupMultiIter ipconf_iter; + AcdData * data; + guint timeout; + gboolean addr_found; + int r; + const guint8 * hwaddr_arr; + size_t length; + guint i; + + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(configs); + g_return_if_fail(cb); + + for (i = 0, addr_found = FALSE; configs[i]; i++) { + if (nm_ip4_config_get_num_addresses(configs[i]) > 0) { + addr_found = TRUE; + break; + } + } + + timeout = _prop_get_ipv4_dad_timeout(self); + hwaddr_arr = nm_platform_link_get_address(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + &length); + + if (!timeout || !hwaddr_arr || !addr_found || length != ETH_ALEN + || nm_device_sys_iface_state_is_external_or_assume(self)) { + /* DAD not needed, signal success */ + cb(self, configs, TRUE); + + for (i = 0; configs[i]; i++) + g_object_unref(configs[i]); + g_free(configs); + + return; + } + + data = g_slice_new0(AcdData); + data->configs = configs; + data->callback = cb; + data->device = self; + + acd_manager = nm_acd_manager_new(nm_device_get_ip_ifindex(self), + hwaddr_arr, + length, + &acd_callbacks, + data); + priv->acd.dad_list = g_slist_append(priv->acd.dad_list, acd_manager); + + for (i = 0; configs[i]; i++) { + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, configs[i], &address) + nm_acd_manager_add_address(acd_manager, address->address); + } + + r = nm_acd_manager_start_probe(acd_manager, timeout); + if (r < 0) { + _LOGW(LOGD_DEVICE, "acd probe failed"); + + /* DAD could not be started, signal success */ + cb(self, configs, TRUE); + + priv->acd.dad_list = g_slist_remove(priv->acd.dad_list, acd_manager); + nm_acd_manager_free(acd_manager); + } } /*****************************************************************************/ /* IPv4LL stuff */ static void -ipv4ll_cleanup (NMDevice *self) +ipv4ll_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->ipv4ll) { - sd_ipv4ll_set_callback (priv->ipv4ll, NULL, NULL); - sd_ipv4ll_stop (priv->ipv4ll); - priv->ipv4ll = sd_ipv4ll_unref (priv->ipv4ll); - } + if (priv->ipv4ll) { + sd_ipv4ll_set_callback(priv->ipv4ll, NULL, NULL); + sd_ipv4ll_stop(priv->ipv4ll); + priv->ipv4ll = sd_ipv4ll_unref(priv->ipv4ll); + } - nm_clear_g_source (&priv->ipv4ll_timeout); + nm_clear_g_source(&priv->ipv4ll_timeout); } static NMIP4Config * -ipv4ll_get_ip4_config (NMDevice *self, guint32 lla) +ipv4ll_get_ip4_config(NMDevice *self, guint32 lla) { - NMIP4Config *config = NULL; - NMPlatformIP4Address address; - NMPlatformIP4Route route; + NMIP4Config * config = NULL; + NMPlatformIP4Address address; + NMPlatformIP4Route route; - config = nm_device_ip4_config_new (self); - g_assert (config); + config = nm_device_ip4_config_new(self); + g_assert(config); - memset (&address, 0, sizeof (address)); - nm_platform_ip4_address_set_addr (&address, lla, 16); - address.addr_source = NM_IP_CONFIG_SOURCE_IP4LL; - nm_ip4_config_add_address (config, &address); + memset(&address, 0, sizeof(address)); + nm_platform_ip4_address_set_addr(&address, lla, 16); + address.addr_source = NM_IP_CONFIG_SOURCE_IP4LL; + nm_ip4_config_add_address(config, &address); - /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */ - memset (&route, 0, sizeof (route)); - route.network = htonl (0xE0000000L); - route.plen = 4; - route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL; - route.table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (self, AF_INET)); - route.metric = nm_device_get_route_metric (self, AF_INET); - nm_ip4_config_add_route (config, &route, NULL); + /* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */ + memset(&route, 0, sizeof(route)); + route.network = htonl(0xE0000000L); + route.plen = 4; + route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL; + route.table_coerced = nm_platform_route_table_coerce(nm_device_get_route_table(self, AF_INET)); + route.metric = nm_device_get_route_metric(self, AF_INET); + nm_ip4_config_add_route(config, &route, NULL); - return config; + return config; } -#define IPV4LL_NETWORK (htonl (0xA9FE0000L)) -#define IPV4LL_NETMASK (htonl (0xFFFF0000L)) - static void -nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) -{ - NMDevice *self = data; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - struct in_addr address; - NMIP4Config *config; - int r; - - if (priv->act_request.obj == NULL) - return; - - nm_assert (nm_streq (nm_device_get_effective_ip_config_method (self, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)); - - switch (event) { - case SD_IPV4LL_EVENT_BIND: - r = sd_ipv4ll_get_address (ll, &address); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); - return; - } - - if ((address.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) { - _LOGE (LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); - return; - } - - config = ipv4ll_get_ip4_config (self, address.s_addr); - if (config == NULL) { - _LOGE (LOGD_AUTOIP4, "failed to get IPv4LL config"); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); - return; - } - - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) { - nm_clear_g_source (&priv->ipv4ll_timeout); - nm_device_activate_schedule_ip_config_result (self, AF_INET, NM_IP_CONFIG_CAST (config)); - } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { - applied_config_init (&priv->dev_ip_config_4, config); - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { - _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); - } - } else - g_assert_not_reached (); - - g_object_unref (config); - break; - default: - _LOGW (LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); - } +nm_device_handle_ipv4ll_event(sd_ipv4ll *ll, int event, void *data) +{ + NMDevice * self = data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + struct in_addr address; + NMIP4Config * config; + int r; + + if (priv->act_request.obj == NULL) + return; + + nm_assert(nm_streq(nm_device_get_effective_ip_config_method(self, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)); + + switch (event) { + case SD_IPV4LL_EVENT_BIND: + r = sd_ipv4ll_get_address(ll, &address); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "invalid IPv4 link-local address received, error %d.", r); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); + return; + } + + if (!nm_utils_ip4_address_is_link_local(address.s_addr)) { + _LOGE(LOGD_AUTOIP4, "invalid address %08x received (not link-local).", address.s_addr); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); + return; + } + + config = ipv4ll_get_ip4_config(self, address.s_addr); + if (config == NULL) { + _LOGE(LOGD_AUTOIP4, "failed to get IPv4LL config"); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); + return; + } + + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) { + nm_clear_g_source(&priv->ipv4ll_timeout); + nm_device_activate_schedule_ip_config_result(self, AF_INET, NM_IP_CONFIG_CAST(config)); + } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { + applied_config_init(&priv->dev_ip_config_4, config); + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) { + _LOGE(LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); + } + } else + g_assert_not_reached(); + + g_object_unref(config); + break; + default: + _LOGW(LOGD_AUTOIP4, "IPv4LL address no longer valid after event %d.", event); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_AUTOIP_FAILED); + } } static gboolean -ipv4ll_timeout_cb (gpointer user_data) +ipv4ll_timeout_cb(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->ipv4ll_timeout) { - _LOGI (LOGD_AUTOIP4, "IPv4LL configuration timed out."); - priv->ipv4ll_timeout = 0; - ipv4ll_cleanup (self); + if (priv->ipv4ll_timeout) { + _LOGI(LOGD_AUTOIP4, "IPv4LL configuration timed out."); + priv->ipv4ll_timeout = 0; + ipv4ll_cleanup(self); - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) - nm_device_activate_schedule_ip_config_timeout (self, AF_INET); - } + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) + nm_device_activate_schedule_ip_config_timeout(self, AF_INET); + } - return FALSE; + return FALSE; } static NMActStageReturn -ipv4ll_start (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const struct ether_addr *addr; - int ifindex, r; - size_t addr_len; - - ipv4ll_cleanup (self); - - r = sd_ipv4ll_new (&priv->ipv4ll); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: new() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - r = sd_ipv4ll_attach_event (priv->ipv4ll, NULL, 0); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: attach_event() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - ifindex = nm_device_get_ip_ifindex (self); - addr = nm_platform_link_get_address (nm_device_get_platform (self), ifindex, &addr_len); - if (!addr || addr_len != ETH_ALEN) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: can't retrieve hardware address"); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - r = sd_ipv4ll_set_mac (priv->ipv4ll, addr); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: set_mac() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - r = sd_ipv4ll_set_ifindex (priv->ipv4ll, ifindex); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: set_ifindex() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - r = sd_ipv4ll_set_callback (priv->ipv4ll, nm_device_handle_ipv4ll_event, self); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: set_callback() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - r = sd_ipv4ll_start (priv->ipv4ll); - if (r < 0) { - _LOGE (LOGD_AUTOIP4, "IPv4LL: start() failed with error %d", r); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - _LOGI (LOGD_DEVICE | LOGD_AUTOIP4, "IPv4LL: started"); - - /* Start a timeout to bound the address attempt */ - priv->ipv4ll_timeout = g_timeout_add_seconds (20, ipv4ll_timeout_cb, self); - return NM_ACT_STAGE_RETURN_POSTPONE; +ipv4ll_start(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const struct ether_addr *addr; + int ifindex, r; + size_t addr_len; + + ipv4ll_cleanup(self); + + r = sd_ipv4ll_new(&priv->ipv4ll); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: new() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + r = sd_ipv4ll_attach_event(priv->ipv4ll, NULL, 0); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: attach_event() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + ifindex = nm_device_get_ip_ifindex(self); + addr = nm_platform_link_get_address(nm_device_get_platform(self), ifindex, &addr_len); + if (!addr || addr_len != ETH_ALEN) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: can't retrieve hardware address"); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + r = sd_ipv4ll_set_mac(priv->ipv4ll, addr); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: set_mac() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + r = sd_ipv4ll_set_ifindex(priv->ipv4ll, ifindex); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: set_ifindex() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + r = sd_ipv4ll_set_callback(priv->ipv4ll, nm_device_handle_ipv4ll_event, self); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: set_callback() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + r = sd_ipv4ll_start(priv->ipv4ll); + if (r < 0) { + _LOGE(LOGD_AUTOIP4, "IPv4LL: start() failed with error %d", r); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + _LOGI(LOGD_DEVICE | LOGD_AUTOIP4, "IPv4LL: started"); + + /* Start a timeout to bound the address attempt */ + priv->ipv4ll_timeout = g_timeout_add_seconds(20, ipv4ll_timeout_cb, self); + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ static void -ensure_con_ip_config (NMDevice *self, int addr_family) +ensure_con_ip_config(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - const gboolean IS_IPv4 = (addr_family == AF_INET); - NMIPConfig *con_ip_config; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + const gboolean IS_IPv4 = (addr_family == AF_INET); + NMIPConfig * con_ip_config; - if (priv->con_ip_config_x[IS_IPv4]) - return; + if (priv->con_ip_config_x[IS_IPv4]) + return; - connection = nm_device_get_applied_connection (self); - if (!connection) - return; + connection = nm_device_get_applied_connection(self); + if (!connection) + return; - con_ip_config = nm_device_ip_config_new (self, addr_family); + con_ip_config = nm_device_ip_config_new(self, addr_family); - if (IS_IPv4) { - nm_ip4_config_merge_setting (NM_IP4_CONFIG (con_ip_config), - nm_connection_get_setting_ip4_config (connection), - _get_mdns (self), - _get_llmnr (self), - nm_device_get_route_table (self, addr_family), - nm_device_get_route_metric (self, addr_family)); - } else { - nm_ip6_config_merge_setting (NM_IP6_CONFIG (con_ip_config), - nm_connection_get_setting_ip6_config (connection), - nm_device_get_route_table (self, addr_family), - nm_device_get_route_metric (self, addr_family)); - } + if (IS_IPv4) { + nm_ip4_config_merge_setting(NM_IP4_CONFIG(con_ip_config), + nm_connection_get_setting_ip4_config(connection), + _prop_get_connection_mdns(self), + _prop_get_connection_llmnr(self), + nm_device_get_route_table(self, addr_family), + nm_device_get_route_metric(self, addr_family)); + } else { + nm_ip6_config_merge_setting(NM_IP6_CONFIG(con_ip_config), + nm_connection_get_setting_ip6_config(connection), + nm_device_get_route_table(self, addr_family), + nm_device_get_route_metric(self, addr_family)); + } - if (nm_device_sys_iface_state_is_external_or_assume (self)) { - /* For assumed connections ignore all addresses and routes. */ - nm_ip_config_reset_addresses (con_ip_config); - nm_ip_config_reset_routes (con_ip_config); - } + if (nm_device_sys_iface_state_is_external_or_assume(self)) { + /* For assumed connections ignore all addresses and routes. */ + nm_ip_config_reset_addresses(con_ip_config); + nm_ip_config_reset_routes(con_ip_config); + } - priv->con_ip_config_x[IS_IPv4] = con_ip_config; + priv->con_ip_config_x[IS_IPv4] = con_ip_config; } /*****************************************************************************/ -/* DHCPv4 stuff */ - -static guint32 -get_dhcp_timeout (NMDevice *self, int addr_family) -{ - NMDeviceClass *klass; - NMConnection *connection; - int timeout_i; - guint32 timeout; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert_addr_family (addr_family); - - connection = nm_device_get_applied_connection (self); - - timeout_i = nm_setting_ip_config_get_dhcp_timeout (nm_connection_get_setting_ip_config (connection, addr_family)); - nm_assert (timeout_i >= 0 && timeout_i <= G_MAXINT32); - - timeout = (guint32) timeout_i; - if (timeout) - goto out; - - timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.dhcp-timeout") - : NM_CON_DEFAULT ("ipv6.dhcp-timeout"), - self, - 0, G_MAXINT32, 0); - if (timeout) - goto out; - - klass = NM_DEVICE_GET_CLASS (self); - if (klass->get_dhcp_timeout_for_device) { - timeout = klass->get_dhcp_timeout_for_device (self, addr_family); - if (timeout) - goto out; - } - - timeout = NM_DHCP_TIMEOUT_DEFAULT; - -out: - G_STATIC_ASSERT_EXPR (G_MAXINT32 == NM_DHCP_TIMEOUT_INFINITY); - nm_assert (timeout > 0); - nm_assert (timeout <= G_MAXINT32); - return timeout; -} static void -dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) +dhcp4_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->dhcp_data_4.was_active = FALSE; - nm_clear_g_source (&priv->dhcp_data_4.grace_id); - priv->dhcp_data_4.grace_pending = FALSE; - nm_clear_g_free (&priv->dhcp4.pac_url); - nm_clear_g_free (&priv->dhcp4.root_path); + priv->dhcp_data_4.was_active = FALSE; + nm_clear_g_source(&priv->dhcp_data_4.grace_id); + priv->dhcp_data_4.grace_pending = FALSE; + nm_clear_g_free(&priv->dhcp4.pac_url); - if (priv->dhcp_data_4.client) { - /* Stop any ongoing DHCP transaction on this device */ - nm_clear_g_signal_handler (priv->dhcp_data_4.client, &priv->dhcp_data_4.state_sigid); + if (priv->dhcp_data_4.client) { + /* Stop any ongoing DHCP transaction on this device */ + nm_clear_g_signal_handler(priv->dhcp_data_4.client, &priv->dhcp_data_4.state_sigid); - if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE - || cleanup_type == CLEANUP_TYPE_REMOVED) - nm_dhcp_client_stop (priv->dhcp_data_4.client, release); + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) + nm_dhcp_client_stop(priv->dhcp_data_4.client, release); - g_clear_object (&priv->dhcp_data_4.client); - } + g_clear_object(&priv->dhcp_data_4.client); + } - if (priv->dhcp_data_4.config) { - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_4.config); - _notify (self, PROP_DHCP4_CONFIG); - } + if (priv->dhcp_data_4.config) { + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config); + _notify(self, PROP_DHCP4_CONFIG); + } } static gboolean -ip_config_merge_and_apply (NMDevice *self, - int addr_family, - gboolean commit) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean success; - gs_unref_object NMIPConfig *composite = NULL; - NMIPConfig *config; - gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL; - NMConnection *connection; - gboolean ignore_auto_routes = FALSE; - gboolean ignore_auto_dns = FALSE; - gboolean ignore_default_routes = FALSE; - GSList *iter; - const char *ip6_addr_gen_token = NULL; - const gboolean IS_IPv4 = (addr_family == AF_INET); - - if (nm_device_sys_iface_state_is_external (self)) - commit = FALSE; - - connection = nm_device_get_applied_connection (self); - - /* Apply ignore-auto-routes and ignore-auto-dns settings */ - if (connection) { - NMSettingIPConfig *s_ip; - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - if (s_ip) { - ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip); - ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip); - - /* if the connection has an explicit gateway, we also ignore - * the default routes from other sources. */ - ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip) - || nm_setting_ip_config_get_gateway (s_ip); - - if (!IS_IPv4) { - NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (s_ip); - - if (nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) - ip6_addr_gen_token = nm_setting_ip6_config_get_token (s_ip6); - } - } - } - - composite = nm_device_ip_config_new (self, addr_family); - - if (!IS_IPv4) { - nm_ip6_config_set_privacy (NM_IP6_CONFIG (composite), - priv->ndisc - ? priv->ndisc_use_tempaddr - : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - } - - init_ip_config_dns_priority (self, composite); - - if (commit) { - if (priv->queued_ip_config_id_x[IS_IPv4]) - update_ext_ip_config (self, addr_family, FALSE); - ensure_con_ip_config (self, addr_family); - } - - if (!IS_IPv4) { - if ( commit - && priv->ipv6ll_has) { - const NMPlatformIP6Address ll_a = { - .address = priv->ipv6ll_addr, - .plen = 64, - .addr_source = NM_IP_CONFIG_SOURCE_IP6LL, - }; - const NMPlatformIP6Route ll_r = { - .network.s6_addr16[0] = htons (0xfe80u), - .plen = 64, - .metric = nm_device_get_route_metric (self, addr_family), - .rt_source = NM_IP_CONFIG_SOURCE_IP6LL, - }; - - nm_assert (IN6_IS_ADDR_LINKLOCAL (&priv->ipv6ll_addr)); - - nm_ip6_config_add_address (NM_IP6_CONFIG (composite), &ll_a); - nm_ip6_config_add_route (NM_IP6_CONFIG (composite), &ll_r, NULL); - } - } - - if (commit) { - gboolean v; - - v = default_route_metric_penalty_detect (self, addr_family); - if (IS_IPv4) - priv->default_route_metric_penalty_ip4_has = v; - else - priv->default_route_metric_penalty_ip6_has = v; - } - - /* Merge all the IP configs into the composite config */ - - if (IS_IPv4) { - config = applied_config_get_current (&priv->dev_ip_config_4); - if (config) { - nm_ip4_config_merge (NM_IP4_CONFIG (composite), NM_IP4_CONFIG (config), - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, addr_family)); - } - } - - if (!IS_IPv4) { - config = applied_config_get_current (&priv->ac_ip6_config); - if (config) { - nm_ip6_config_merge (NM_IP6_CONFIG (composite), NM_IP6_CONFIG (config), - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, addr_family)); - } - } - - if (!IS_IPv4) { - config = applied_config_get_current (&priv->dhcp6.ip6_config); - if (config) { - nm_ip6_config_merge (NM_IP6_CONFIG (composite), NM_IP6_CONFIG (config), - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, addr_family)); - } - } - - for (iter = priv->vpn_configs_x[IS_IPv4]; iter; iter = iter->next) - nm_ip_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0); - - if (priv->ext_ip_config_x[IS_IPv4]) - nm_ip_config_merge (composite, priv->ext_ip_config_x[IS_IPv4], NM_IP_CONFIG_MERGE_EXTERNAL, 0); - - /* Merge WWAN config *last* to ensure modem-given settings overwrite - * any external stuff set by pppd or other scripts. - */ - config = applied_config_get_current (&priv->dev2_ip_config_x[IS_IPv4]); - if (config) { - nm_ip_config_merge (composite, config, - (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) - | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) - | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), - default_route_metric_penalty_get (self, addr_family)); - } - - if (!IS_IPv4) { - if (priv->rt6_temporary_not_available) { - const NMPObject *o; - GHashTableIter hiter; - - g_hash_table_iter_init (&hiter, priv->rt6_temporary_not_available); - while (g_hash_table_iter_next (&hiter, (gpointer *) &o, NULL)) { - nm_ip6_config_add_route (NM_IP6_CONFIG (composite), - NMP_OBJECT_CAST_IP6_ROUTE (o), - NULL); - } - } - } - - /* Merge user overrides into the composite config. For assumed connections, - * con_ip_config_x is empty. */ - if (priv->con_ip_config_x[IS_IPv4]) { - nm_ip_config_merge (composite, priv->con_ip_config_x[IS_IPv4], NM_IP_CONFIG_MERGE_DEFAULT, - default_route_metric_penalty_get (self, addr_family)); - } - - if (commit) { - gboolean is_vrf; - - is_vrf = priv->master && nm_device_get_device_type (priv->master) == NM_DEVICE_TYPE_VRF; - - if (IS_IPv4) { - nm_ip4_config_add_dependent_routes (NM_IP4_CONFIG (composite), - nm_device_get_route_table (self, addr_family), - nm_device_get_route_metric (self, addr_family), - is_vrf, - &ip4_dev_route_blacklist); - } else { - nm_ip6_config_add_dependent_routes (NM_IP6_CONFIG (composite), - nm_device_get_route_table (self, addr_family), - nm_device_get_route_metric (self, addr_family), - is_vrf); - } - } - - if (IS_IPv4) { - if (commit) { - if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) - NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, NM_IP4_CONFIG (composite)); - } - } - - if (!IS_IPv4) { - NMUtilsIPv6IfaceId iid; - - if ( commit - && priv->ndisc_started - && ip6_addr_gen_token - && nm_utils_ipv6_interface_identifier_get_from_token (&iid, ip6_addr_gen_token)) { - set_ipv6_token (self, iid, ip6_addr_gen_token); - } - } - - success = nm_device_set_ip_config (self, addr_family, composite, commit, ip4_dev_route_blacklist); - if (commit) { - if (IS_IPv4) - priv->v4_commit_first_time = FALSE; - else - priv->v6_commit_first_time = FALSE; - } - - return success; +ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean success; + gs_unref_object NMIPConfig *composite = NULL; + NMIPConfig * config; + gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL; + NMConnection * connection; + gboolean ignore_auto_routes = FALSE; + gboolean ignore_auto_dns = FALSE; + gboolean ignore_default_routes = FALSE; + GSList * iter; + const char * ip6_addr_gen_token = NULL; + const gboolean IS_IPv4 = (addr_family == AF_INET); + + if (nm_device_sys_iface_state_is_external(self)) + commit = FALSE; + + connection = nm_device_get_applied_connection(self); + + /* Apply ignore-auto-routes and ignore-auto-dns settings */ + if (connection) { + NMSettingIPConfig *s_ip; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (s_ip) { + ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes(s_ip); + ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns(s_ip); + + /* if the connection has an explicit gateway, we also ignore + * the default routes from other sources. */ + ignore_default_routes = nm_setting_ip_config_get_never_default(s_ip) + || nm_setting_ip_config_get_gateway(s_ip); + + if (!IS_IPv4) { + NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG(s_ip); + + if (nm_setting_ip6_config_get_addr_gen_mode(s_ip6) + == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) + ip6_addr_gen_token = nm_setting_ip6_config_get_token(s_ip6); + } + } + } + + composite = nm_device_ip_config_new(self, addr_family); + + if (!IS_IPv4) { + nm_ip6_config_set_privacy(NM_IP6_CONFIG(composite), + priv->ndisc ? priv->ndisc_use_tempaddr + : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + } + + init_ip_config_dns_priority(self, composite); + + if (commit) { + if (priv->queued_ip_config_id_x[IS_IPv4]) + update_ext_ip_config(self, addr_family, FALSE); + ensure_con_ip_config(self, addr_family); + } + + if (!IS_IPv4) { + if (commit && priv->ipv6ll_has) { + const NMPlatformIP6Address ll_a = { + .address = priv->ipv6ll_addr, + .plen = 64, + .addr_source = NM_IP_CONFIG_SOURCE_IP6LL, + }; + const NMPlatformIP6Route ll_r = { + .network.s6_addr16[0] = htons(0xfe80u), + .plen = 64, + .metric = nm_device_get_route_metric(self, addr_family), + .rt_source = NM_IP_CONFIG_SOURCE_IP6LL, + }; + + nm_assert(IN6_IS_ADDR_LINKLOCAL(&priv->ipv6ll_addr)); + + nm_ip6_config_add_address(NM_IP6_CONFIG(composite), &ll_a); + nm_ip6_config_add_route(NM_IP6_CONFIG(composite), &ll_r, NULL); + } + } + + if (commit) { + gboolean v; + + v = default_route_metric_penalty_detect(self, addr_family); + if (IS_IPv4) + priv->default_route_metric_penalty_ip4_has = v; + else + priv->default_route_metric_penalty_ip6_has = v; + } + + /* Merge all the IP configs into the composite config */ + + if (IS_IPv4) { + config = applied_config_get_current(&priv->dev_ip_config_4); + if (config) { + nm_ip4_config_merge( + NM_IP4_CONFIG(composite), + NM_IP4_CONFIG(config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get(self, addr_family)); + } + } + + if (!IS_IPv4) { + config = applied_config_get_current(&priv->ac_ip6_config); + if (config) { + nm_ip6_config_merge( + NM_IP6_CONFIG(composite), + NM_IP6_CONFIG(config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get(self, addr_family)); + } + } + + if (!IS_IPv4) { + config = applied_config_get_current(&priv->dhcp6.ip6_config); + if (config) { + nm_ip6_config_merge( + NM_IP6_CONFIG(composite), + NM_IP6_CONFIG(config), + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get(self, addr_family)); + } + } + + for (iter = priv->vpn_configs_x[IS_IPv4]; iter; iter = iter->next) + nm_ip_config_merge(composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0); + + if (priv->ext_ip_config_x[IS_IPv4]) + nm_ip_config_merge(composite, + priv->ext_ip_config_x[IS_IPv4], + NM_IP_CONFIG_MERGE_EXTERNAL, + 0); + + /* Merge WWAN config *last* to ensure modem-given settings overwrite + * any external stuff set by pppd or other scripts. + */ + config = applied_config_get_current(&priv->dev2_ip_config_x[IS_IPv4]); + if (config) { + nm_ip_config_merge(composite, + config, + (ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0) + | (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0) + | (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0), + default_route_metric_penalty_get(self, addr_family)); + } + + if (!IS_IPv4) { + if (priv->rt6_temporary_not_available) { + const NMPObject *o; + GHashTableIter hiter; + + g_hash_table_iter_init(&hiter, priv->rt6_temporary_not_available); + while (g_hash_table_iter_next(&hiter, (gpointer *) &o, NULL)) { + nm_ip6_config_add_route(NM_IP6_CONFIG(composite), + NMP_OBJECT_CAST_IP6_ROUTE(o), + NULL); + } + } + } + + /* Merge user overrides into the composite config. For assumed connections, + * con_ip_config_x is empty. */ + if (priv->con_ip_config_x[IS_IPv4]) { + nm_ip_config_merge(composite, + priv->con_ip_config_x[IS_IPv4], + NM_IP_CONFIG_MERGE_DEFAULT, + default_route_metric_penalty_get(self, addr_family)); + } + + if (commit) { + gboolean is_vrf; + + is_vrf = priv->master && nm_device_get_device_type(priv->master) == NM_DEVICE_TYPE_VRF; + + if (IS_IPv4) { + nm_ip4_config_add_dependent_routes(NM_IP4_CONFIG(composite), + nm_device_get_route_table(self, addr_family), + nm_device_get_route_metric(self, addr_family), + is_vrf, + &ip4_dev_route_blacklist); + } else { + nm_ip6_config_add_dependent_routes(NM_IP6_CONFIG(composite), + nm_device_get_route_table(self, addr_family), + nm_device_get_route_metric(self, addr_family), + is_vrf); + } + } + + if (IS_IPv4) { + if (commit) { + if (NM_DEVICE_GET_CLASS(self)->ip4_config_pre_commit) + NM_DEVICE_GET_CLASS(self)->ip4_config_pre_commit(self, NM_IP4_CONFIG(composite)); + } + } + + if (!IS_IPv4) { + NMUtilsIPv6IfaceId iid; + + if (commit && priv->ndisc_started && ip6_addr_gen_token + && nm_utils_ipv6_interface_identifier_get_from_token(&iid, ip6_addr_gen_token)) { + set_ipv6_token(self, iid, ip6_addr_gen_token); + } + } + + success = + nm_device_set_ip_config(self, addr_family, composite, commit, ip4_dev_route_blacklist); + if (commit) { + if (IS_IPv4) + priv->v4_commit_first_time = FALSE; + else + priv->v6_commit_first_time = FALSE; + } + + return success; } static gboolean -dhcp4_lease_change (NMDevice *self, NMIP4Config *config, gboolean bound) +dhcp4_lease_change(NMDevice *self, NMIP4Config *config, gboolean bound) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free_error GError *error = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free_error GError *error = NULL; - g_return_val_if_fail (config, FALSE); + g_return_val_if_fail(config, FALSE); - applied_config_init (&priv->dev_ip_config_4, config); + applied_config_init(&priv->dev_ip_config_4, config); - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { - _LOGW (LOGD_DHCP4, "failed to update IPv4 config for DHCP change."); - return FALSE; - } + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) { + _LOGW(LOGD_DHCP4, "failed to update IPv4 config for DHCP change."); + return FALSE; + } - /* TODO: we should perform DAD again whenever we obtain a - * new lease after an expiry. But what should we do if - * a duplicate address is detected? Fail the connection; - * restart DHCP; continue without an address? */ - if (bound && !nm_dhcp_client_accept (priv->dhcp_data_4.client, &error)) { - _LOGW (LOGD_DHCP4, "error accepting lease: %s", error->message); - return FALSE; - } + /* TODO: we should perform DAD again whenever we obtain a + * new lease after an expiry. But what should we do if + * a duplicate address is detected? Fail the connection; + * restart DHCP; continue without an address? */ + if (bound && !nm_dhcp_client_accept(priv->dhcp_data_4.client, &error)) { + _LOGW(LOGD_DHCP4, "error accepting lease: %s", error->message); + return FALSE; + } - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE, - self, - NULL, - NULL, NULL, NULL); + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP4_CHANGE, self, NULL, NULL, NULL, NULL); - return TRUE; + return TRUE; } static gboolean -dhcp_grace_period_expired (NMDevice *self, int addr_family) +dhcp_grace_period_expired(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); - priv->dhcp_data_x[IS_IPv4].grace_id = 0; - priv->dhcp_data_x[IS_IPv4].grace_pending = FALSE; + priv->dhcp_data_x[IS_IPv4].grace_id = 0; + priv->dhcp_data_x[IS_IPv4].grace_pending = FALSE; - _LOGI (LOGD_DHCP_from_addr_family (addr_family), - "DHCPv%c: grace period expired", - nm_utils_addr_family_to_char (addr_family)); + _LOGI(LOGD_DHCP_from_addr_family(addr_family), + "DHCPv%c: grace period expired", + nm_utils_addr_family_to_char(addr_family)); - nm_device_ip_method_failed (self, - addr_family, - NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); - /* If the device didn't fail, the DHCP client will continue */ + nm_device_ip_method_failed(self, addr_family, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + /* If the device didn't fail, the DHCP client will continue */ - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean -dhcp_grace_period_expired_4 (gpointer user_data) +dhcp_grace_period_expired_4(gpointer user_data) { - return dhcp_grace_period_expired (user_data, AF_INET); + return dhcp_grace_period_expired(user_data, AF_INET); } static gboolean -dhcp_grace_period_expired_6 (gpointer user_data) +dhcp_grace_period_expired_6(gpointer user_data) { - return dhcp_grace_period_expired (user_data, AF_INET6); + return dhcp_grace_period_expired(user_data, AF_INET6); } static gboolean -dhcp_grace_period_start (NMDevice *self, int addr_family) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - guint32 timeout; - - /* In any other case (expired lease, assumed connection, etc.), - * wait for some time before failing the IP method. - */ - if (priv->dhcp_data_x[IS_IPv4].grace_pending) { - /* already pending. */ - return FALSE; - } - - /* Start a grace period equal to the DHCP timeout multiplied - * by a constant factor. */ - timeout = get_dhcp_timeout (self, addr_family); - if (timeout == NM_DHCP_TIMEOUT_INFINITY) - _LOGI (LOGD_DHCP_from_addr_family (addr_family), - "DHCPv%c: trying to acquire a new lease", - nm_utils_addr_family_to_char (addr_family)); - else { - timeout = dhcp_grace_period_from_timeout (timeout); - _LOGI (LOGD_DHCP_from_addr_family (addr_family), - "DHCPv%c: trying to acquire a new lease within %u seconds", - nm_utils_addr_family_to_char (addr_family), - timeout); - nm_assert (!priv->dhcp_data_x[IS_IPv4].grace_id); - priv->dhcp_data_x[IS_IPv4].grace_id = g_timeout_add_seconds (timeout, - IS_IPv4 - ? dhcp_grace_period_expired_4 - : dhcp_grace_period_expired_6, - self); - } - - priv->dhcp_data_x[IS_IPv4].grace_pending = TRUE; - - return TRUE; +dhcp_grace_period_start(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + guint32 timeout; + + /* In any other case (expired lease, assumed connection, etc.), + * wait for some time before failing the IP method. + */ + if (priv->dhcp_data_x[IS_IPv4].grace_pending) { + /* already pending. */ + return FALSE; + } + + /* Start a grace period equal to the DHCP timeout multiplied + * by a constant factor. */ + timeout = _prop_get_ipvx_dhcp_timeout(self, addr_family); + if (timeout == NM_DHCP_TIMEOUT_INFINITY) + _LOGI(LOGD_DHCP_from_addr_family(addr_family), + "DHCPv%c: trying to acquire a new lease", + nm_utils_addr_family_to_char(addr_family)); + else { + timeout = dhcp_grace_period_from_timeout(timeout); + _LOGI(LOGD_DHCP_from_addr_family(addr_family), + "DHCPv%c: trying to acquire a new lease within %u seconds", + nm_utils_addr_family_to_char(addr_family), + timeout); + nm_assert(!priv->dhcp_data_x[IS_IPv4].grace_id); + priv->dhcp_data_x[IS_IPv4].grace_id = g_timeout_add_seconds( + timeout, + IS_IPv4 ? dhcp_grace_period_expired_4 : dhcp_grace_period_expired_6, + self); + } + + priv->dhcp_data_x[IS_IPv4].grace_pending = TRUE; + + return TRUE; } static void -dhcp4_fail (NMDevice *self, NMDhcpState dhcp_state) +dhcp4_fail(NMDevice *self, NMDhcpState dhcp_state) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - _LOGD (LOGD_DHCP4, "DHCPv4 failed (ip_state %s, was_active %d)", - _ip_state_to_string (priv->ip_state_4), - priv->dhcp_data_4.was_active); + _LOGD(LOGD_DHCP4, + "DHCPv4 failed (ip_state %s, was_active %d)", + _ip_state_to_string(priv->ip_state_4), + priv->dhcp_data_4.was_active); - /* The client is always left running after a failure. */ + /* The client is always left running after a failure. */ - /* Nothing to do if we failed before... */ - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL) - goto clear_config; + /* Nothing to do if we failed before... */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL) + goto clear_config; - /* ... and also if there are static addresses configured - * on the interface. - */ - if ( priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE - && priv->con_ip_config_4 - && nm_ip4_config_get_num_addresses (priv->con_ip_config_4) > 0) - goto clear_config; + /* ... and also if there are static addresses configured + * on the interface. + */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && priv->con_ip_config_4 + && nm_ip4_config_get_num_addresses(priv->con_ip_config_4) > 0) + goto clear_config; - /* Fail the method when one of the following is true: - * 1) the DHCP client terminated: it does not make sense to start a grace - * period without a client running; - * 2) we failed to get an initial lease AND the client was - * not active before. - */ - if ( dhcp_state == NM_DHCP_STATE_TERMINATED - || (!priv->dhcp_data_4.was_active && priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF)) { - nm_device_activate_schedule_ip_config_timeout (self, AF_INET); - return; - } + /* Fail the method when one of the following is true: + * 1) the DHCP client terminated: it does not make sense to start a grace + * period without a client running; + * 2) we failed to get an initial lease AND the client was + * not active before. + */ + if (dhcp_state == NM_DHCP_STATE_TERMINATED + || (!priv->dhcp_data_4.was_active && priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF)) { + nm_device_activate_schedule_ip_config_timeout(self, AF_INET); + return; + } - if (dhcp_grace_period_start (self, AF_INET)) - goto clear_config; + if (dhcp_grace_period_start(self, AF_INET)) + goto clear_config; - return; + return; clear_config: - /* The previous configuration is no longer valid */ - if (priv->dhcp_data_4.config) { - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_4.config); - priv->dhcp_data_4.config = nm_dhcp_config_new (AF_INET); - _notify (self, PROP_DHCP4_CONFIG); - } + /* The previous configuration is no longer valid */ + if (priv->dhcp_data_4.config) { + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config); + priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET); + _notify(self, PROP_DHCP4_CONFIG); + } } static void -dhcp4_dad_cb (NMDevice *self, NMIP4Config **configs, gboolean success) +dhcp4_dad_cb(NMDevice *self, NMIP4Config **configs, gboolean success) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (success) { - nm_device_activate_schedule_ip_config_result (self, AF_INET, - NM_IP_CONFIG_CAST (configs[1])); - } else { - nm_dhcp_client_decline (priv->dhcp_data_4.client, "Address conflict detected", NULL); - nm_device_ip_method_failed (self, AF_INET, - NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); - } + if (success) { + nm_device_activate_schedule_ip_config_result(self, AF_INET, NM_IP_CONFIG_CAST(configs[1])); + } else { + nm_dhcp_client_decline(priv->dhcp_data_4.client, "Address conflict detected", NULL); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); + } } static void -dhcp4_state_changed (NMDhcpClient *client, - NMDhcpState state, - NMIP4Config *ip4_config, - GHashTable *options, - const char *event_id, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMIP4Config *manual, **configs; - NMConnection *connection; - - g_return_if_fail (nm_dhcp_client_get_addr_family (client) == AF_INET); - g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config)); - - _LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state); - - switch (state) { - case NM_DHCP_STATE_BOUND: - case NM_DHCP_STATE_EXTENDED: - if (!ip4_config) { - _LOGW (LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event."); - dhcp4_fail (self, state); - break; - } - - nm_clear_g_source (&priv->dhcp_data_4.grace_id); - priv->dhcp_data_4.grace_pending = FALSE; - - /* After some failures, we have been able to renew the lease: - * update the ip state - */ - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL) - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_CONF); - - g_free (priv->dhcp4.pac_url); - priv->dhcp4.pac_url = g_strdup (g_hash_table_lookup (options, "wpad")); - nm_device_set_proxy_config (self, priv->dhcp4.pac_url); - - g_free (priv->dhcp4.root_path); - priv->dhcp4.root_path = g_strdup (g_hash_table_lookup (options, "root_path")); - - nm_dhcp_config_set_options (priv->dhcp_data_4.config, options); - _notify (self, PROP_DHCP4_CONFIG); - - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) { - connection = nm_device_get_applied_connection (self); - g_assert (connection); - - manual = nm_device_ip4_config_new (self); - nm_ip4_config_merge_setting (manual, - nm_connection_get_setting_ip4_config (connection), - NM_SETTING_CONNECTION_MDNS_DEFAULT, - NM_SETTING_CONNECTION_LLMNR_DEFAULT, - nm_device_get_route_table (self, AF_INET), - nm_device_get_route_metric (self, AF_INET)); - - configs = g_new0 (NMIP4Config *, 3); - configs[0] = manual; - configs[1] = g_object_ref (ip4_config); - - ipv4_dad_start (self, configs, dhcp4_dad_cb); - } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { - if (dhcp4_lease_change (self, ip4_config, - state == NM_DHCP_STATE_BOUND)) - nm_device_update_metered (self); - else - dhcp4_fail (self, state); - } - break; - case NM_DHCP_STATE_TIMEOUT: - dhcp4_fail (self, state); - break; - case NM_DHCP_STATE_EXPIRE: - /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) - break; - /* fall-through */ - case NM_DHCP_STATE_DONE: - case NM_DHCP_STATE_FAIL: - case NM_DHCP_STATE_TERMINATED: - dhcp4_fail (self, state); - break; - default: - break; - } -} - -/** - * dhcp_get_iaid: - * @self: the #NMDevice - * @addr_family: the address family - * @connection: the connection - * @out_is_explicit: on return, %TRUE if the user set a valid IAID in - * the connection or in global configuration; %FALSE if the connection - * property was empty and no valid global configuration was provided. - * - * Returns: a IAID value for this device and the given connection. - */ -static guint32 -dhcp_get_iaid (NMDevice *self, - int addr_family, - NMConnection *connection, - gboolean *out_is_explicit) -{ - NMSettingIPConfig *s_ip; - const char *iaid_str; - gs_free char *iaid_str_free = NULL; - guint32 iaid; - const char *iface; - const char *fail_reason; - gboolean is_explicit = TRUE; - - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - iaid_str = nm_setting_ip_config_get_dhcp_iaid (s_ip); - if (!iaid_str) { - iaid_str_free = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.dhcp-iaid") - : NM_CON_DEFAULT ("ipv6.dhcp-iaid"), - self); - iaid_str = iaid_str_free; - if (!iaid_str) { - iaid_str = NM_IAID_IFNAME; - is_explicit = FALSE; - } else if (!_nm_utils_iaid_verify (iaid_str, NULL)) { - _LOGW (LOGD_DEVICE, "invalid global default '%s' for ipv%c.dhcp-iaid", - iaid_str, - nm_utils_addr_family_to_char (addr_family)); - iaid_str = NM_IAID_IFNAME; - is_explicit = FALSE; - } - } - - if (nm_streq0 (iaid_str, NM_IAID_MAC)) { - const NMPlatformLink *pllink; - - pllink = nm_platform_link_get (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self)); - if (!pllink || pllink->l_address.len < 4) { - fail_reason = "invalid link-layer address"; - goto out_fail; - } - - /* @iaid is in native endianness. Use unaligned_read_be32() - * so that the IAID for a given MAC address is the same on - * BE and LE machines. */ - iaid = unaligned_read_be32 (&pllink->l_address.data[pllink->l_address.len - 4]); - goto out_good; - } else if (nm_streq0 (iaid_str, NM_IAID_PERM_MAC)) { - guint8 hwaddr_buf[NM_UTILS_HWADDR_LEN_MAX]; - const char *hwaddr_str; - gsize hwaddr_len; - - hwaddr_str = nm_device_get_permanent_hw_address (self); - if (!hwaddr_str) { - fail_reason = "no permanent link-layer address"; - goto out_fail; - } - - if (!_nm_utils_hwaddr_aton (hwaddr_str, hwaddr_buf, sizeof (hwaddr_buf), &hwaddr_len)) - g_return_val_if_reached (0); - - if (hwaddr_len < 4) { - fail_reason = "invalid link-layer address"; - goto out_fail; - } - - iaid = unaligned_read_be32 (&hwaddr_buf[hwaddr_len - 4]); - goto out_good; - } else if (nm_streq (iaid_str, "stable")) { - nm_auto_free_checksum GChecksum *sum = NULL; - guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1]; - NMUtilsStableType stable_type; - const char *stable_id; - guint32 salted_header; - const guint8 *host_id; - gsize host_id_len; - - stable_id = _get_stable_id (self, connection, &stable_type); - salted_header = htonl (53390459 + stable_type); - nm_utils_host_id_get (&host_id, &host_id_len); - iface = nm_device_get_ip_iface (self); - - sum = g_checksum_new (G_CHECKSUM_SHA1); - g_checksum_update (sum, (const guchar *) &salted_header, sizeof (salted_header)); - g_checksum_update (sum, (const guchar *) stable_id, strlen (stable_id) + 1); - g_checksum_update (sum, (const guchar *) iface, strlen (iface) + 1); - g_checksum_update (sum, (const guchar *) host_id, host_id_len); - nm_utils_checksum_get_digest (sum, digest); - - iaid = unaligned_read_be32 (digest); - goto out_good; - } else if ((iaid = _nm_utils_ascii_str_to_int64 (iaid_str, 10, 0, G_MAXUINT32, -1)) != -1) { - goto out_good; - } else { - iface = nm_device_get_ip_iface (self); - iaid = nm_utils_create_dhcp_iaid (TRUE, - (const guint8 *) iface, - strlen (iface)); - goto out_good; - } - -out_fail: - nm_assert (fail_reason); - _LOGW ( addr_family == AF_INET - ? (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4) - : (LOGD_DEVICE | LOGD_DHCP6 | LOGD_IP6), - "ipv%c.dhcp-iaid: failure to generate IAID: %s. Using interface-name based IAID", - nm_utils_addr_family_to_char (addr_family), fail_reason); - is_explicit = FALSE; - iface = nm_device_get_ip_iface (self); - iaid = nm_utils_create_dhcp_iaid (TRUE, - (const guint8 *) iface, - strlen (iface)); -out_good: - _LOGD ( addr_family == AF_INET - ? (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4) - : (LOGD_DEVICE | LOGD_DHCP6 | LOGD_IP6), - "ipv%c.dhcp-iaid: using %u (0x%08x) IAID (str: '%s', explicit %d)", - nm_utils_addr_family_to_char (addr_family), iaid, iaid, - iaid_str, is_explicit); - NM_SET_OUT (out_is_explicit, is_explicit); - return iaid; +dhcp4_state_changed(NMDhcpClient *client, + NMDhcpState state, + NMIP4Config * ip4_config, + GHashTable * options, + gpointer user_data) +{ + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMIP4Config * manual, **configs; + NMConnection * connection; + + g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET); + g_return_if_fail(!ip4_config || NM_IS_IP4_CONFIG(ip4_config)); + + _LOGD(LOGD_DHCP4, "new DHCPv4 client state %d", state); + + switch (state) { + case NM_DHCP_STATE_BOUND: + case NM_DHCP_STATE_EXTENDED: + if (!ip4_config) { + _LOGW(LOGD_DHCP4, "failed to get IPv4 config in response to DHCP event."); + dhcp4_fail(self, state); + break; + } + + nm_clear_g_source(&priv->dhcp_data_4.grace_id); + priv->dhcp_data_4.grace_pending = FALSE; + + /* After some failures, we have been able to renew the lease: + * update the ip state + */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL) + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_CONF); + + g_free(priv->dhcp4.pac_url); + priv->dhcp4.pac_url = g_strdup(g_hash_table_lookup(options, "wpad")); + nm_device_set_proxy_config(self, priv->dhcp4.pac_url); + + nm_dhcp_config_set_options(priv->dhcp_data_4.config, options); + _notify(self, PROP_DHCP4_CONFIG); + + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) { + connection = nm_device_get_applied_connection(self); + g_assert(connection); + + manual = nm_device_ip4_config_new(self); + nm_ip4_config_merge_setting(manual, + nm_connection_get_setting_ip4_config(connection), + NM_SETTING_CONNECTION_MDNS_DEFAULT, + NM_SETTING_CONNECTION_LLMNR_DEFAULT, + nm_device_get_route_table(self, AF_INET), + nm_device_get_route_metric(self, AF_INET)); + + configs = g_new0(NMIP4Config *, 3); + configs[0] = manual; + configs[1] = g_object_ref(ip4_config); + + ipv4_dad_start(self, configs, dhcp4_dad_cb); + } else if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { + if (dhcp4_lease_change(self, ip4_config, state == NM_DHCP_STATE_BOUND)) + nm_device_update_metered(self); + else + dhcp4_fail(self, state); + } + break; + case NM_DHCP_STATE_TIMEOUT: + dhcp4_fail(self, state); + break; + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_CONF) + break; + /* fall-through */ + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: + case NM_DHCP_STATE_TERMINATED: + dhcp4_fail(self, state); + break; + default: + break; + } } -static NMDhcpHostnameFlags -get_dhcp_hostname_flags (NMDevice *self, int addr_family) -{ - NMConnection *connection; - NMSettingIPConfig *s_ip; - NMDhcpHostnameFlags flags; - gs_free_error GError *error = NULL; - - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DHCP_HOSTNAME_FLAG_NONE); - - connection = nm_device_get_applied_connection (self); - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - g_return_val_if_fail (s_ip, NM_DHCP_HOSTNAME_FLAG_NONE); - - if (!nm_setting_ip_config_get_dhcp_send_hostname (s_ip)) - return NM_DHCP_HOSTNAME_FLAG_NONE; - - flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip); - if (flags != NM_DHCP_HOSTNAME_FLAG_NONE) - return flags; - - flags = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? NM_CON_DEFAULT ("ipv4.dhcp-hostname-flags") - : NM_CON_DEFAULT ("ipv6.dhcp-hostname-flags"), - self, - 0, NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS, - 0); - - if (!_nm_utils_validate_dhcp_hostname_flags (flags, addr_family, &error)) { - _LOGW (LOGD_DEVICE, "invalid global default value 0x%x for ipv%d.%s: %s", - (guint) flags, - addr_family == AF_INET ? 4 : 6, - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, - error->message); - flags = NM_DHCP_HOSTNAME_FLAG_NONE; - } - - if (flags != NM_DHCP_HOSTNAME_FLAG_NONE) - return flags; - - if (addr_family == AF_INET) - return NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP4; - else - return NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP6; +static NMActStageReturn +dhcp4_start(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingIPConfig *s_ip4; + gs_unref_bytes GBytes *vendor_class_identifier = NULL; + gs_unref_bytes GBytes *hwaddr = NULL; + gs_unref_bytes GBytes *bcast_hwaddr = NULL; + gs_unref_bytes GBytes *client_id = NULL; + gs_free char * mud_url_free = NULL; + NMConnection * connection; + NMSettingConnection * s_con; + GError * error = NULL; + const NMPlatformLink * pllink; + const char *const * reject_servers; + + connection = nm_device_get_applied_connection(self); + g_return_val_if_fail(connection, FALSE); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + + s_con = nm_connection_get_setting_connection(connection); + nm_assert(s_con); + + /* Clear old exported DHCP options */ + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config); + priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET); + + pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + if (pllink) { + hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address); + bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast); + } + + client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr); + vendor_class_identifier = + _prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip4)); + reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip4, NULL); + + g_warn_if_fail(priv->dhcp_data_4.client == NULL); + priv->dhcp_data_4.client = + nm_dhcp_manager_start_ip4(nm_dhcp_manager_get(), + nm_netns_get_multi_idx(nm_device_get_netns(self)), + nm_device_get_ip_iface(self), + nm_device_get_ip_ifindex(self), + hwaddr, + bcast_hwaddr, + nm_connection_get_uuid(connection), + nm_device_get_route_table(self, AF_INET), + nm_device_get_route_metric(self, AF_INET), + nm_setting_ip_config_get_dhcp_send_hostname(s_ip4), + nm_setting_ip_config_get_dhcp_hostname(s_ip4), + nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)), + _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET), + _prop_get_connection_mud_url(self, s_con, &mud_url_free), + client_id, + _prop_get_ipvx_dhcp_timeout(self, AF_INET), + priv->dhcp_anycast_address, + NULL, + vendor_class_identifier, + reject_servers, + &error); + if (!priv->dhcp_data_4.client) { + _LOGW(LOGD_DHCP4, "failure to start DHCP: %s", error->message); + g_clear_error(&error); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv->dhcp_data_4.state_sigid = g_signal_connect(priv->dhcp_data_4.client, + NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, + G_CALLBACK(dhcp4_state_changed), + self); + + if (nm_device_sys_iface_state_is_external_or_assume(self)) + priv->dhcp_data_4.was_active = TRUE; + + /* DHCP devices will be notified by the DHCP manager when stuff happens */ + return NM_ACT_STAGE_RETURN_POSTPONE; } -static const char * -connection_get_mud_url (NMDevice *self, - NMSettingConnection *s_con, - char **out_mud_url) +gboolean +nm_device_dhcp4_renew(NMDevice *self, gboolean release) { - const char *mud_url; - gs_free char *s = NULL; - - nm_assert (out_mud_url && !*out_mud_url); - - mud_url = nm_setting_connection_get_mud_url (s_con); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (mud_url) { - if (nm_streq (mud_url, NM_CONNECTION_MUD_URL_NONE)) - return NULL; - return mud_url; - } + g_return_val_if_fail(priv->dhcp_data_4.client != NULL, FALSE); - s = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.mud-url"), - self); - if (s) { - if (nm_streq (s, NM_CONNECTION_MUD_URL_NONE)) - return NULL; - if (nm_sd_http_url_is_valid_https (s)) - return (*out_mud_url = g_steal_pointer (&s)); - } + _LOGI(LOGD_DHCP4, "DHCPv4 lease renewal requested"); - return NULL; -} - -static GBytes * -dhcp4_get_client_id (NMDevice *self, - NMConnection *connection, - GBytes *hwaddr) -{ - NMSettingIPConfig *s_ip4; - const char *client_id; - gs_free char *client_id_default = NULL; - guint8 *client_id_buf; - const char *fail_reason; - guint8 hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX]; - const guint8 *hwaddr_bin; - int arp_type; - gsize hwaddr_len; - GBytes *result; - gs_free char *logstr1 = NULL; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - client_id = nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)); - - if (!client_id) { - client_id_default = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ipv4.dhcp-client-id"), - self); - if (client_id_default && client_id_default[0]) { - /* a non-empty client-id is always valid, see nm_dhcp_utils_client_id_string_to_bytes(). */ - client_id = client_id_default; - } - } - - if (!client_id) { - _LOGD (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, - "ipv4.dhcp-client-id: no explicit client-id configured"); - return NULL; - } - - if (nm_streq (client_id, "mac")) { - if (!hwaddr) { - fail_reason = "missing link-layer address"; - goto out_fail; - } - - hwaddr_bin = g_bytes_get_data (hwaddr, &hwaddr_len); - arp_type = nm_utils_arp_type_detect_from_hwaddrlen (hwaddr_len); - if (arp_type < 0) { - fail_reason = "unsupported link-layer address"; - goto out_fail; - } - - result = nm_utils_dhcp_client_id_mac (arp_type, hwaddr_bin, hwaddr_len); - goto out_good; - } - - if (nm_streq (client_id, "perm-mac")) { - const char *hwaddr_str; - - hwaddr_str = nm_device_get_permanent_hw_address (self); - if (!hwaddr_str) { - fail_reason = "missing permanent link-layer address"; - goto out_fail; - } - - if (!_nm_utils_hwaddr_aton (hwaddr_str, hwaddr_bin_buf, sizeof (hwaddr_bin_buf), &hwaddr_len)) - g_return_val_if_reached (NULL); - - arp_type = nm_utils_arp_type_detect_from_hwaddrlen (hwaddr_len); - if (arp_type < 0) { - fail_reason = "unsupported permanent link-layer address"; - goto out_fail; - } - - result = nm_utils_dhcp_client_id_mac (arp_type, hwaddr_bin_buf, hwaddr_len); - goto out_good; - } - - if (nm_streq (client_id, "duid")) { - guint32 iaid = dhcp_get_iaid (self, AF_INET, connection, NULL); - - result = nm_utils_dhcp_client_id_systemd_node_specific (iaid); - goto out_good; - } - - if (nm_streq (client_id, "stable")) { - nm_auto_free_checksum GChecksum *sum = NULL; - guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1]; - NMUtilsStableType stable_type; - const char *stable_id; - guint32 salted_header; - const guint8 *host_id; - gsize host_id_len; - - stable_id = _get_stable_id (self, connection, &stable_type); - salted_header = htonl (2011610591 + stable_type); - nm_utils_host_id_get (&host_id, &host_id_len); - - sum = g_checksum_new (G_CHECKSUM_SHA1); - g_checksum_update (sum, (const guchar *) &salted_header, sizeof (salted_header)); - g_checksum_update (sum, (const guchar *) stable_id, strlen (stable_id) + 1); - g_checksum_update (sum, (const guchar *) host_id, host_id_len); - nm_utils_checksum_get_digest (sum, digest); - - client_id_buf = g_malloc (1 + 15); - client_id_buf[0] = 0; - memcpy (&client_id_buf[1], digest, 15); - result = g_bytes_new_take (client_id_buf, 1 + 15); - goto out_good; - } - - result = nm_dhcp_utils_client_id_string_to_bytes (client_id); - goto out_good; - -out_fail: - nm_assert (fail_reason); - _LOGW (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, - "ipv4.dhcp-client-id: failure to generate client id (%s). Use random client id", - fail_reason); - client_id_buf = g_malloc (1 + 15); - client_id_buf[0] = 0; - nm_utils_random_bytes (&client_id_buf[1], 15); - result = g_bytes_new_take (client_id_buf, 1 + 15); + /* Terminate old DHCP instance and release the old lease */ + dhcp4_cleanup(self, CLEANUP_TYPE_DECONFIGURE, release); -out_good: - nm_assert (result); - _LOGD (LOGD_DEVICE | LOGD_DHCP4 | LOGD_IP4, - "ipv4.dhcp-client-id: use \"%s\" client ID: %s", - client_id, - (logstr1 = nm_dhcp_utils_duid_to_string (result))); - return result; + /* Start DHCP again on the interface */ + return dhcp4_start(self) != NM_ACT_STAGE_RETURN_FAILURE; } -static NMActStageReturn -dhcp4_start (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingIPConfig *s_ip4; - gs_unref_bytes GBytes *hwaddr = NULL; - gs_unref_bytes GBytes *bcast_hwaddr = NULL; - gs_unref_bytes GBytes *client_id = NULL; - gs_free char *mud_url_free = NULL; - NMConnection *connection; - NMSettingConnection *s_con; - GError *error = NULL; - const NMPlatformLink *pllink; - - connection = nm_device_get_applied_connection (self); - g_return_val_if_fail (connection, FALSE); - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - - s_con = nm_connection_get_setting_connection (connection); - nm_assert (s_con); - - /* Clear old exported DHCP options */ - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_4.config); - priv->dhcp_data_4.config = nm_dhcp_config_new (AF_INET); - - pllink = nm_platform_link_get (nm_device_get_platform (self), nm_device_get_ip_ifindex (self)); - if (pllink) { - hwaddr = nmp_link_address_get_as_bytes (&pllink->l_address); - bcast_hwaddr = nmp_link_address_get_as_bytes (&pllink->l_broadcast); - } - - client_id = dhcp4_get_client_id (self, connection, hwaddr); - - g_warn_if_fail (priv->dhcp_data_4.client == NULL); - priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), - nm_netns_get_multi_idx (nm_device_get_netns (self)), - nm_device_get_ip_iface (self), - nm_device_get_ip_ifindex (self), - hwaddr, - bcast_hwaddr, - nm_connection_get_uuid (connection), - nm_device_get_route_table (self, AF_INET), - nm_device_get_route_metric (self, AF_INET), - nm_setting_ip_config_get_dhcp_send_hostname (s_ip4), - nm_setting_ip_config_get_dhcp_hostname (s_ip4), - nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)), - get_dhcp_hostname_flags (self, AF_INET), - connection_get_mud_url (self, s_con, &mud_url_free), - client_id, - get_dhcp_timeout (self, AF_INET), - priv->dhcp_anycast_address, - NULL, - &error); - if (!priv->dhcp_data_4.client) { - _LOGW (LOGD_DHCP4, "failure to start DHCP: %s", error->message); - g_clear_error (&error); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - priv->dhcp_data_4.state_sigid = g_signal_connect (priv->dhcp_data_4.client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK (dhcp4_state_changed), - self); - - if (nm_device_sys_iface_state_is_external_or_assume (self)) - priv->dhcp_data_4.was_active = TRUE; - - /* DHCP devices will be notified by the DHCP manager when stuff happens */ - return NM_ACT_STAGE_RETURN_POSTPONE; -} +/*****************************************************************************/ -gboolean -nm_device_dhcp4_renew (NMDevice *self, gboolean release) +static NMIP4Config * +shared4_new_config(NMDevice *self, NMConnection *connection) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - g_return_val_if_fail (priv->dhcp_data_4.client != NULL, FALSE); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMIP4Config * config; + NMSettingIPConfig * s_ip4; + NMPlatformIP4Address address = { + .addr_source = NM_IP_CONFIG_SOURCE_SHARED, + }; - _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested"); + g_return_val_if_fail(self, NULL); + g_return_val_if_fail(connection, NULL); - /* Terminate old DHCP instance and release the old lease */ - dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release); - - /* Start DHCP again on the interface */ - return dhcp4_start (self) != NM_ACT_STAGE_RETURN_FAILURE; -} - -/*****************************************************************************/ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (s_ip4 && nm_setting_ip_config_get_num_addresses(s_ip4) > 0) { + /* Use the first user-supplied address */ + NMIPAddress *user = nm_setting_ip_config_get_address(s_ip4, 0); + in_addr_t a; -static GHashTable *shared_ips = NULL; + nm_ip_address_get_address_binary(user, &a); + nm_platform_ip4_address_set_addr(&address, a, nm_ip_address_get_prefix(user)); + nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release); + } else { + if (!priv->shared_ip_handle) + priv->shared_ip_handle = nm_netns_shared_ip_reserve(nm_device_get_netns(self)); + nm_platform_ip4_address_set_addr(&address, priv->shared_ip_handle->addr, 24); + } -static void -shared_ip_release (gpointer data) -{ - g_hash_table_remove (shared_ips, data); - if (!g_hash_table_size (shared_ips)) - nm_clear_pointer (&shared_ips, g_hash_table_unref); -} + config = nm_device_ip4_config_new(self); + nm_ip4_config_add_address(config, &address); -static NMIP4Config * -shared4_new_config (NMDevice *self, NMConnection *connection) -{ - NMIP4Config *config = NULL; - gboolean is_generated = FALSE; - NMSettingIPConfig *s_ip4; - NMPlatformIP4Address address = { - .addr_source = NM_IP_CONFIG_SOURCE_SHARED, - }; - - g_return_val_if_fail (self, NULL); - g_return_val_if_fail (connection, NULL); - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4 && nm_setting_ip_config_get_num_addresses (s_ip4)) { - /* Use the first user-supplied address */ - NMIPAddress *user = nm_setting_ip_config_get_address (s_ip4, 0); - in_addr_t a; - - nm_ip_address_get_address_binary (user, &a); - nm_platform_ip4_address_set_addr (&address, a, nm_ip_address_get_prefix (user)); - } else { - /* Find an unused address in the 10.42.x.x range */ - guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */ - guint32 count = 0; - - if (G_UNLIKELY (!shared_ips)) - shared_ips = g_hash_table_new (nm_direct_hash, NULL); - else { - while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) { - count += ntohl (0x100); - if (count > ntohl (0xFE00)) { - _LOGE (LOGD_SHARING, "ran out of shared IP addresses!"); - return FALSE; - } - } - } - nm_platform_ip4_address_set_addr (&address, start + count, 24); - g_hash_table_add (shared_ips, GUINT_TO_POINTER (address.address)); - is_generated = TRUE; - } - - config = nm_device_ip4_config_new (self); - nm_ip4_config_add_address (config, &address); - if (is_generated) { - /* Remove the address lock when the object gets disposed */ - g_object_set_qdata_full (G_OBJECT (config), NM_CACHED_QUARK ("shared-ip"), - GUINT_TO_POINTER (address.address), - shared_ip_release); - } - return config; + return config; } /*****************************************************************************/ static gboolean -connection_ip_method_requires_carrier (NMConnection *connection, - int addr_family, - gboolean *out_ip_enabled) +connection_ip_method_requires_carrier(NMConnection *connection, + int addr_family, + gboolean * out_ip_enabled) { - const char *method; + const char *method; - method = nm_utils_get_ip_config_method (connection, addr_family); + method = nm_utils_get_ip_config_method(connection, addr_family); - if (addr_family == AF_INET) { - NM_SET_OUT (out_ip_enabled, !nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)); - return NM_IN_STRSET (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL); - } + if (addr_family == AF_INET) { + NM_SET_OUT(out_ip_enabled, !nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)); + return NM_IN_STRSET(method, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL); + } - NM_SET_OUT (out_ip_enabled, - !NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)); - return NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_DHCP, - NM_SETTING_IP6_CONFIG_METHOD_SHARED, - NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL); + NM_SET_OUT(out_ip_enabled, + !NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)); + return NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_SHARED, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL); } static gboolean -connection_requires_carrier (NMConnection *connection) -{ - NMSettingIPConfig *s_ip4, *s_ip6; - NMSettingConnection *s_con; - gboolean ip4_carrier_wanted, ip6_carrier_wanted; - gboolean ip4_used = FALSE, ip6_used = FALSE; - - /* We can progress to IP_CONFIG now, so that we're enslaved. - * That may actually cause carrier to go up and thus continue acivation. */ - s_con = nm_connection_get_setting_connection (connection); - if (nm_setting_connection_get_master (s_con)) - return FALSE; - - ip4_carrier_wanted = connection_ip_method_requires_carrier (connection, AF_INET, &ip4_used); - if (ip4_carrier_wanted) { - /* If IPv4 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv6 method. - */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4 && !nm_setting_ip_config_get_may_fail (s_ip4)) - return TRUE; - } - - ip6_carrier_wanted = connection_ip_method_requires_carrier (connection, AF_INET6, &ip6_used); - if (ip6_carrier_wanted) { - /* If IPv6 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv4 method. - */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6 && !nm_setting_ip_config_get_may_fail (s_ip6)) - return TRUE; - } - - /* If an IP version wants a carrier and the other IP version isn't - * used, the connection requires carrier since it will just fail without one. - */ - if (ip4_carrier_wanted && !ip6_used) - return TRUE; - if (ip6_carrier_wanted && !ip4_used) - return TRUE; - - /* If both want a carrier, the whole connection wants a carrier */ - return ip4_carrier_wanted && ip6_carrier_wanted; +connection_requires_carrier(NMConnection *connection) +{ + NMSettingIPConfig * s_ip4, *s_ip6; + NMSettingConnection *s_con; + gboolean ip4_carrier_wanted, ip6_carrier_wanted; + gboolean ip4_used = FALSE, ip6_used = FALSE; + + /* We can progress to IP_CONFIG now, so that we're enslaved. + * That may actually cause carrier to go up and thus continue activation. */ + s_con = nm_connection_get_setting_connection(connection); + if (nm_setting_connection_get_master(s_con)) + return FALSE; + + ip4_carrier_wanted = connection_ip_method_requires_carrier(connection, AF_INET, &ip4_used); + if (ip4_carrier_wanted) { + /* If IPv4 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv6 method. + */ + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (s_ip4 && !nm_setting_ip_config_get_may_fail(s_ip4)) + return TRUE; + } + + ip6_carrier_wanted = connection_ip_method_requires_carrier(connection, AF_INET6, &ip6_used); + if (ip6_carrier_wanted) { + /* If IPv6 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv4 method. + */ + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (s_ip6 && !nm_setting_ip_config_get_may_fail(s_ip6)) + return TRUE; + } + + /* If an IP version wants a carrier and the other IP version isn't + * used, the connection requires carrier since it will just fail without one. + */ + if (ip4_carrier_wanted && !ip6_used) + return TRUE; + if (ip6_carrier_wanted && !ip4_used) + return TRUE; + + /* If both want a carrier, the whole connection wants a carrier */ + return ip4_carrier_wanted && ip6_carrier_wanted; } static gboolean -have_any_ready_slaves (NMDevice *self) +have_any_ready_slaves(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - SlaveInfo *info; - CList *iter; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + SlaveInfo * info; + CList * iter; - /* Any enslaved slave is "ready" in the generic case as it's - * at least >= NM_DEVCIE_STATE_IP_CONFIG and has had Layer 2 - * properties set up. - */ - c_list_for_each (iter, &priv->slaves) { - info = c_list_entry (iter, SlaveInfo, lst_slave); - if (NM_DEVICE_GET_PRIVATE (info->slave)->is_enslaved) - return TRUE; - } - return FALSE; + /* Any enslaved slave is "ready" in the generic case as it's + * at least >= NM_DEVCIE_STATE_IP_CONFIG and has had Layer 2 + * properties set up. + */ + c_list_for_each (iter, &priv->slaves) { + info = c_list_entry(iter, SlaveInfo, lst_slave); + if (NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved) + return TRUE; + } + return FALSE; } /*****************************************************************************/ /* DHCPv6 stuff */ static void -dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) +dhcp6_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->dhcp_data_6.was_active = FALSE; - priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; - applied_config_clear (&priv->dhcp6.ip6_config); - nm_clear_g_free (&priv->dhcp6.event_id); - nm_clear_g_source (&priv->dhcp_data_6.grace_id); - priv->dhcp_data_6.grace_pending = FALSE; + priv->dhcp_data_6.was_active = FALSE; + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; + applied_config_clear(&priv->dhcp6.ip6_config); + nm_clear_g_free(&priv->dhcp6.event_id); + nm_clear_g_source(&priv->dhcp_data_6.grace_id); + priv->dhcp_data_6.grace_pending = FALSE; - if (priv->dhcp_data_6.client) { - nm_clear_g_signal_handler (priv->dhcp_data_6.client, &priv->dhcp_data_6.state_sigid); - nm_clear_g_signal_handler (priv->dhcp_data_6.client, &priv->dhcp6.prefix_sigid); + if (priv->dhcp_data_6.client) { + nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp_data_6.state_sigid); + nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp6.prefix_sigid); - if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE - || cleanup_type == CLEANUP_TYPE_REMOVED) - nm_dhcp_client_stop (priv->dhcp_data_6.client, release); + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) + nm_dhcp_client_stop(priv->dhcp_data_6.client, release); - g_clear_object (&priv->dhcp_data_6.client); - } + g_clear_object(&priv->dhcp_data_6.client); + } - if (priv->dhcp_data_6.config) { - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_6.config); - _notify (self, PROP_DHCP6_CONFIG); - } + if (priv->dhcp_data_6.config) { + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config); + _notify(self, PROP_DHCP6_CONFIG); + } } static gboolean -dhcp6_lease_change (NMDevice *self) +dhcp6_lease_change(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *settings_connection; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingsConnection *settings_connection; - if (!applied_config_get_current (&priv->dhcp6.ip6_config)) { - _LOGW (LOGD_DHCP6, "failed to get DHCPv6 config for rebind"); - return FALSE; - } + if (!applied_config_get_current(&priv->dhcp6.ip6_config)) { + _LOGW(LOGD_DHCP6, "failed to get DHCPv6 config for rebind"); + return FALSE; + } - g_assert (priv->dhcp_data_6.client); /* sanity check */ + g_assert(priv->dhcp_data_6.client); /* sanity check */ - settings_connection = nm_device_get_settings_connection (self); - g_assert (settings_connection); + settings_connection = nm_device_get_settings_connection(self); + g_assert(settings_connection); - /* Apply the updated config */ - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) { - _LOGW (LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event"); - return FALSE; - } + /* Apply the updated config */ + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) { + _LOGW(LOGD_DHCP6, "failed to update IPv6 config in response to DHCP event"); + return FALSE; + } - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE, - self, - NULL, - NULL, NULL, NULL); + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE, self, NULL, NULL, NULL, NULL); - return TRUE; + return TRUE; } static void -dhcp6_fail (NMDevice *self, NMDhcpState dhcp_state) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean is_dhcp_managed; - - _LOGD (LOGD_DHCP6, "DHCPv6 failed (ip_state %s, was_active %d)", - _ip_state_to_string (priv->ip_state_6), - priv->dhcp_data_6.was_active); - - /* The client is always left running after a failure. */ - - /* Nothing to do if we failed before... */ - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) - goto clear_config; - - is_dhcp_managed = (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED); - - if (is_dhcp_managed) { - /* ... and also if there are static addresses configured - * on the interface. - */ - if ( priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE - && priv->con_ip_config_6 - && nm_ip6_config_get_num_addresses (priv->con_ip_config_6)) - goto clear_config; - - /* Fail the method when one of the following is true: - * 1) the DHCP client terminated: it does not make sense to start a grace - * period without a client running; - * 2) we failed to get an initial lease AND the client was - * not active before. - */ - if ( dhcp_state == NM_DHCP_STATE_TERMINATED - || (!priv->dhcp_data_6.was_active && priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF)) { - nm_device_activate_schedule_ip_config_timeout (self, AF_INET6); - return; - } - - if (dhcp_grace_period_start (self, AF_INET6)) - goto clear_config; - } else { - /* not a hard failure; just live with the RA info */ - dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE); - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - } - return; +dhcp6_fail(NMDevice *self, NMDhcpState dhcp_state) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean is_dhcp_managed; + + _LOGD(LOGD_DHCP6, + "DHCPv6 failed (ip_state %s, was_active %d)", + _ip_state_to_string(priv->ip_state_6), + priv->dhcp_data_6.was_active); + + /* The client is always left running after a failure. */ + + /* Nothing to do if we failed before... */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) + goto clear_config; + + is_dhcp_managed = (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED); + + if (is_dhcp_managed) { + /* ... and also if there are static addresses configured + * on the interface. + */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE && priv->con_ip_config_6 + && nm_ip6_config_get_num_addresses(priv->con_ip_config_6)) + goto clear_config; + + /* Fail the method when one of the following is true: + * 1) the DHCP client terminated: it does not make sense to start a grace + * period without a client running; + * 2) we failed to get an initial lease AND the client was + * not active before. + */ + if (dhcp_state == NM_DHCP_STATE_TERMINATED + || (!priv->dhcp_data_6.was_active && priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF)) { + nm_device_activate_schedule_ip_config_timeout(self, AF_INET6); + return; + } + + if (dhcp_grace_period_start(self, AF_INET6)) + goto clear_config; + } else { + /* not a hard failure; just live with the RA info */ + dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, FALSE); + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + } + return; clear_config: - /* The previous configuration is no longer valid */ - if (priv->dhcp_data_6.config) { - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_6.config); - priv->dhcp_data_6.config = nm_dhcp_config_new (AF_INET6); - _notify (self, PROP_DHCP6_CONFIG); - } + /* The previous configuration is no longer valid */ + if (priv->dhcp_data_6.config) { + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config); + priv->dhcp_data_6.config = nm_dhcp_config_new(AF_INET6); + _notify(self, PROP_DHCP6_CONFIG); + } } static void -dhcp6_state_changed (NMDhcpClient *client, - NMDhcpState state, - NMIP6Config *ip6_config, - GHashTable *options, - const char *event_id, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - g_return_if_fail (nm_dhcp_client_get_addr_family (client) == AF_INET6); - g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config)); - - _LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state); - - switch (state) { - case NM_DHCP_STATE_BOUND: - case NM_DHCP_STATE_EXTENDED: - nm_clear_g_source (&priv->dhcp_data_6.grace_id); - priv->dhcp_data_6.grace_pending = FALSE; - /* If the server sends multiple IPv6 addresses, we receive a state - * changed event for each of them. Use the event ID to merge IPv6 - * addresses from the same transaction into a single configuration. - */ - if ( ip6_config - && event_id - && priv->dhcp6.event_id - && !strcmp (event_id, priv->dhcp6.event_id)) { - NMDedupMultiIter ipconf_iter; - const NMPlatformIP6Address *a; - - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6_config, &a) - applied_config_add_address (&priv->dhcp6.ip6_config, NM_PLATFORM_IP_ADDRESS_CAST (a)); - } else { - nm_clear_g_free (&priv->dhcp6.event_id); - if (ip6_config) { - applied_config_init (&priv->dhcp6.ip6_config, ip6_config); - priv->dhcp6.event_id = g_strdup (event_id); - nm_dhcp_config_set_options (priv->dhcp_data_6.config, options); - _notify (self, PROP_DHCP6_CONFIG); - } else - applied_config_clear (&priv->dhcp6.ip6_config); - } - - /* After long time we have been able to renew the lease: - * update the ip state - */ - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_CONF); - - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { - if (!applied_config_get_current (&priv->dhcp6.ip6_config)) { - nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED); - break; - } - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - } else if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) - if (!dhcp6_lease_change (self)) - dhcp6_fail (self, state); - break; - case NM_DHCP_STATE_TIMEOUT: - if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) - dhcp6_fail (self, state); - else { - /* not a hard failure; just live with the RA info */ - dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE); - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - } - break; - case NM_DHCP_STATE_EXPIRE: - /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ - if (priv->ip_state_6 != NM_DEVICE_IP_STATE_CONF) - dhcp6_fail (self, state); - break; - case NM_DHCP_STATE_TERMINATED: - /* In IPv6 info-only mode, the client doesn't handle leases so it - * may exit right after getting a response from the server. That's - * normal. In that case we just ignore the exit. - */ - if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) - break; - /* fall-through */ - case NM_DHCP_STATE_DONE: - case NM_DHCP_STATE_FAIL: - dhcp6_fail (self, state); - break; - default: - break; - } +dhcp6_state_changed(NMDhcpClient *client, + NMDhcpState state, + NMIP6Config * ip6_config, + GHashTable * options, + gpointer user_data) +{ + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free char * event_id = NULL; + + g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET6); + g_return_if_fail(!ip6_config || NM_IS_IP6_CONFIG(ip6_config)); + + _LOGD(LOGD_DHCP6, "new DHCPv6 client state %d", state); + + switch (state) { + case NM_DHCP_STATE_BOUND: + case NM_DHCP_STATE_EXTENDED: + nm_clear_g_source(&priv->dhcp_data_6.grace_id); + priv->dhcp_data_6.grace_pending = FALSE; + /* If the server sends multiple IPv6 addresses, we receive a state + * changed event for each of them. Use the event ID to merge IPv6 + * addresses from the same transaction into a single configuration. + */ + + event_id = nm_dhcp_utils_get_dhcp6_event_id(options); + + if (ip6_config && event_id && priv->dhcp6.event_id + && nm_streq(event_id, priv->dhcp6.event_id)) { + NMDedupMultiIter ipconf_iter; + const NMPlatformIP6Address *a; + + nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6_config, &a) + applied_config_add_address(&priv->dhcp6.ip6_config, NM_PLATFORM_IP_ADDRESS_CAST(a)); + } else { + nm_clear_g_free(&priv->dhcp6.event_id); + if (ip6_config) { + applied_config_init(&priv->dhcp6.ip6_config, ip6_config); + priv->dhcp6.event_id = g_strdup(event_id); + nm_dhcp_config_set_options(priv->dhcp_data_6.config, options); + _notify(self, PROP_DHCP6_CONFIG); + } else + applied_config_clear(&priv->dhcp6.ip6_config); + } + + /* After long time we have been able to renew the lease: + * update the ip state + */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_CONF); + + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { + if (!applied_config_get_current(&priv->dhcp6.ip6_config)) { + nm_device_ip_method_failed(self, AF_INET6, NM_DEVICE_STATE_REASON_DHCP_FAILED); + break; + } + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + } else if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) + if (!dhcp6_lease_change(self)) + dhcp6_fail(self, state); + break; + case NM_DHCP_STATE_TIMEOUT: + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) + dhcp6_fail(self, state); + else { + /* not a hard failure; just live with the RA info */ + dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, FALSE); + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + } + break; + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip_state_6 != NM_DEVICE_IP_STATE_CONF) + dhcp6_fail(self, state); + break; + case NM_DHCP_STATE_TERMINATED: + /* In IPv6 info-only mode, the client doesn't handle leases so it + * may exit right after getting a response from the server. That's + * normal. In that case we just ignore the exit. + */ + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) + break; + /* fall-through */ + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: + dhcp6_fail(self, state); + break; + default: + break; + } } static void -dhcp6_prefix_delegated (NMDhcpClient *client, - NMPlatformIP6Address *prefix, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - /* Just re-emit. The device just contributes the prefix to the - * pool in NMPolicy, which decides about subnet allocation - * on the shared devices. */ - g_signal_emit (self, signals[IP6_PREFIX_DELEGATED], 0, prefix); -} - -/*****************************************************************************/ - -/* RFC 3315 defines the epoch for the DUID-LLT time field on Jan 1st 2000. */ -#define EPOCH_DATETIME_200001010000 946684800 - -static GBytes * -generate_duid_llt (int arp_type, - const guint8 *hwaddr, - gsize hwaddr_len, - gint64 time) -{ - guint8 *arr; - const guint16 duid_type = htons (1); - const guint16 hw_type = htons (arp_type); - const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000)); - - if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) - nm_assert_not_reached (); - - arr = g_new (guint8, 2 + 2 + 4 + hwaddr_len); - - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], &duid_time, 4); - memcpy (&arr[8], hwaddr, hwaddr_len); - - return g_bytes_new_take (arr, 2 + 2 + 4 + hwaddr_len); -} - -static GBytes * -generate_duid_ll (int arp_type, - const guint8 *hwaddr, - gsize hwaddr_len) -{ - guint8 *arr; - const guint16 duid_type = htons (3); - const guint16 hw_type = htons (arp_type); - - if (!nm_utils_arp_type_get_hwaddr_relevant_part (arp_type, &hwaddr, &hwaddr_len)) - nm_assert_not_reached (); - - arr = g_new (guint8, 2 + 2 + hwaddr_len); - - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], hwaddr, hwaddr_len); - - return g_bytes_new_take (arr, 2 + 2 + hwaddr_len); -} - -static GBytes * -generate_duid_uuid (const NMUuid *uuid) -{ - const guint16 duid_type = htons (4); - guint8 *duid_buffer; - - nm_assert (uuid); - - /* Generate a DHCP Unique Identifier for DHCPv6 using the - * DUID-UUID method (see RFC 6355 section 4). Format is: - * - * u16: type (DUID-UUID = 4) - * u8[16]: UUID bytes - */ - G_STATIC_ASSERT_EXPR (sizeof (duid_type) == 2); - G_STATIC_ASSERT_EXPR (sizeof (*uuid) == 16); - duid_buffer = g_malloc (18); - memcpy (&duid_buffer[0], &duid_type, 2); - memcpy (&duid_buffer[2], uuid, 16); - return g_bytes_new_take (duid_buffer, 18); -} - -static GBytes * -generate_duid_from_machine_id (void) +dhcp6_prefix_delegated(NMDhcpClient *client, NMPlatformIP6Address *prefix, gpointer user_data) { - static GBytes *volatile global_duid = NULL; - GBytes *p; - -again: - p = g_atomic_pointer_get (&global_duid); - if (G_UNLIKELY (!p)) { - nm_auto_free_checksum GChecksum *sum = NULL; - const NMUuid *machine_id; - union { - guint8 sha256[NM_UTILS_CHECKSUM_LENGTH_SHA256]; - NMUuid uuid; - } digest; - - machine_id = nm_utils_machine_id_bin (); - - /* Hash the machine ID so it's not leaked to the network */ - sum = g_checksum_new (G_CHECKSUM_SHA256); - g_checksum_update (sum, (const guchar *) machine_id, sizeof (*machine_id)); - nm_utils_checksum_get_digest (sum, digest.sha256); - - G_STATIC_ASSERT_EXPR (sizeof (digest.sha256) > sizeof (digest.uuid)); - p = generate_duid_uuid (&digest.uuid); - - if (!g_atomic_pointer_compare_and_exchange (&global_duid, NULL, p)) { - g_bytes_unref (p); - goto again; - } - } + NMDevice *self = NM_DEVICE(user_data); - return g_bytes_ref (p); -} - -static GBytes * -dhcp6_get_duid (NMDevice *self, NMConnection *connection, GBytes *hwaddr, gboolean *out_enforce) -{ - NMSettingIPConfig *s_ip6; - const char *duid; - gs_free char *duid_default = NULL; - const char *duid_error; - GBytes *duid_out; - gboolean duid_enforce = TRUE; - gs_free char *logstr1 = NULL; - const guint8 *hwaddr_bin; - gsize hwaddr_len; - int arp_type; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - duid = nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6)); - - if (!duid) { - duid_default = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ipv6.dhcp-duid"), - self); - duid = duid_default; - if (!duid) - duid = "lease"; - } - - if (nm_streq (duid, "lease")) { - duid_enforce = FALSE; - duid_out = generate_duid_from_machine_id (); - goto out_good; - } - - if (!_nm_utils_dhcp_duid_valid (duid, &duid_out)) { - duid_error = "invalid duid"; - goto out_fail; - } - - if (duid_out) - goto out_good; - - if (NM_IN_STRSET (duid, "ll", "llt")) { - if (!hwaddr) { - duid_error = "missing link-layer address"; - goto out_fail; - } - - hwaddr_bin = g_bytes_get_data (hwaddr, &hwaddr_len); - arp_type = nm_utils_arp_type_detect_from_hwaddrlen (hwaddr_len); - if (arp_type < 0) { - duid_error = "unsupported link-layer address"; - goto out_fail; - } - - if (nm_streq (duid, "ll")) - duid_out = generate_duid_ll (arp_type, hwaddr_bin, hwaddr_len); - else { - duid_out = generate_duid_llt (arp_type, hwaddr_bin, hwaddr_len, - nm_utils_host_id_get_timestamp_ns () / NM_UTILS_NSEC_PER_SEC); - } - - goto out_good; - } - - if (NM_IN_STRSET (duid, "stable-ll", "stable-llt", "stable-uuid")) { - /* preferably, we would salt the checksum differently for each @duid type. We missed - * to do that initially, so most types use the DEFAULT_SALT. - * - * Implementations that are added later, should use a distinct salt instead, - * like "stable-ll"/"stable-llt" with ARPHRD_INFINIBAND below. */ - const guint32 DEFAULT_SALT = 670531087u; - nm_auto_free_checksum GChecksum *sum = NULL; - NMUtilsStableType stable_type; - const char *stable_id = NULL; - guint32 salted_header; - const guint8 *host_id; - gsize host_id_len; - union { - guint8 sha256[NM_UTILS_CHECKSUM_LENGTH_SHA256]; - guint8 hwaddr_eth[ETH_ALEN]; - guint8 hwaddr_infiniband[INFINIBAND_ALEN]; - NMUuid uuid; - struct _nm_packed { - guint8 hwaddr[ETH_ALEN]; - guint32 timestamp; - } llt_eth; - struct _nm_packed { - guint8 hwaddr[INFINIBAND_ALEN]; - guint32 timestamp; - } llt_infiniband; - } digest; - - stable_id = _get_stable_id (self, connection, &stable_type); - - if (NM_IN_STRSET (duid, "stable-ll", "stable-llt")) { - /* for stable LL/LLT DUIDs, we still need a hardware address to detect - * the arp-type. Alternatively, we would be able to detect it based on - * other means (e.g. NMDevice type), but instead require the hardware - * address to be present. This is at least consistent with the "ll"/"llt" - * modes above. */ - if (!hwaddr) { - duid_error = "missing link-layer address"; - goto out_fail; - } - if ((arp_type = nm_utils_arp_type_detect_from_hwaddrlen (g_bytes_get_size (hwaddr))) < 0) { - duid_error = "unsupported link-layer address"; - goto out_fail; - } - - if (arp_type == ARPHRD_ETHER) - salted_header = DEFAULT_SALT; - else { - nm_assert (arp_type == ARPHRD_INFINIBAND); - salted_header = 0x42492CEFu + ((guint32) arp_type); - } - } else { - salted_header = DEFAULT_SALT; - arp_type = -1; - } - - salted_header = htonl (salted_header + ((guint32) stable_type)); - - nm_utils_host_id_get (&host_id, &host_id_len); - - sum = g_checksum_new (G_CHECKSUM_SHA256); - g_checksum_update (sum, (const guchar *) &salted_header, sizeof (salted_header)); - g_checksum_update (sum, (const guchar *) stable_id, -1); - g_checksum_update (sum, (const guchar *) host_id, host_id_len); - nm_utils_checksum_get_digest (sum, digest.sha256); - - G_STATIC_ASSERT_EXPR (sizeof (digest) == sizeof (digest.sha256)); - - if (nm_streq (duid, "stable-ll")) { - switch (arp_type) { - case ARPHRD_ETHER: - duid_out = generate_duid_ll (arp_type, digest.hwaddr_eth, sizeof (digest.hwaddr_eth)); - break; - case ARPHRD_INFINIBAND: - duid_out = generate_duid_ll (arp_type, digest.hwaddr_infiniband, sizeof (digest.hwaddr_infiniband)); - break; - default: - g_return_val_if_reached (NULL); - } - } else if (nm_streq (duid, "stable-llt")) { - gint64 time; - guint32 timestamp; - -#define EPOCH_DATETIME_THREE_YEARS (356 * 24 * 3600 * 3) - - /* We want a variable time between the host_id timestamp and three years - * before. Let's compute the time (in seconds) from 0 to 3 years; then we'll - * subtract it from the host_id timestamp. - */ - time = nm_utils_host_id_get_timestamp_ns () / NM_UTILS_NSEC_PER_SEC; - - /* don't use too old timestamps. They cannot be expressed in DUID-LLT and - * would all be truncated to zero. */ - time = NM_MAX (time, EPOCH_DATETIME_200001010000 + EPOCH_DATETIME_THREE_YEARS); - - switch (arp_type) { - case ARPHRD_ETHER: - timestamp = unaligned_read_be32 (&digest.llt_eth.timestamp); - time -= timestamp % EPOCH_DATETIME_THREE_YEARS; - duid_out = generate_duid_llt (arp_type, digest.llt_eth.hwaddr, sizeof (digest.llt_eth.hwaddr), time); - break; - case ARPHRD_INFINIBAND: - timestamp = unaligned_read_be32 (&digest.llt_infiniband.timestamp); - time -= timestamp % EPOCH_DATETIME_THREE_YEARS; - duid_out = generate_duid_llt (arp_type, digest.llt_infiniband.hwaddr, sizeof (digest.llt_infiniband.hwaddr), time); - break; - default: - g_return_val_if_reached (NULL); - } - } else { - nm_assert (nm_streq (duid, "stable-uuid")); - duid_out = generate_duid_uuid (&digest.uuid); - } - - goto out_good; - } - - g_return_val_if_reached (NULL); - -out_fail: - nm_assert (!duid_out && duid_error); - { - NMUuid uuid; - - _LOGW (LOGD_IP6 | LOGD_DHCP6, - "ipv6.dhcp-duid: failure to generate %s DUID: %s. Fallback to random DUID-UUID.", - duid, duid_error); - - nm_utils_random_bytes (&uuid, sizeof (uuid)); - duid_out = generate_duid_uuid (&uuid); - } - -out_good: - nm_assert (duid_out); - _LOGD (LOGD_IP6 | LOGD_DHCP6, - "ipv6.dhcp-duid: generate %s DUID '%s' (%s)", - duid, - (logstr1 = nm_dhcp_utils_duid_to_string (duid_out)), - duid_enforce ? "enforcing" : "prefer lease"); - - NM_SET_OUT (out_enforce, duid_enforce); - return duid_out; + /* Just re-emit. The device just contributes the prefix to the + * pool in NMPolicy, which decides about subnet allocation + * on the shared devices. */ + g_signal_emit(self, signals[IP6_PREFIX_DELEGATED], 0, prefix); } /*****************************************************************************/ static gboolean -dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingIPConfig *s_ip6; - gs_unref_bytes GBytes *hwaddr = NULL; - gs_unref_bytes GBytes *duid = NULL; - gboolean enforce_duid = FALSE; - const NMPlatformLink *pllink; - gs_free char *mud_url_free = NULL; - GError *error = NULL; - guint32 iaid; - gboolean iaid_explicit; - NMSettingConnection *s_con; - const NMPlatformIP6Address *ll_addr = NULL; - - g_return_val_if_fail (connection, FALSE); - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - nm_assert (s_ip6); - s_con = nm_connection_get_setting_connection (connection); - nm_assert (s_con); - - if (priv->ext_ip6_config_captured) { - ll_addr = nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); - } - - if (!ll_addr) { - _LOGW (LOGD_DHCP6, "can't start DHCPv6: no link-local address"); - return FALSE; - } - - pllink = nm_platform_link_get (nm_device_get_platform (self), nm_device_get_ip_ifindex (self)); - if (pllink) - hwaddr = nmp_link_address_get_as_bytes (&pllink->l_address); - - iaid = dhcp_get_iaid (self, AF_INET6, connection, &iaid_explicit); - duid = dhcp6_get_duid (self, connection, hwaddr, &enforce_duid); - - priv->dhcp_data_6.client = nm_dhcp_manager_start_ip6 (nm_dhcp_manager_get (), - nm_device_get_multi_index (self), - nm_device_get_ip_iface (self), - nm_device_get_ip_ifindex (self), - &ll_addr->address, - nm_connection_get_uuid (connection), - nm_device_get_route_table (self, AF_INET6), - nm_device_get_route_metric (self, AF_INET6), - nm_setting_ip_config_get_dhcp_send_hostname (s_ip6), - nm_setting_ip_config_get_dhcp_hostname (s_ip6), - get_dhcp_hostname_flags (self, AF_INET6), - connection_get_mud_url (self, s_con, &mud_url_free), - duid, - enforce_duid, - iaid, - iaid_explicit, - get_dhcp_timeout (self, AF_INET6), - priv->dhcp_anycast_address, - (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, - nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), - priv->dhcp6.needed_prefixes, - &error); - if (!priv->dhcp_data_6.client) { - _LOGW (LOGD_DHCP6, "failure to start DHCPv6: %s", error->message); - g_clear_error (&error); - if (nm_device_sys_iface_state_is_external_or_assume (self)) - priv->dhcp_data_6.was_active = TRUE; - return FALSE; - } - - priv->dhcp_data_6.state_sigid = g_signal_connect (priv->dhcp_data_6.client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK (dhcp6_state_changed), - self); - priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp_data_6.client, - NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, - G_CALLBACK (dhcp6_prefix_delegated), - self); - - if (nm_device_sys_iface_state_is_external_or_assume (self)) - priv->dhcp_data_6.was_active = TRUE; - - return TRUE; +dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingIPConfig *s_ip6; + gs_unref_bytes GBytes *hwaddr = NULL; + gs_unref_bytes GBytes * duid = NULL; + gboolean enforce_duid = FALSE; + const NMPlatformLink * pllink; + gs_free char * mud_url_free = NULL; + GError * error = NULL; + guint32 iaid; + gboolean iaid_explicit; + NMSettingConnection * s_con; + const NMPlatformIP6Address *ll_addr = NULL; + + g_return_val_if_fail(connection, FALSE); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + nm_assert(s_ip6); + s_con = nm_connection_get_setting_connection(connection); + nm_assert(s_con); + + if (priv->ext_ip6_config_captured) { + ll_addr = nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); + } + + if (!ll_addr) { + _LOGW(LOGD_DHCP6, "can't start DHCPv6: no link-local address"); + return FALSE; + } + + pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + if (pllink) + hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address); + + iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, &iaid_explicit); + duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid); + + priv->dhcp_data_6.client = nm_dhcp_manager_start_ip6( + nm_dhcp_manager_get(), + nm_device_get_multi_index(self), + nm_device_get_ip_iface(self), + nm_device_get_ip_ifindex(self), + &ll_addr->address, + nm_connection_get_uuid(connection), + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6), + nm_setting_ip_config_get_dhcp_send_hostname(s_ip6), + nm_setting_ip_config_get_dhcp_hostname(s_ip6), + _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET6), + _prop_get_connection_mud_url(self, s_con, &mud_url_free), + duid, + enforce_duid, + iaid, + iaid_explicit, + _prop_get_ipvx_dhcp_timeout(self, AF_INET6), + priv->dhcp_anycast_address, + (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, + nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)), + priv->dhcp6.needed_prefixes, + &error); + if (!priv->dhcp_data_6.client) { + _LOGW(LOGD_DHCP6, "failure to start DHCPv6: %s", error->message); + g_clear_error(&error); + if (nm_device_sys_iface_state_is_external_or_assume(self)) + priv->dhcp_data_6.was_active = TRUE; + return FALSE; + } + + priv->dhcp_data_6.state_sigid = g_signal_connect(priv->dhcp_data_6.client, + NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, + G_CALLBACK(dhcp6_state_changed), + self); + priv->dhcp6.prefix_sigid = g_signal_connect(priv->dhcp_data_6.client, + NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, + G_CALLBACK(dhcp6_prefix_delegated), + self); + + if (nm_device_sys_iface_state_is_external_or_assume(self)) + priv->dhcp_data_6.was_active = TRUE; + + return TRUE; } static gboolean -dhcp6_start (NMDevice *self, gboolean wait_for_ll) +dhcp6_start(NMDevice *self, gboolean wait_for_ll) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; - nm_dbus_object_clear_and_unexport (&priv->dhcp_data_6.config); - priv->dhcp_data_6.config = nm_dhcp_config_new (AF_INET6); + nm_dbus_object_clear_and_unexport(&priv->dhcp_data_6.config); + priv->dhcp_data_6.config = nm_dhcp_config_new(AF_INET6); - nm_assert (!applied_config_get_current (&priv->dhcp6.ip6_config)); - applied_config_clear (&priv->dhcp6.ip6_config); - nm_clear_g_free (&priv->dhcp6.event_id); + nm_assert(!applied_config_get_current(&priv->dhcp6.ip6_config)); + applied_config_clear(&priv->dhcp6.ip6_config); + nm_clear_g_free(&priv->dhcp6.event_id); - connection = nm_device_get_applied_connection (self); - g_return_val_if_fail (connection, FALSE); + connection = nm_device_get_applied_connection(self); + g_return_val_if_fail(connection, FALSE); - if (wait_for_ll) { - /* ensure link local is ready... */ - if (!linklocal6_start (self)) { - /* wait for the LL address to show up */ - return TRUE; - } - /* already have the LL address; kick off DHCP */ - } + if (wait_for_ll) { + /* ensure link local is ready... */ + if (!linklocal6_start(self)) { + /* wait for the LL address to show up */ + return TRUE; + } + /* already have the LL address; kick off DHCP */ + } - if (!dhcp6_start_with_link_ready (self, connection)) - return FALSE; + if (!dhcp6_start_with_link_ready(self, connection)) + return FALSE; - return TRUE; + return TRUE; } gboolean -nm_device_dhcp6_renew (NMDevice *self, gboolean release) +nm_device_dhcp6_renew(NMDevice *self, gboolean release) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - g_return_val_if_fail (priv->dhcp_data_6.client != NULL, FALSE); + g_return_val_if_fail(priv->dhcp_data_6.client != NULL, FALSE); - _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested"); + _LOGI(LOGD_DHCP6, "DHCPv6 lease renewal requested"); - /* Terminate old DHCP instance and release the old lease */ - dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release); + /* Terminate old DHCP instance and release the old lease */ + dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, release); - /* Start DHCP again on the interface */ - return dhcp6_start (self, FALSE); + /* Start DHCP again on the interface */ + return dhcp6_start(self, FALSE); } /*****************************************************************************/ @@ -9675,24 +9879,24 @@ nm_device_dhcp6_renew (NMDevice *self, gboolean release) * from known prefixes for a newly active shared connection. */ void -nm_device_request_ip6_prefixes (NMDevice *self, int needed_prefixes) +nm_device_request_ip6_prefixes(NMDevice *self, int needed_prefixes) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->dhcp6.needed_prefixes = needed_prefixes; + priv->dhcp6.needed_prefixes = needed_prefixes; - if (priv->dhcp_data_6.client) { - _LOGD (LOGD_IP6, "ipv6-pd: asking DHCPv6 for %d prefixes", needed_prefixes); - nm_device_dhcp6_renew (self, FALSE); - } else { - _LOGI (LOGD_IP6, "ipv6-pd: device doesn't use DHCPv6, can't request prefixes"); - } + if (priv->dhcp_data_6.client) { + _LOGD(LOGD_IP6, "ipv6-pd: asking DHCPv6 for %d prefixes", needed_prefixes); + nm_device_dhcp6_renew(self, FALSE); + } else { + _LOGI(LOGD_IP6, "ipv6-pd: device doesn't use DHCPv6, can't request prefixes"); + } } gboolean -nm_device_needs_ip6_subnet (NMDevice *self) +nm_device_needs_ip6_subnet(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->needs_ip6_subnet; + return NM_DEVICE_GET_PRIVATE(self)->needs_ip6_subnet; } /* @@ -9700,26 +9904,27 @@ nm_device_needs_ip6_subnet (NMDevice *self) * or the prefix from which it is allocated is renewed. */ void -nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet) +nm_device_use_ip6_subnet(NMDevice *self, const NMPlatformIP6Address *subnet) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatformIP6Address address = *subnet; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatformIP6Address address = *subnet; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - if (!applied_config_get_current (&priv->ac_ip6_config)) - applied_config_init_new (&priv->ac_ip6_config, self, AF_INET6); + if (!applied_config_get_current(&priv->ac_ip6_config)) + applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6); - /* Assign a ::1 address in the subnet for us. */ - address.address.s6_addr32[3] |= htonl (1); - applied_config_add_address (&priv->ac_ip6_config, NM_PLATFORM_IP_ADDRESS_CAST (&address)); + /* Assign a ::1 address in the subnet for us. */ + address.address.s6_addr32[3] |= htonl(1); + applied_config_add_address(&priv->ac_ip6_config, NM_PLATFORM_IP_ADDRESS_CAST(&address)); - _LOGD (LOGD_IP6, "ipv6-pd: using %s address (preferred for %u seconds)", - _nm_utils_inet6_ntop (&address.address, sbuf), - subnet->preferred); + _LOGD(LOGD_IP6, + "ipv6-pd: using %s address (preferred for %u seconds)", + _nm_utils_inet6_ntop(&address.address, sbuf), + subnet->preferred); - /* This also updates the ndisc if there are actual changes. */ - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "ipv6-pd: failed applying IP6 config for connection sharing"); + /* This also updates the ndisc if there are actual changes. */ + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "ipv6-pd: failed applying IP6 config for connection sharing"); } /* @@ -9727,1301 +9932,1266 @@ nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet) * The ipv6.method=shared devices just reuse its DNS configuration. */ void -nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device) +nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMIP6Config *from_config = NULL; - guint i, len; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMIP6Config * from_config = NULL; + guint i, len; - if (applied_config_get_current (&priv->ac_ip6_config)) { - applied_config_reset_nameservers (&priv->ac_ip6_config); - applied_config_reset_searches (&priv->ac_ip6_config); - } else - applied_config_init_new (&priv->ac_ip6_config, self, AF_INET6); + if (applied_config_get_current(&priv->ac_ip6_config)) { + applied_config_reset_nameservers(&priv->ac_ip6_config); + applied_config_reset_searches(&priv->ac_ip6_config); + } else + applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6); - if (from_device) - from_config = nm_device_get_ip6_config (from_device); - if (!from_config) - return; + if (from_device) + from_config = nm_device_get_ip6_config(from_device); + if (!from_config) + return; - len = nm_ip6_config_get_num_nameservers (from_config); - for (i = 0; i < len; i++) { - applied_config_add_nameserver (&priv->ac_ip6_config, - (const NMIPAddr *) nm_ip6_config_get_nameserver (from_config, i)); - } + len = nm_ip6_config_get_num_nameservers(from_config); + for (i = 0; i < len; i++) { + applied_config_add_nameserver( + &priv->ac_ip6_config, + (const NMIPAddr *) nm_ip6_config_get_nameserver(from_config, i)); + } - len = nm_ip6_config_get_num_searches (from_config); - for (i = 0; i < len; i++) { - applied_config_add_search (&priv->ac_ip6_config, - nm_ip6_config_get_search (from_config, i)); - } + len = nm_ip6_config_get_num_searches(from_config); + for (i = 0; i < len; i++) { + applied_config_add_search(&priv->ac_ip6_config, nm_ip6_config_get_search(from_config, i)); + } - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "ipv6-pd: failed applying DNS config for connection sharing"); + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "ipv6-pd: failed applying DNS config for connection sharing"); } /*****************************************************************************/ static void -linklocal6_failed (NMDevice *self) +linklocal6_failed(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_clear_g_source (&priv->linklocal6_timeout_id); - nm_device_activate_schedule_ip_config_timeout (self, AF_INET6); + nm_clear_g_source(&priv->linklocal6_timeout_id); + nm_device_activate_schedule_ip_config_timeout(self, AF_INET6); } static gboolean -linklocal6_timeout_cb (gpointer user_data) +linklocal6_timeout_cb(gpointer user_data) { - NMDevice *self = user_data; + NMDevice *self = user_data; - _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout"); - linklocal6_failed (self); - return G_SOURCE_REMOVE; + _LOGD(LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout"); + linklocal6_failed(self); + return G_SOURCE_REMOVE; } static void -linklocal6_check_complete (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - const char *method; - - if (!priv->linklocal6_timeout_id) { - /* we are not waiting for linklocal to complete. Nothing to do. */ - return; - } - - if ( !priv->ext_ip6_config_captured - || !nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) { - /* we don't have a non-tentative link local address yet. Wait longer. */ - return; - } - - nm_clear_g_source (&priv->linklocal6_timeout_id); - - connection = nm_device_get_applied_connection (self); - g_assert (connection); - - method = nm_device_get_effective_ip_config_method (self, AF_INET6); - - _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method); - - if (NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_SHARED)) - addrconf6_start_with_link_ready (self); - else if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { - if (!dhcp6_start_with_link_ready (self, connection)) { - /* Time out IPv6 instead of failing the entire activation */ - nm_device_activate_schedule_ip_config_timeout (self, AF_INET6); - } - } else if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - else - g_return_if_fail (FALSE); +linklocal6_check_complete(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + const char * method; + + if (!priv->linklocal6_timeout_id) { + /* we are not waiting for linklocal to complete. Nothing to do. */ + return; + } + + if (!priv->ext_ip6_config_captured + || !nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) { + /* we don't have a non-tentative link local address yet. Wait longer. */ + return; + } + + nm_clear_g_source(&priv->linklocal6_timeout_id); + + connection = nm_device_get_applied_connection(self); + g_assert(connection); + + method = nm_device_get_effective_ip_config_method(self, AF_INET6); + + _LOGD(LOGD_DEVICE, + "linklocal6: waiting for link-local addresses successful, continue with method %s", + method); + + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_SHARED)) + addrconf6_start_with_link_ready(self); + else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + if (!dhcp6_start_with_link_ready(self, connection)) { + /* Time out IPv6 instead of failing the entire activation */ + nm_device_activate_schedule_ip_config_timeout(self, AF_INET6); + } + } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + else + g_return_if_fail(FALSE); } static void -check_and_add_ipv6ll_addr (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - struct in6_addr lladdr; - NMConnection *connection; - NMSettingIP6Config *s_ip6 = NULL; - GError *error = NULL; - const char *addr_type; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - if (!priv->ipv6ll_handle) - return; - - if ( priv->ext_ip6_config_captured - && nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) { - /* Already have an LL address, nothing to do */ - return; - } - - priv->ipv6ll_has = FALSE; - memset (&priv->ipv6ll_addr, 0, sizeof (priv->ipv6ll_addr)); - - memset (&lladdr, 0, sizeof (lladdr)); - lladdr.s6_addr16[0] = htons (0xfe80); - - connection = nm_device_get_applied_connection (self); - if (connection) - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); - - if (s_ip6 && nm_setting_ip6_config_get_addr_gen_mode (s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { - NMUtilsStableType stable_type; - const char *stable_id; - - stable_id = _get_stable_id (self, connection, &stable_type); - if (!nm_utils_ipv6_addr_set_stable_privacy (stable_type, - &lladdr, - nm_device_get_iface (self), - stable_id, - priv->linklocal6_dad_counter++, - &error)) { - _LOGW (LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message); - g_clear_error (&error); - linklocal6_failed (self); - return; - } - addr_type = "stable-privacy"; - } else { - NMUtilsIPv6IfaceId iid; - - if (priv->linklocal6_timeout_id) { - /* We already started and attempt to add a LL address. For the EUI-64 - * mode we can't pick a new one, we'll just fail. */ - _LOGW (LOGD_IP6, "linklocal6: DAD failed for an EUI-64 address"); - linklocal6_failed (self); - return; - } - - if (!nm_device_get_ip_iface_identifier (self, &iid, TRUE)) { - _LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); - return; - } - nm_utils_ipv6_addr_set_interface_identifier (&lladdr, iid); - addr_type = "EUI-64"; - } - - _LOGD (LOGD_IP6, "linklocal6: generated %s IPv6LL address %s", - addr_type, _nm_utils_inet6_ntop (&lladdr, sbuf)); - priv->ipv6ll_has = TRUE; - priv->ipv6ll_addr = lladdr; - ip_config_merge_and_apply (self, AF_INET6, TRUE); +check_and_add_ipv6ll_addr(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + struct in6_addr lladdr; + NMConnection * connection; + NMSettingIP6Config *s_ip6 = NULL; + GError * error = NULL; + const char * addr_type; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + if (!priv->ipv6ll_handle) + return; + + if (priv->ext_ip6_config_captured + && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) { + /* Already have an LL address, nothing to do */ + return; + } + + priv->ipv6ll_has = FALSE; + memset(&priv->ipv6ll_addr, 0, sizeof(priv->ipv6ll_addr)); + + memset(&lladdr, 0, sizeof(lladdr)); + lladdr.s6_addr16[0] = htons(0xfe80); + + connection = nm_device_get_applied_connection(self); + if (connection) + s_ip6 = NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(connection)); + + if (s_ip6 + && nm_setting_ip6_config_get_addr_gen_mode(s_ip6) + == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { + NMUtilsStableType stable_type; + const char * stable_id; + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + if (!nm_utils_ipv6_addr_set_stable_privacy(stable_type, + &lladdr, + nm_device_get_iface(self), + stable_id, + priv->linklocal6_dad_counter++, + &error)) { + _LOGW(LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message); + g_clear_error(&error); + linklocal6_failed(self); + return; + } + addr_type = "stable-privacy"; + } else { + NMUtilsIPv6IfaceId iid; + + if (priv->linklocal6_timeout_id) { + /* We already started and attempt to add a LL address. For the EUI-64 + * mode we can't pick a new one, we'll just fail. */ + _LOGW(LOGD_IP6, "linklocal6: DAD failed for an EUI-64 address"); + linklocal6_failed(self); + return; + } + + if (!nm_device_get_ip_iface_identifier(self, &iid, TRUE)) { + _LOGW(LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); + return; + } + nm_utils_ipv6_addr_set_interface_identifier(&lladdr, iid); + addr_type = "EUI-64"; + } + + _LOGD(LOGD_IP6, + "linklocal6: generated %s IPv6LL address %s", + addr_type, + _nm_utils_inet6_ntop(&lladdr, sbuf)); + priv->ipv6ll_has = TRUE; + priv->ipv6ll_addr = lladdr; + ip_config_merge_and_apply(self, AF_INET6, TRUE); } static gboolean -linklocal6_start (NMDevice *self) +linklocal6_start(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_clear_g_source (&priv->linklocal6_timeout_id); + nm_clear_g_source(&priv->linklocal6_timeout_id); - if ( priv->ext_ip6_config_captured - && nm_ip6_config_find_first_address (priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) - return TRUE; + if (priv->ext_ip6_config_captured + && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + return TRUE; - _LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", - nm_device_get_effective_ip_config_method (self, AF_INET6)); + _LOGD(LOGD_DEVICE, + "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses " + "configured. Wait.", + nm_device_get_effective_ip_config_method(self, AF_INET6)); - check_and_add_ipv6ll_addr (self); + check_and_add_ipv6ll_addr(self); - /* Depending on the network and what the 'dad_transmits' and 'retrans_time_ms' - * sysctl values are, DAD for the IPv6LL address may take quite a while. - * FIXME: use dad/retrans sysctl values if they are higher than a minimum time. - * (rh #1101809) - */ - priv->linklocal6_timeout_id = g_timeout_add_seconds (15, linklocal6_timeout_cb, self); - return FALSE; + /* Depending on the network and what the 'dad_transmits' and 'retrans_time_ms' + * sysctl values are, DAD for the IPv6LL address may take quite a while. + * FIXME: use dad/retrans sysctl values if they are higher than a minimum time. + * (rh #1101809) + */ + priv->linklocal6_timeout_id = g_timeout_add_seconds(15, linklocal6_timeout_cb, self); + return FALSE; } /*****************************************************************************/ gint64 -nm_device_get_configured_mtu_from_connection_default (NMDevice *self, - const char *property_name, - guint32 max_mtu) +nm_device_get_configured_mtu_from_connection_default(NMDevice * self, + const char *property_name, + guint32 max_mtu) { - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property_name, - self, - 0, max_mtu, -1); + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + property_name, + self, + 0, + max_mtu, + -1); } guint32 -nm_device_get_configured_mtu_from_connection (NMDevice *self, - GType setting_type, - NMDeviceMtuSource *out_source) -{ - const char *global_property_name; - NMConnection *connection; - NMSetting *setting; - gint64 mtu_default; - guint32 mtu = 0; - guint32 max_mtu = G_MAXUINT32; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (out_source); - - connection = nm_device_get_applied_connection (self); - if (!connection) - g_return_val_if_reached (0); - - setting = nm_connection_get_setting (connection, setting_type); - - if (setting_type == NM_TYPE_SETTING_WIRED) { - if (setting) - mtu = nm_setting_wired_get_mtu (NM_SETTING_WIRED (setting)); - global_property_name = NM_CON_DEFAULT ("ethernet.mtu"); - } else if (setting_type == NM_TYPE_SETTING_WIRELESS) { - if (setting) - mtu = nm_setting_wireless_get_mtu (NM_SETTING_WIRELESS (setting)); - global_property_name = NM_CON_DEFAULT ("wifi.mtu"); - } else if (setting_type == NM_TYPE_SETTING_INFINIBAND) { - if (setting) - mtu = nm_setting_infiniband_get_mtu (NM_SETTING_INFINIBAND (setting)); - global_property_name = NM_CON_DEFAULT ("infiniband.mtu"); - max_mtu = NM_INFINIBAND_MAX_MTU; - } else if (setting_type == NM_TYPE_SETTING_IP_TUNNEL) { - if (setting) - mtu = nm_setting_ip_tunnel_get_mtu (NM_SETTING_IP_TUNNEL (setting)); - global_property_name = NM_CON_DEFAULT ("ip-tunnel.mtu"); - } else if (setting_type == NM_TYPE_SETTING_WIREGUARD) { - if (setting) - mtu = nm_setting_wireguard_get_mtu (NM_SETTING_WIREGUARD (setting)); - global_property_name = NM_CON_DEFAULT ("wireguard.mtu"); - } else - g_return_val_if_reached (0); - - if (mtu) { - *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; - return mtu; - } - - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, global_property_name, max_mtu); - if (mtu_default >= 0) { - *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; - return (guint32) mtu_default; - } - - *out_source = NM_DEVICE_MTU_SOURCE_NONE; - return 0; +nm_device_get_configured_mtu_from_connection(NMDevice * self, + GType setting_type, + NMDeviceMtuSource *out_source) +{ + const char * global_property_name; + NMConnection *connection; + NMSetting * setting; + gint64 mtu_default; + guint32 mtu = 0; + guint32 max_mtu = G_MAXUINT32; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(out_source); + + connection = nm_device_get_applied_connection(self); + if (!connection) + g_return_val_if_reached(0); + + setting = nm_connection_get_setting(connection, setting_type); + + if (setting_type == NM_TYPE_SETTING_WIRED) { + if (setting) + mtu = nm_setting_wired_get_mtu(NM_SETTING_WIRED(setting)); + global_property_name = NM_CON_DEFAULT("ethernet.mtu"); + } else if (setting_type == NM_TYPE_SETTING_WIRELESS) { + if (setting) + mtu = nm_setting_wireless_get_mtu(NM_SETTING_WIRELESS(setting)); + global_property_name = NM_CON_DEFAULT("wifi.mtu"); + } else if (setting_type == NM_TYPE_SETTING_INFINIBAND) { + if (setting) + mtu = nm_setting_infiniband_get_mtu(NM_SETTING_INFINIBAND(setting)); + global_property_name = NM_CON_DEFAULT("infiniband.mtu"); + max_mtu = NM_INFINIBAND_MAX_MTU; + } else if (setting_type == NM_TYPE_SETTING_IP_TUNNEL) { + if (setting) + mtu = nm_setting_ip_tunnel_get_mtu(NM_SETTING_IP_TUNNEL(setting)); + global_property_name = NM_CON_DEFAULT("ip-tunnel.mtu"); + } else if (setting_type == NM_TYPE_SETTING_WIREGUARD) { + if (setting) + mtu = nm_setting_wireguard_get_mtu(NM_SETTING_WIREGUARD(setting)); + global_property_name = NM_CON_DEFAULT("wireguard.mtu"); + } else + g_return_val_if_reached(0); + + if (mtu) { + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; + return mtu; + } + + mtu_default = + nm_device_get_configured_mtu_from_connection_default(self, global_property_name, max_mtu); + if (mtu_default >= 0) { + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; + return (guint32) mtu_default; + } + + *out_source = NM_DEVICE_MTU_SOURCE_NONE; + return 0; } guint32 -nm_device_get_configured_mtu_for_wired (NMDevice *self, - NMDeviceMtuSource *out_source, - gboolean *out_force) +nm_device_get_configured_mtu_for_wired(NMDevice * self, + NMDeviceMtuSource *out_source, + gboolean * out_force) { - return nm_device_get_configured_mtu_from_connection (self, - NM_TYPE_SETTING_WIRED, - out_source); + return nm_device_get_configured_mtu_from_connection(self, NM_TYPE_SETTING_WIRED, out_source); } guint32 -nm_device_get_configured_mtu_wired_parent (NMDevice *self, - NMDeviceMtuSource *out_source, - gboolean *out_force) -{ - guint32 mtu = 0; - guint32 parent_mtu = 0; - int ifindex; - - ifindex = nm_device_parent_get_ifindex (self); - if (ifindex > 0) { - parent_mtu = nm_platform_link_get_mtu (nm_device_get_platform (self), ifindex); - if (parent_mtu >= NM_DEVICE_GET_CLASS (self)->mtu_parent_delta) - parent_mtu -= NM_DEVICE_GET_CLASS (self)->mtu_parent_delta; - else - parent_mtu = 0; - } - - mtu = nm_device_get_configured_mtu_for_wired (self, out_source, NULL); - - if (parent_mtu && mtu > parent_mtu) { - /* Trying to set a MTU that is out of range from configuration: - * fall back to the parent MTU and set force flag so that it - * overrides an MTU with higher priority already configured. - */ - *out_source = NM_DEVICE_MTU_SOURCE_PARENT; - *out_force = TRUE; - return parent_mtu; - } - - if (*out_source != NM_DEVICE_MTU_SOURCE_NONE) { - nm_assert (mtu > 0); - return mtu; - } - - /* Inherit the MTU from parent device, if any */ - if (parent_mtu) { - mtu = parent_mtu; - *out_source = NM_DEVICE_MTU_SOURCE_PARENT; - } - - return mtu; +nm_device_get_configured_mtu_wired_parent(NMDevice * self, + NMDeviceMtuSource *out_source, + gboolean * out_force) +{ + guint32 mtu = 0; + guint32 parent_mtu = 0; + int ifindex; + + ifindex = nm_device_parent_get_ifindex(self); + if (ifindex > 0) { + parent_mtu = nm_platform_link_get_mtu(nm_device_get_platform(self), ifindex); + if (parent_mtu >= NM_DEVICE_GET_CLASS(self)->mtu_parent_delta) + parent_mtu -= NM_DEVICE_GET_CLASS(self)->mtu_parent_delta; + else + parent_mtu = 0; + } + + mtu = nm_device_get_configured_mtu_for_wired(self, out_source, NULL); + + if (parent_mtu && mtu > parent_mtu) { + /* Trying to set a MTU that is out of range from configuration: + * fall back to the parent MTU and set force flag so that it + * overrides an MTU with higher priority already configured. + */ + *out_source = NM_DEVICE_MTU_SOURCE_PARENT; + *out_force = TRUE; + return parent_mtu; + } + + if (*out_source != NM_DEVICE_MTU_SOURCE_NONE) { + nm_assert(mtu > 0); + return mtu; + } + + /* Inherit the MTU from parent device, if any */ + if (parent_mtu) { + mtu = parent_mtu; + *out_source = NM_DEVICE_MTU_SOURCE_PARENT; + } + + return mtu; } /*****************************************************************************/ static void -_set_mtu (NMDevice *self, guint32 mtu) +_set_mtu(NMDevice *self, guint32 mtu) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->mtu == mtu) - return; + if (priv->mtu == mtu) + return; - priv->mtu = mtu; - _notify (self, PROP_MTU); + priv->mtu = mtu; + _notify(self, PROP_MTU); - if (priv->master) { - /* changing the MTU of a slave, might require the master to reset - * its MTU. Note that the master usually cannot set a MTU larger - * then the slave's. Hence, when the slave increases the MTU, - * master might want to retry setting the MTU. */ - nm_device_commit_mtu (priv->master); - } + if (priv->master) { + /* changing the MTU of a slave, might require the master to reset + * its MTU. Note that the master usually cannot set a MTU larger + * then the slave's. Hence, when the slave increases the MTU, + * master might want to retry setting the MTU. */ + nm_device_commit_mtu(priv->master); + } } static gboolean -set_platform_mtu (NMDevice *self, guint32 mtu) +set_platform_mtu(NMDevice *self, guint32 mtu) { - int r; + int r; - r = nm_platform_link_set_mtu (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - mtu); - return (r != -NME_PL_CANT_SET_MTU); + r = nm_platform_link_set_mtu(nm_device_get_platform(self), nm_device_get_ip_ifindex(self), mtu); + return (r != -NME_PL_CANT_SET_MTU); } static void -_commit_mtu (NMDevice *self, const NMIP4Config *config) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceMtuSource source = NM_DEVICE_MTU_SOURCE_NONE; - guint32 ip6_mtu, ip6_mtu_orig; - guint32 mtu_desired, mtu_desired_orig; - guint32 mtu_plat; - struct { - gboolean initialized; - guint32 value; - } ip6_mtu_sysctl = { 0, }; - int ifindex; - char sbuf[64], sbuf1[64], sbuf2[64]; - gboolean success = TRUE; - - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex <= 0) - return; - - if ( !nm_device_get_applied_connection (self) - || nm_device_sys_iface_state_is_external_or_assume (self)) { - /* we don't tamper with the MTU of disconnected and - * external/assumed devices. */ - return; - } - - { - guint32 mtu = 0; - gboolean force = FALSE; - - /* We take the MTU from various sources: (in order of increasing - * priority) parent link, IP configuration (which contains the - * MTU from DHCP/PPP), connection profile. - * - * We could just compare it with the platform MTU and apply it - * when different, but this would revert at random times manual - * changes done by the user with the MTU from the connection. - * - * Instead, we remember the source of the currently configured - * MTU and apply the new one only when the new source has a - * higher priority, so that we don't set a MTU from same source - * multiple times. An exception to this is for the PARENT - * source, since we need to keep tracking the parent MTU when it - * changes. - * - * The subclass can set the @force argument to TRUE to signal that the - * returned MTU should be applied even if it has a lower priority. This - * is useful when the value from a lower source should - * preempt the one from higher ones. - */ - - if (NM_DEVICE_GET_CLASS (self)->get_configured_mtu) - mtu = NM_DEVICE_GET_CLASS (self)->get_configured_mtu (self, &source, &force); - - if ( config - && !force - && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG - && nm_ip4_config_get_mtu (config)) { - mtu = nm_ip4_config_get_mtu (config); - source = NM_DEVICE_MTU_SOURCE_IP_CONFIG; - } - - if (mtu != 0) { - _LOGT (LOGD_DEVICE, - "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", - (guint) mtu, - mtu_source_to_str (source), (guint) source, - mtu_source_to_str (priv->mtu_source), (guint) priv->mtu_source, - force ? " (forced)" : ""); - } - - if ( mtu != 0 - && ( force - || source > priv->mtu_source - || (priv->mtu_source == NM_DEVICE_MTU_SOURCE_PARENT && source == priv->mtu_source))) - mtu_desired = mtu; - else { - mtu_desired = 0; - source = NM_DEVICE_MTU_SOURCE_NONE; - } - } - - if (mtu_desired && mtu_desired < 1280) { - NMSettingIPConfig *s_ip6; - - s_ip6 = nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG); - if ( s_ip6 - && !NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { - /* the interface has IPv6 enabled. The MTU with IPv6 cannot be smaller - * then 1280. - * - * For slave-devices (that don't have @s_ip6 we) don't do this fixup because - * it's anyway an unsolved problem when the slave configures a conflicting - * MTU. */ - mtu_desired = 1280; - } - } - - ip6_mtu = priv->ip6_mtu; - if (!ip6_mtu && priv->mtu_source == NM_DEVICE_MTU_SOURCE_NONE) { - /* initially, if the IPv6 MTU is not specified, grow it as large as the - * link MTU @mtu_desired. Only exception is, if @mtu_desired is so small - * to disable IPv6. */ - if (mtu_desired >= 1280) - ip6_mtu = mtu_desired; - } - - if (!ip6_mtu && !mtu_desired) - return; - - mtu_desired_orig = mtu_desired; - ip6_mtu_orig = ip6_mtu; - - mtu_plat = nm_platform_link_get_mtu (nm_device_get_platform (self), ifindex); - - if (ip6_mtu) { - ip6_mtu = NM_MAX (1280, ip6_mtu); - - if (!mtu_desired) - mtu_desired = mtu_plat; - - if (mtu_desired) { - mtu_desired = NM_MAX (1280, mtu_desired); - - if (mtu_desired < ip6_mtu) - ip6_mtu = mtu_desired; - } - } - - _LOGT (LOGD_DEVICE, "mtu: device-mtu: %u%s, ipv6-mtu: %u%s, ifindex: %d", - (guint) mtu_desired, - mtu_desired == mtu_desired_orig ? "" : nm_sprintf_buf (sbuf1, " (was %u)", (guint) mtu_desired_orig), - (guint) ip6_mtu, - ip6_mtu == ip6_mtu_orig ? "" : nm_sprintf_buf (sbuf2, " (was %u)", (guint) ip6_mtu_orig), - ifindex); - -#define _IP6_MTU_SYS() \ - ({ \ - if (!ip6_mtu_sysctl.initialized) { \ - ip6_mtu_sysctl.value = nm_device_sysctl_ip_conf_get_int_checked (self, AF_INET6, "mtu", 10, 0, G_MAXUINT32, 0); \ - ip6_mtu_sysctl.initialized = TRUE; \ - } \ - ip6_mtu_sysctl.value; \ - }) - if ( (mtu_desired && mtu_desired != mtu_plat) - || (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ())) { - gboolean anticipated_failure = FALSE; - - if (!priv->mtu_initial && !priv->ip6_mtu_initial) { - /* before touching any of the MTU parameters, record the - * original setting to restore on deactivation. */ - priv->mtu_initial = mtu_plat; - priv->ip6_mtu_initial = _IP6_MTU_SYS (); - } - - if (mtu_desired && mtu_desired != mtu_plat) { - if (!NM_DEVICE_GET_CLASS (self)->set_platform_mtu (self, mtu_desired)) { - anticipated_failure = TRUE; - success = FALSE; - _LOGW (LOGD_DEVICE, "mtu: failure to set MTU. %s", - NM_IS_DEVICE_VLAN (self) - ? "Is the parent's MTU size large enough?" - : (!c_list_is_empty (&priv->slaves) - ? "Are the MTU sizes of the slaves large enough?" - : "Did you configure the MTU correctly?")); - } - priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_msec () + CARRIER_WAIT_TIME_AFTER_MTU_MS; - } - - if (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ()) { - if (!nm_device_sysctl_ip_conf_set (self, AF_INET6, "mtu", - nm_sprintf_buf (sbuf, "%u", (unsigned) ip6_mtu))) { - int errsv = errno; - NMLogLevel level = LOGL_WARN; - const char *msg = NULL; - - success = FALSE; - - if (anticipated_failure && errsv == EINVAL) { - level = LOGL_DEBUG; - msg = "Is the underlying MTU value successfully set?"; - } else if (!g_file_test ("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) { - level = LOGL_DEBUG; - msg = "IPv6 is disabled"; - success = TRUE; - } - - _NMLOG (level, - LOGD_DEVICE, - "mtu: failure to set IPv6 MTU%s%s", - msg ? ": " : "", - msg ?: ""); - } - priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_msec () + CARRIER_WAIT_TIME_AFTER_MTU_MS; - } - } - - if (success && source != NM_DEVICE_MTU_SOURCE_NONE) - priv->mtu_source = source; +_commit_mtu(NMDevice *self, const NMIP4Config *config) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceMtuSource source = NM_DEVICE_MTU_SOURCE_NONE; + guint32 ip6_mtu, ip6_mtu_orig; + guint32 mtu_desired, mtu_desired_orig; + guint32 mtu_plat; + struct { + gboolean initialized; + guint32 value; + } ip6_mtu_sysctl = { + 0, + }; + int ifindex; + char sbuf[64], sbuf1[64], sbuf2[64]; + gboolean success = TRUE; + + ifindex = nm_device_get_ip_ifindex(self); + if (ifindex <= 0) + return; + + if (!nm_device_get_applied_connection(self) + || nm_device_sys_iface_state_is_external_or_assume(self)) { + /* we don't tamper with the MTU of disconnected and + * external/assumed devices. */ + return; + } + + { + guint32 mtu = 0; + gboolean force = FALSE; + + /* We take the MTU from various sources: (in order of increasing + * priority) parent link, IP configuration (which contains the + * MTU from DHCP/PPP), connection profile. + * + * We could just compare it with the platform MTU and apply it + * when different, but this would revert at random times manual + * changes done by the user with the MTU from the connection. + * + * Instead, we remember the source of the currently configured + * MTU and apply the new one only when the new source has a + * higher priority, so that we don't set a MTU from same source + * multiple times. An exception to this is for the PARENT + * source, since we need to keep tracking the parent MTU when it + * changes. + * + * The subclass can set the @force argument to TRUE to signal that the + * returned MTU should be applied even if it has a lower priority. This + * is useful when the value from a lower source should + * preempt the one from higher ones. + */ + + if (NM_DEVICE_GET_CLASS(self)->get_configured_mtu) + mtu = NM_DEVICE_GET_CLASS(self)->get_configured_mtu(self, &source, &force); + + if (config && !force && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG + && nm_ip4_config_get_mtu(config)) { + mtu = nm_ip4_config_get_mtu(config); + source = NM_DEVICE_MTU_SOURCE_IP_CONFIG; + } + + if (mtu != 0) { + _LOGT(LOGD_DEVICE, + "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", + (guint) mtu, + mtu_source_to_str(source), + (guint) source, + mtu_source_to_str(priv->mtu_source), + (guint) priv->mtu_source, + force ? " (forced)" : ""); + } + + if (mtu != 0 + && (force || source > priv->mtu_source + || (priv->mtu_source == NM_DEVICE_MTU_SOURCE_PARENT && source == priv->mtu_source))) + mtu_desired = mtu; + else { + mtu_desired = 0; + source = NM_DEVICE_MTU_SOURCE_NONE; + } + } + + if (mtu_desired && mtu_desired < 1280) { + NMSettingIPConfig *s_ip6; + + s_ip6 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG); + if (s_ip6 + && !NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip6), + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + /* the interface has IPv6 enabled. The MTU with IPv6 cannot be smaller + * then 1280. + * + * For slave-devices (that don't have @s_ip6 we) don't do this fixup because + * it's anyway an unsolved problem when the slave configures a conflicting + * MTU. */ + mtu_desired = 1280; + } + } + + ip6_mtu = priv->ip6_mtu; + if (!ip6_mtu && priv->mtu_source == NM_DEVICE_MTU_SOURCE_NONE) { + /* initially, if the IPv6 MTU is not specified, grow it as large as the + * link MTU @mtu_desired. Only exception is, if @mtu_desired is so small + * to disable IPv6. */ + if (mtu_desired >= 1280) + ip6_mtu = mtu_desired; + } + + if (!ip6_mtu && !mtu_desired) + return; + + mtu_desired_orig = mtu_desired; + ip6_mtu_orig = ip6_mtu; + + mtu_plat = nm_platform_link_get_mtu(nm_device_get_platform(self), ifindex); + + if (ip6_mtu) { + ip6_mtu = NM_MAX(1280, ip6_mtu); + + if (!mtu_desired) + mtu_desired = mtu_plat; + + if (mtu_desired) { + mtu_desired = NM_MAX(1280, mtu_desired); + + if (mtu_desired < ip6_mtu) + ip6_mtu = mtu_desired; + } + } + + _LOGT(LOGD_DEVICE, + "mtu: device-mtu: %u%s, ipv6-mtu: %u%s, ifindex: %d", + (guint) mtu_desired, + mtu_desired == mtu_desired_orig + ? "" + : nm_sprintf_buf(sbuf1, " (was %u)", (guint) mtu_desired_orig), + (guint) ip6_mtu, + ip6_mtu == ip6_mtu_orig ? "" : nm_sprintf_buf(sbuf2, " (was %u)", (guint) ip6_mtu_orig), + ifindex); + +#define _IP6_MTU_SYS() \ + ({ \ + if (!ip6_mtu_sysctl.initialized) { \ + ip6_mtu_sysctl.value = nm_device_sysctl_ip_conf_get_int_checked(self, \ + AF_INET6, \ + "mtu", \ + 10, \ + 0, \ + G_MAXUINT32, \ + 0); \ + ip6_mtu_sysctl.initialized = TRUE; \ + } \ + ip6_mtu_sysctl.value; \ + }) + if ((mtu_desired && mtu_desired != mtu_plat) || (ip6_mtu && ip6_mtu != _IP6_MTU_SYS())) { + gboolean anticipated_failure = FALSE; + + if (!priv->mtu_initial && !priv->ip6_mtu_initial) { + /* before touching any of the MTU parameters, record the + * original setting to restore on deactivation. */ + priv->mtu_initial = mtu_plat; + priv->ip6_mtu_initial = _IP6_MTU_SYS(); + } + + if (mtu_desired && mtu_desired != mtu_plat) { + if (!NM_DEVICE_GET_CLASS(self)->set_platform_mtu(self, mtu_desired)) { + anticipated_failure = TRUE; + success = FALSE; + _LOGW(LOGD_DEVICE, + "mtu: failure to set MTU. %s", + NM_IS_DEVICE_VLAN(self) + ? "Is the parent's MTU size large enough?" + : (!c_list_is_empty(&priv->slaves) + ? "Are the MTU sizes of the slaves large enough?" + : "Did you configure the MTU correctly?")); + } + priv->carrier_wait_until_ms = + nm_utils_get_monotonic_timestamp_msec() + CARRIER_WAIT_TIME_AFTER_MTU_MS; + } + + if (ip6_mtu && ip6_mtu != _IP6_MTU_SYS()) { + if (!nm_device_sysctl_ip_conf_set(self, + AF_INET6, + "mtu", + nm_sprintf_buf(sbuf, "%u", (unsigned) ip6_mtu))) { + int errsv = errno; + NMLogLevel level = LOGL_WARN; + const char *msg = NULL; + + success = FALSE; + + if (anticipated_failure && errsv == EINVAL) { + level = LOGL_DEBUG; + msg = "Is the underlying MTU value successfully set?"; + } else if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) { + level = LOGL_DEBUG; + msg = "IPv6 is disabled"; + success = TRUE; + } + + _NMLOG(level, + LOGD_DEVICE, + "mtu: failure to set IPv6 MTU%s%s", + msg ? ": " : "", + msg ?: ""); + } + priv->carrier_wait_until_ms = + nm_utils_get_monotonic_timestamp_msec() + CARRIER_WAIT_TIME_AFTER_MTU_MS; + } + } + + if (success && source != NM_DEVICE_MTU_SOURCE_NONE) + priv->mtu_source = source; #undef _IP6_MTU_SYS } void -nm_device_commit_mtu (NMDevice *self) +nm_device_commit_mtu(NMDevice *self) { - NMDeviceState state; + NMDeviceState state; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - state = nm_device_get_state (self); - if ( state >= NM_DEVICE_STATE_CONFIG - && state < NM_DEVICE_STATE_DEACTIVATING) { - _LOGT (LOGD_DEVICE, "mtu: commit-mtu..."); - _commit_mtu (self, NM_DEVICE_GET_PRIVATE (self)->ip_config_4); - } else - _LOGT (LOGD_DEVICE, "mtu: commit-mtu... skip due to state %s", nm_device_state_to_str (state)); + state = nm_device_get_state(self); + if (state >= NM_DEVICE_STATE_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) { + _LOGT(LOGD_DEVICE, "mtu: commit-mtu..."); + _commit_mtu(self, NM_DEVICE_GET_PRIVATE(self)->ip_config_4); + } else + _LOGT(LOGD_DEVICE, + "mtu: commit-mtu... skip due to state %s", + nm_device_state_to_str(state)); } static void -ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self) -{ - NMNDiscConfigMap changed = changed_int; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - guint i; - - g_return_if_fail (priv->act_request.obj); - - if (!applied_config_get_current (&priv->ac_ip6_config)) - applied_config_init_new (&priv->ac_ip6_config, self, AF_INET6); - - if (changed & NM_NDISC_CONFIG_ADDRESSES) { - guint8 plen; - guint32 ifa_flags; - - /* Check, whether kernel is recent enough to help user space handling RA. - * If it's not supported, we have no ipv6-privacy and must add autoconf - * addresses as /128. The reason for the /128 is to prevent the kernel - * from adding a prefix route for this address. */ - ifa_flags = 0; - if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - ifa_flags |= IFA_F_NOPREFIXROUTE; - if (NM_IN_SET (priv->ndisc_use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) - ifa_flags |= IFA_F_MANAGETEMPADDR; - plen = 64; - } else - plen = 128; - - nm_ip6_config_reset_addresses_ndisc ((NMIP6Config *) priv->ac_ip6_config.orig, - rdata->addresses, - rdata->addresses_n, - plen, - ifa_flags); - if (priv->ac_ip6_config.current) { - nm_ip6_config_reset_addresses_ndisc ((NMIP6Config *) priv->ac_ip6_config.current, - rdata->addresses, - rdata->addresses_n, - plen, - ifa_flags); - } - } - - if (NM_FLAGS_ANY (changed, NM_NDISC_CONFIG_ROUTES - | NM_NDISC_CONFIG_GATEWAYS)) { - nm_ip6_config_reset_routes_ndisc ((NMIP6Config *) priv->ac_ip6_config.orig, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table (self, AF_INET6), - nm_device_get_route_metric (self, AF_INET6), - nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); - if (priv->ac_ip6_config.current) { - nm_ip6_config_reset_routes_ndisc ((NMIP6Config *) priv->ac_ip6_config.current, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table (self, AF_INET6), - nm_device_get_route_metric (self, AF_INET6), - nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); - } - - } - - if (changed & NM_NDISC_CONFIG_DNS_SERVERS) { - /* Rebuild DNS server list from neighbor discovery cache. */ - applied_config_reset_nameservers (&priv->ac_ip6_config); - - for (i = 0; i < rdata->dns_servers_n; i++) - applied_config_add_nameserver (&priv->ac_ip6_config, (const NMIPAddr *) &rdata->dns_servers[i].address); - } - - if (changed & NM_NDISC_CONFIG_DNS_DOMAINS) { - /* Rebuild domain list from neighbor discovery cache. */ - applied_config_reset_searches (&priv->ac_ip6_config); - - for (i = 0; i < rdata->dns_domains_n; i++) - applied_config_add_search (&priv->ac_ip6_config, rdata->dns_domains[i].domain); - } - - if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { - dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE); - - priv->dhcp6.mode = rdata->dhcp_level; - if (priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE) { - _LOGD (LOGD_DEVICE | LOGD_DHCP6, - "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6" - " as requested by IPv6 router..."); - if (!dhcp6_start (self, FALSE)) { - if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_DHCP_START_FAILED); - return; - } - } - } - } - - if (changed & NM_NDISC_CONFIG_HOP_LIMIT) - nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (nm_device_get_platform (self), nm_device_get_ip_iface (self), rdata->hop_limit); - - if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) { - nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (nm_device_get_platform (self), - nm_device_get_ip_iface (self), - rdata->reachable_time_ms); - } - - if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) { - nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (nm_device_get_platform (self), - nm_device_get_ip_iface (self), - rdata->retrans_timer_ms); - } - - if (changed & NM_NDISC_CONFIG_MTU) { - if (priv->ip6_mtu != rdata->mtu) { - _LOGD (LOGD_DEVICE, "mtu: set IPv6 MTU to %u", (guint) rdata->mtu); - priv->ip6_mtu = rdata->mtu; - } - } - - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); +ndisc_config_changed(NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self) +{ + NMNDiscConfigMap changed = changed_int; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + guint i; + + g_return_if_fail(priv->act_request.obj); + + if (!applied_config_get_current(&priv->ac_ip6_config)) + applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6); + + if (changed & NM_NDISC_CONFIG_ADDRESSES) { + guint8 plen; + guint32 ifa_flags; + + /* Check, whether kernel is recent enough to help user space handling RA. + * If it's not supported, we have no ipv6-privacy and must add autoconf + * addresses as /128. The reason for the /128 is to prevent the kernel + * from adding a prefix route for this address. */ + ifa_flags = 0; + if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { + ifa_flags |= IFA_F_NOPREFIXROUTE; + if (NM_IN_SET(priv->ndisc_use_tempaddr, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) + ifa_flags |= IFA_F_MANAGETEMPADDR; + plen = 64; + } else + plen = 128; + + nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.orig, + rdata->addresses, + rdata->addresses_n, + plen, + ifa_flags); + if (priv->ac_ip6_config.current) { + nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.current, + rdata->addresses, + rdata->addresses_n, + plen, + ifa_flags); + } + } + + if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) { + nm_ip6_config_reset_routes_ndisc( + (NMIP6Config *) priv->ac_ip6_config.orig, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6), + nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + if (priv->ac_ip6_config.current) { + nm_ip6_config_reset_routes_ndisc( + (NMIP6Config *) priv->ac_ip6_config.current, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6), + nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + } + } + + if (changed & NM_NDISC_CONFIG_DNS_SERVERS) { + /* Rebuild DNS server list from neighbor discovery cache. */ + applied_config_reset_nameservers(&priv->ac_ip6_config); + + for (i = 0; i < rdata->dns_servers_n; i++) + applied_config_add_nameserver(&priv->ac_ip6_config, + (const NMIPAddr *) &rdata->dns_servers[i].address); + } + + if (changed & NM_NDISC_CONFIG_DNS_DOMAINS) { + /* Rebuild domain list from neighbor discovery cache. */ + applied_config_reset_searches(&priv->ac_ip6_config); + + for (i = 0; i < rdata->dns_domains_n; i++) + applied_config_add_search(&priv->ac_ip6_config, rdata->dns_domains[i].domain); + } + + if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { + dhcp6_cleanup(self, CLEANUP_TYPE_DECONFIGURE, TRUE); + + priv->dhcp6.mode = rdata->dhcp_level; + if (priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE) { + _LOGD(LOGD_DEVICE | LOGD_DHCP6, + "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6" + " as requested by IPv6 router..."); + if (!dhcp6_start(self, FALSE)) { + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) { + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DHCP_START_FAILED); + return; + } + } + } + } + + if (changed & NM_NDISC_CONFIG_HOP_LIMIT) + nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(nm_device_get_platform(self), + nm_device_get_ip_iface(self), + rdata->hop_limit); + + if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) { + nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(nm_device_get_platform(self), + nm_device_get_ip_iface(self), + rdata->reachable_time_ms); + } + + if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) { + nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(nm_device_get_platform(self), + nm_device_get_ip_iface(self), + rdata->retrans_timer_ms); + } + + if (changed & NM_NDISC_CONFIG_MTU) { + if (priv->ip6_mtu != rdata->mtu) { + _LOGD(LOGD_DEVICE, "mtu: set IPv6 MTU to %u", (guint) rdata->mtu); + priv->ip6_mtu = rdata->mtu; + } + } + + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); } static void -ndisc_ra_timeout (NMNDisc *ndisc, NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - /* We don't want to stop listening for router advertisements completely, - * but instead let device activation continue activating. If an RA - * shows up later, we'll use it as long as the device is not disconnected. - */ - - _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement"); - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { - /* If RA is our only source of addressing information and we don't - * ever receive one, then time out IPv6. But if there is other - * IPv6 configuration, like manual IPv6 addresses or external IPv6 - * config, consider that sufficient for IPv6 success. - * - * FIXME: it doesn't seem correct to determine this based on which - * addresses we find inside priv->ip_config_6. - */ - if ( priv->ip_config_6 - && nm_ip6_config_find_first_address (priv->ip_config_6, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)) - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - else - nm_device_activate_schedule_ip_config_timeout (self, AF_INET6); - } +ndisc_ra_timeout(NMNDisc *ndisc, NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + /* We don't want to stop listening for router advertisements completely, + * but instead let device activation continue activating. If an RA + * shows up later, we'll use it as long as the device is not disconnected. + */ + + _LOGD(LOGD_IP6, "timed out waiting for IPv6 router advertisement"); + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { + /* If RA is our only source of addressing information and we don't + * ever receive one, then time out IPv6. But if there is other + * IPv6 configuration, like manual IPv6 addresses or external IPv6 + * config, consider that sufficient for IPv6 success. + * + * FIXME: it doesn't seem correct to determine this based on which + * addresses we find inside priv->ip_config_6. + */ + if (priv->ip_config_6 + && nm_ip6_config_find_first_address(priv->ip_config_6, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)) + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + else + nm_device_activate_schedule_ip_config_timeout(self, AF_INET6); + } } static void -addrconf6_start_with_link_ready (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMUtilsIPv6IfaceId iid; - - g_assert (priv->ndisc); - - if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { - _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier"); - nm_ndisc_set_iid (priv->ndisc, iid); - } else { - /* Don't abort the addrconf at this point -- if ndisc needs the iid - * it will notice this itself. */ - _LOGI (LOGD_IP6, "addrconf6: no interface identifier; IPv6 address creation may fail"); - } - - /* Apply any manual configuration before starting RA */ - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration"); - - if (nm_ndisc_get_node_type (priv->ndisc) == NM_NDISC_NODE_TYPE_ROUTER) { - nm_device_sysctl_ip_conf_set (self, AF_INET6, "forwarding", "1"); - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - priv->needs_ip6_subnet = TRUE; - g_signal_emit (self, signals[IP6_SUBNET_NEEDED], 0); - } - - priv->ndisc_changed_id = g_signal_connect (priv->ndisc, - NM_NDISC_CONFIG_RECEIVED, - G_CALLBACK (ndisc_config_changed), - self); - priv->ndisc_timeout_id = g_signal_connect (priv->ndisc, - NM_NDISC_RA_TIMEOUT_SIGNAL, - G_CALLBACK (ndisc_ra_timeout), - self); - - ndisc_set_router_config (priv->ndisc, self); - nm_ndisc_start (priv->ndisc); - priv->ndisc_started = TRUE; - return; -} - -static NMNDiscNodeType -ndisc_node_type (NMDevice *self) -{ - if (nm_streq (nm_device_get_effective_ip_config_method (self, AF_INET6), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) - return NM_NDISC_NODE_TYPE_ROUTER; - return NM_NDISC_NODE_TYPE_HOST; -} - -static gint32 -get_ra_timeout (NMDevice *self) -{ - NMConnection *connection; - gint32 timeout; - - G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_DEFAULT == 0); - G_STATIC_ASSERT_EXPR (NM_RA_TIMEOUT_INFINITY == G_MAXINT32); - - connection = nm_device_get_applied_connection (self); - - timeout = nm_setting_ip6_config_get_ra_timeout (NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection))); - nm_assert (timeout >= 0); - if (timeout) - return timeout; - - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ipv6.ra-timeout"), - self, - 0, G_MAXINT32, 0); +addrconf6_start_with_link_ready(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMUtilsIPv6IfaceId iid; + + g_assert(priv->ndisc); + + if (nm_device_get_ip_iface_identifier(self, &iid, FALSE)) { + _LOGD(LOGD_IP6, "addrconf6: using the device EUI-64 identifier"); + nm_ndisc_set_iid(priv->ndisc, iid); + } else { + /* Don't abort the addrconf at this point -- if ndisc needs the iid + * it will notice this itself. */ + _LOGI(LOGD_IP6, "addrconf6: no interface identifier; IPv6 address creation may fail"); + } + + /* Apply any manual configuration before starting RA */ + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed to apply manual IPv6 configuration"); + + if (nm_ndisc_get_node_type(priv->ndisc) == NM_NDISC_NODE_TYPE_ROUTER) { + nm_device_sysctl_ip_conf_set(self, AF_INET6, "forwarding", "1"); + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + priv->needs_ip6_subnet = TRUE; + g_signal_emit(self, signals[IP6_SUBNET_NEEDED], 0); + } + + priv->ndisc_changed_id = g_signal_connect(priv->ndisc, + NM_NDISC_CONFIG_RECEIVED, + G_CALLBACK(ndisc_config_changed), + self); + priv->ndisc_timeout_id = g_signal_connect(priv->ndisc, + NM_NDISC_RA_TIMEOUT_SIGNAL, + G_CALLBACK(ndisc_ra_timeout), + self); + + ndisc_set_router_config(priv->ndisc, self); + nm_ndisc_start(priv->ndisc); + priv->ndisc_started = TRUE; + return; } static gboolean -addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - NMSettingIP6Config *s_ip6 = NULL; - GError *error = NULL; - NMUtilsStableType stable_type; - const char *stable_id; - - connection = nm_device_get_applied_connection (self); - g_assert (connection); - - nm_assert (!applied_config_get_current (&priv->ac_ip6_config)); - applied_config_clear (&priv->ac_ip6_config); - - nm_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); - nm_clear_g_source (&priv->rt6_temporary_not_available_id); - - s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); - g_assert (s_ip6); - - stable_id = _get_stable_id (self, connection, &stable_type); - priv->ndisc = nm_lndp_ndisc_new (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - nm_device_get_ip_iface (self), - stable_type, - stable_id, - nm_setting_ip6_config_get_addr_gen_mode (s_ip6), - ndisc_node_type (self), - get_ra_timeout (self), - &error); - if (!priv->ndisc) { - _LOGE (LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message); - g_error_free (error); - return FALSE; - } - - priv->ndisc_use_tempaddr = use_tempaddr; - - if ( NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) - && !nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - _LOGW (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for " - "IPv6 private addresses. This feature is not available"); - } - - /* ensure link local is ready... */ - if (!linklocal6_start (self)) { - /* wait for the LL address to show up */ - return TRUE; - } - - /* already have the LL address; kick off neighbor discovery */ - addrconf6_start_with_link_ready (self); - return TRUE; +addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + NMSettingIP6Config *s_ip6 = NULL; + GError * error = NULL; + NMUtilsStableType stable_type; + const char * stable_id; + NMNDiscNodeType node_type; + int max_addresses; + int router_solicitations; + int router_solicitation_interval; + guint32 ra_timeout; + guint32 default_ra_timeout; + + connection = nm_device_get_applied_connection(self); + g_assert(connection); + + nm_assert(!applied_config_get_current(&priv->ac_ip6_config)); + applied_config_clear(&priv->ac_ip6_config); + + nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref); + nm_clear_g_source(&priv->rt6_temporary_not_available_id); + + s_ip6 = NM_SETTING_IP6_CONFIG(nm_connection_get_setting_ip6_config(connection)); + g_assert(s_ip6); + + if (nm_streq(nm_device_get_effective_ip_config_method(self, AF_INET6), + NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + node_type = NM_NDISC_NODE_TYPE_ROUTER; + else + node_type = NM_NDISC_NODE_TYPE_HOST; + + nm_lndp_ndisc_get_sysctl(nm_device_get_platform(self), + nm_device_get_ip_iface(self), + &max_addresses, + &router_solicitations, + &router_solicitation_interval, + &default_ra_timeout); + + if (node_type == NM_NDISC_NODE_TYPE_ROUTER) + ra_timeout = 0u; + else { + ra_timeout = _prop_get_ipv6_ra_timeout(self); + if (ra_timeout == 0u) + ra_timeout = default_ra_timeout; + } + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + priv->ndisc = nm_lndp_ndisc_new(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + nm_device_get_ip_iface(self), + stable_type, + stable_id, + nm_setting_ip6_config_get_addr_gen_mode(s_ip6), + node_type, + max_addresses, + router_solicitations, + router_solicitation_interval, + ra_timeout, + &error); + if (!priv->ndisc) { + _LOGE(LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message); + g_error_free(error); + return FALSE; + } + + priv->ndisc_use_tempaddr = use_tempaddr; + + if (NM_IN_SET(use_tempaddr, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) + && !nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { + _LOGW(LOGD_IP6, + "The kernel does not support extended IFA_FLAGS needed by NM for " + "IPv6 private addresses. This feature is not available"); + } + + /* ensure link local is ready... */ + if (!linklocal6_start(self)) { + /* wait for the LL address to show up */ + return TRUE; + } + + /* already have the LL address; kick off neighbor discovery */ + addrconf6_start_with_link_ready(self); + return TRUE; } static void -addrconf6_cleanup (NMDevice *self) +addrconf6_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->ndisc_started = FALSE; - nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_changed_id); - nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_timeout_id); + priv->ndisc_started = FALSE; + nm_clear_g_signal_handler(priv->ndisc, &priv->ndisc_changed_id); + nm_clear_g_signal_handler(priv->ndisc, &priv->ndisc_timeout_id); - applied_config_clear (&priv->ac_ip6_config); - nm_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); - nm_clear_g_source (&priv->rt6_temporary_not_available_id); - g_clear_object (&priv->ndisc); + applied_config_clear(&priv->ac_ip6_config); + nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref); + nm_clear_g_source(&priv->rt6_temporary_not_available_id); + if (priv->ndisc) { + nm_ndisc_stop(priv->ndisc); + g_clear_object(&priv->ndisc); + } } /*****************************************************************************/ static void -save_ip6_properties (NMDevice *self) -{ - static const char *const ip6_properties_to_save[] = { - "accept_ra", - "forwarding", - "disable_ipv6", - "hop_limit", - "use_tempaddr", - }; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform = nm_device_get_platform (self); - const char *ifname; - char *value; - int i; - - g_hash_table_remove_all (priv->ip6_saved_properties); - - ifname = nm_device_get_ip_iface_from_platform (self); - if (!ifname) - return; - - for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) { - value = nm_platform_sysctl_ip_conf_get (platform, - AF_INET6, - ifname, - ip6_properties_to_save[i]); - if (value) { - g_hash_table_insert (priv->ip6_saved_properties, - (char *) ip6_properties_to_save[i], - value); - } - } +save_ip6_properties(NMDevice *self) +{ + static const char *const ip6_properties_to_save[] = { + "accept_ra", + "forwarding", + "disable_ipv6", + "hop_limit", + "use_tempaddr", + }; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform * platform = nm_device_get_platform(self); + const char * ifname; + char * value; + int i; + + g_hash_table_remove_all(priv->ip6_saved_properties); + + ifname = nm_device_get_ip_iface_from_platform(self); + if (!ifname) + return; + + for (i = 0; i < G_N_ELEMENTS(ip6_properties_to_save); i++) { + value = + nm_platform_sysctl_ip_conf_get(platform, AF_INET6, ifname, ip6_properties_to_save[i]); + if (value) { + g_hash_table_insert(priv->ip6_saved_properties, + (char *) ip6_properties_to_save[i], + value); + } + } } static void -restore_ip6_properties (NMDevice *self) +restore_ip6_properties(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GHashTableIter iter; - gpointer key, value; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + GHashTableIter iter; + gpointer key, value; - g_hash_table_iter_init (&iter, priv->ip6_saved_properties); - while (g_hash_table_iter_next (&iter, &key, &value)) { - /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */ - if ( priv->ipv6ll_handle - && nm_streq (key, "disable_ipv6")) - continue; - nm_device_sysctl_ip_conf_set (self, AF_INET6, key, value); - } + g_hash_table_iter_init(&iter, priv->ip6_saved_properties); + while (g_hash_table_iter_next(&iter, &key, &value)) { + /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */ + if (priv->ipv6ll_handle && nm_streq(key, "disable_ipv6")) + continue; + nm_device_sysctl_ip_conf_set(self, AF_INET6, key, value); + } } static void -set_disable_ipv6 (NMDevice *self, const char *value) +set_disable_ipv6(NMDevice *self, const char *value) { - /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */ - if (!NM_DEVICE_GET_PRIVATE (self)->ipv6ll_handle) - nm_device_sysctl_ip_conf_set (self, AF_INET6, "disable_ipv6", value); + /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */ + if (!NM_DEVICE_GET_PRIVATE(self)->ipv6ll_handle) + nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", value); } static void -set_nm_ipv6ll (NMDevice *self, gboolean enable) +set_nm_ipv6ll(NMDevice *self, gboolean enable) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - int ifindex = nm_device_get_ip_ifindex (self); - - if (!nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - return; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int ifindex = nm_device_get_ip_ifindex(self); - priv->ipv6ll_handle = enable; - if (ifindex > 0) { - const char *detail = enable ? "enable" : "disable"; - int r; + if (!nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) + return; - _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail); - r = nm_platform_link_set_user_ipv6ll_enabled (nm_device_get_platform (self), ifindex, enable); - if (r < 0) { - _NMLOG ( NM_IN_SET (r, -NME_PL_NOT_FOUND, - -NME_PL_OPNOTSUPP) - ? LOGL_DEBUG - : LOGL_WARN, - LOGD_IP6, - "failed to %s userspace IPv6LL address handling (%s)", - detail, - nm_strerror (r)); - } + priv->ipv6ll_handle = enable; + if (ifindex > 0) { + const char *detail = enable ? "enable" : "disable"; + int r; - if (enable) { - gs_free char *value = NULL; - - /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ - value = nm_device_sysctl_ip_conf_get (self, - AF_INET6, - "disable_ipv6"); - if (nm_streq0 (value, "0")) - nm_device_sysctl_ip_conf_set (self, AF_INET6, "disable_ipv6", "1"); - - /* Ensure IPv6 is enabled */ - nm_device_sysctl_ip_conf_set (self, AF_INET6, "disable_ipv6", "0"); - } - - } -} + _LOGD(LOGD_IP6, "will %s userland IPv6LL", detail); + r = nm_platform_link_set_user_ipv6ll_enabled(nm_device_get_platform(self), ifindex, enable); + if (r < 0) { + _NMLOG(NM_IN_SET(r, -NME_PL_NOT_FOUND, -NME_PL_OPNOTSUPP) ? LOGL_DEBUG : LOGL_WARN, + LOGD_IP6, + "failed to %s userspace IPv6LL address handling (%s)", + detail, + nm_strerror(r)); + } -/*****************************************************************************/ + if (enable) { + gs_free char *value = NULL; -static NMSettingIP6ConfigPrivacy -_ip6_privacy_clamp (NMSettingIP6ConfigPrivacy use_tempaddr) -{ - switch (use_tempaddr) { - case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: - return use_tempaddr; - default: - return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - } -} + /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ + value = nm_device_sysctl_ip_conf_get(self, AF_INET6, "disable_ipv6"); + if (nm_streq0(value, "0")) + nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "1"); -static NMSettingIP6ConfigPrivacy -_ip6_privacy_get (NMDevice *self) -{ - NMSettingIP6ConfigPrivacy ip6_privacy; - NMConnection *connection; - - g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - - /* 1.) First look at the per-connection setting. If it is not -1 (unknown), - * use it. */ - connection = nm_device_get_applied_connection (self); - if (connection) { - NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); - - if (s_ip6) { - ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)); - ip6_privacy = _ip6_privacy_clamp (ip6_privacy); - if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) - return ip6_privacy; - } - } - - /* 2.) use the default value from the configuration. */ - ip6_privacy = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("ipv6.ip6-privacy"), - self, - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) - return ip6_privacy; - - if (!nm_device_get_ip_ifindex (self)) - return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - - /* 3.) No valid default-value configured. Fallback to reading sysctl. - * - * Instead of reading static config files in /etc, just read the current sysctl value. - * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves - * the "default" entry untouched. */ - ip6_privacy = nm_platform_sysctl_get_int32 (nm_device_get_platform (self), - NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv6/conf/default/use_tempaddr"), - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - return _ip6_privacy_clamp (ip6_privacy); + /* Ensure IPv6 is enabled */ + nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "0"); + } + } } /*****************************************************************************/ static gboolean -ip_requires_slaves (NMDevice *self, int addr_family) +ip_requires_slaves(NMDevice *self, int addr_family) { - const char *method; + const char *method; - method = nm_device_get_effective_ip_config_method (self, addr_family); + method = nm_device_get_effective_ip_config_method(self, addr_family); - if (addr_family == AF_INET) - return nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + if (addr_family == AF_INET) + return nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - /* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves) - * to complete addressing. SLAAC and DHCP need a peer to provide a prefix. - */ - return NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_DHCP); + /* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves) + * to complete addressing. SLAAC and DHCP need a peer to provide a prefix. + */ + return NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP); } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *self, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) -{ - const gboolean IS_IPv4 = (addr_family == AF_INET); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - const char *method; - - nm_assert_addr_family (addr_family); - - connection = nm_device_get_applied_connection (self); - - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - if ( connection_ip_method_requires_carrier (connection, addr_family, NULL) - && nm_device_is_master (self) - && !priv->carrier) { - _LOGI (LOGD_IP | LOGD_DEVICE, - "IPv%c config waiting until carrier is on", - nm_utils_addr_family_to_char (addr_family)); - return NM_ACT_STAGE_RETURN_IP_WAIT; - } - - if ( nm_device_is_master (self) - && ip_requires_slaves (self, addr_family)) { - /* If the master has no ready slaves, and depends on slaves for - * a successful IP configuration attempt, then postpone IP addressing. - */ - if (!have_any_ready_slaves (self)) { - _LOGI (LOGD_DEVICE | LOGD_IP, - "IPv%c config waiting until slaves are ready", - nm_utils_addr_family_to_char (addr_family)); - return NM_ACT_STAGE_RETURN_IP_WAIT; - } - } - - if (!IS_IPv4) - priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; - - method = nm_device_get_effective_ip_config_method (self, addr_family); - - _LOGD (LOGD_IP | LOGD_DEVICE, "IPv%c config method is %s", - nm_utils_addr_family_to_char (addr_family), method); - - if (IS_IPv4) { - if (NM_IN_STRSET (method, - NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - NMSettingIPConfig *s_ip4; - NMIP4Config **configs, *config; - guint num_addresses; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_return_val_if_fail (s_ip4, NM_ACT_STAGE_RETURN_FAILURE); - num_addresses = nm_setting_ip_config_get_num_addresses (s_ip4); - - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - ret = dhcp4_start (self); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); - return ret; - } - } else { - g_return_val_if_fail (num_addresses != 0, NM_ACT_STAGE_RETURN_FAILURE); - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (num_addresses) { - config = nm_device_ip4_config_new (self); - nm_ip4_config_merge_setting (config, - nm_connection_get_setting_ip4_config (connection), - NM_SETTING_CONNECTION_MDNS_DEFAULT, - NM_SETTING_CONNECTION_LLMNR_DEFAULT, - nm_device_get_route_table (self, AF_INET), - nm_device_get_route_metric (self, AF_INET)); - configs = g_new0 (NMIP4Config *, 2); - configs[0] = config; - ipv4_dad_start (self, configs, ipv4_manual_method_apply); - } - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { - ret = ipv4ll_start (self); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - if (out_config) { - *out_config = shared4_new_config (self, connection); - if (*out_config) { - priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self)); - ret = NM_ACT_STAGE_RETURN_SUCCESS; - } else { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - ret = NM_ACT_STAGE_RETURN_FAILURE; - } - } else - g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - ret = NM_ACT_STAGE_RETURN_SUCCESS; - else - _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); - - return ret; - } else { - NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - const char *ip6_privacy_str = "0"; - NMPlatform *platform; - int ifindex; - - if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { - nm_device_sysctl_ip_conf_set (self, AF_INET6, "disable_ipv6", "1"); - return NM_ACT_STAGE_RETURN_IP_DONE; - } - - if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { - if (!nm_device_sys_iface_state_is_external (self)) { - if (priv->master) { - /* If a device only has an IPv6 link-local address, - * we don't generate an assumed connection. Therefore, - * when a new slave connection (without IP configuration) - * is activated on the device, the link-local address - * remains configured. The IP configuration of an activated - * slave should not depend on the previous state. Flush - * addresses and routes on activation. - */ - ifindex = nm_device_get_ip_ifindex (self); - platform = nm_device_get_platform (self); - - if (ifindex > 0) { - gs_unref_object NMIP6Config *config = nm_device_ip6_config_new (self); - - nm_platform_ip_route_flush (platform, AF_INET6, ifindex); - nm_platform_ip_address_flush (platform, AF_INET6, ifindex); - nm_device_set_ip_config (self, AF_INET6, (NMIPConfig *) config, FALSE, NULL); - } - } else { - gboolean ipv6ll_handle_old = priv->ipv6ll_handle; - - /* When activating an IPv6 'ignore' connection we need to revert back - * to kernel IPv6LL, but the kernel won't actually assign an address - * to the interface until disable_ipv6 is bounced. - */ - set_nm_ipv6ll (self, FALSE); - if (ipv6ll_handle_old) - nm_device_sysctl_ip_conf_set (self, AF_INET6, "disable_ipv6", "1"); - restore_ip6_properties (self); - } - } - return NM_ACT_STAGE_RETURN_IP_DONE; - } - - /* Ensure the MTU makes sense. If it was below 1280 the kernel would not - * expose any ipv6 sysctls or allow presence of any addresses on the interface, - * including LL, which * would make it impossible to autoconfigure MTU to a - * correct value. */ - _commit_mtu (self, priv->ip_config_4); - - /* Any method past this point requires an IPv6LL address. Use NM-controlled - * IPv6LL if this is not an assumed connection, since assumed connections - * will already have IPv6 set up. - */ - if (!nm_device_sys_iface_state_is_external_or_assume (self)) - set_nm_ipv6ll (self, TRUE); - - /* Re-enable IPv6 on the interface */ - nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "0"); - set_disable_ipv6 (self, "0"); - - /* Synchronize external IPv6 configuration with kernel, since - * linklocal6_start() uses the information there to determine if we can - * proceed with the selected method (SLAAC, DHCP, link-local). - */ - nm_platform_process_events (nm_device_get_platform (self)); - g_clear_object (&priv->ext_ip6_config_captured); - priv->ext_ip6_config_captured = nm_ip6_config_capture (nm_device_get_multi_index (self), - nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - - ip6_privacy = _ip6_privacy_get (self); - - if (NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - if (!addrconf6_start (self, ip6_privacy)) { - /* IPv6 might be disabled; allow IPv4 to proceed */ - ret = NM_ACT_STAGE_RETURN_IP_FAIL; - } else - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { - ret = linklocal6_start (self) - ? NM_ACT_STAGE_RETURN_SUCCESS - : NM_ACT_STAGE_RETURN_POSTPONE; - } else if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { - priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_MANAGED; - if (!dhcp6_start (self, TRUE)) { - /* IPv6 might be disabled; allow IPv4 to proceed */ - ret = NM_ACT_STAGE_RETURN_IP_FAIL; - } else - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) - ret = NM_ACT_STAGE_RETURN_SUCCESS; - else - _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method); - - if ( ret != NM_ACT_STAGE_RETURN_FAILURE - && !nm_device_sys_iface_state_is_external_or_assume (self)) { - switch (ip6_privacy) { - case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: - case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: - ip6_privacy_str = "0"; - break; - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: - ip6_privacy_str = "1"; - break; - case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: - ip6_privacy_str = "2"; - break; - } - nm_device_sysctl_ip_conf_set (self, AF_INET6, "use_tempaddr", ip6_privacy_str); - } - - return ret; - } +act_stage3_ip_config_start(NMDevice * self, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) +{ + const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + const char * method; + + nm_assert_addr_family(addr_family); + + connection = nm_device_get_applied_connection(self); + + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + if (connection_ip_method_requires_carrier(connection, addr_family, NULL) + && nm_device_is_master(self) && !priv->carrier) { + _LOGI(LOGD_IP | LOGD_DEVICE, + "IPv%c config waiting until carrier is on", + nm_utils_addr_family_to_char(addr_family)); + return NM_ACT_STAGE_RETURN_IP_WAIT; + } + + if (nm_device_is_master(self) && ip_requires_slaves(self, addr_family)) { + /* If the master has no ready slaves, and depends on slaves for + * a successful IP configuration attempt, then postpone IP addressing. + */ + if (!have_any_ready_slaves(self)) { + _LOGI(LOGD_DEVICE | LOGD_IP, + "IPv%c config waiting until slaves are ready", + nm_utils_addr_family_to_char(addr_family)); + return NM_ACT_STAGE_RETURN_IP_WAIT; + } + } + + if (!IS_IPv4) + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; + + method = nm_device_get_effective_ip_config_method(self, addr_family); + + _LOGD(LOGD_IP | LOGD_DEVICE, + "IPv%c config method is %s", + nm_utils_addr_family_to_char(addr_family), + method); + + if (IS_IPv4) { + if (NM_IN_STRSET(method, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + NMSettingIPConfig *s_ip4; + NMIP4Config ** configs, *config; + guint num_addresses; + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_return_val_if_fail(s_ip4, NM_ACT_STAGE_RETURN_FAILURE); + num_addresses = nm_setting_ip_config_get_num_addresses(s_ip4); + + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + ret = dhcp4_start(self); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); + return ret; + } + } else { + g_return_val_if_fail(num_addresses != 0, NM_ACT_STAGE_RETURN_FAILURE); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (num_addresses) { + config = nm_device_ip4_config_new(self); + nm_ip4_config_merge_setting(config, + nm_connection_get_setting_ip4_config(connection), + NM_SETTING_CONNECTION_MDNS_DEFAULT, + NM_SETTING_CONNECTION_LLMNR_DEFAULT, + nm_device_get_route_table(self, AF_INET), + nm_device_get_route_metric(self, AF_INET)); + configs = g_new0(NMIP4Config *, 2); + configs[0] = config; + ipv4_dad_start(self, configs, ipv4_manual_method_apply); + } + } else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + ret = ipv4ll_start(self); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); + } else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + if (out_config) { + *out_config = shared4_new_config(self, connection); + if (*out_config) { + priv->dnsmasq_manager = nm_dnsmasq_manager_new(nm_device_get_ip_iface(self)); + ret = NM_ACT_STAGE_RETURN_SUCCESS; + } else { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + ret = NM_ACT_STAGE_RETURN_FAILURE; + } + } else + g_return_val_if_reached(NM_ACT_STAGE_RETURN_FAILURE); + } else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + ret = NM_ACT_STAGE_RETURN_SUCCESS; + else + _LOGW(LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); + + return ret; + } else { + NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + const char * ip6_privacy_str = "0"; + NMPlatform * platform; + int ifindex; + + if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "1"); + return NM_ACT_STAGE_RETURN_IP_DONE; + } + + if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + if (!nm_device_sys_iface_state_is_external(self)) { + if (priv->master) { + /* If a device only has an IPv6 link-local address, + * we don't generate an assumed connection. Therefore, + * when a new slave connection (without IP configuration) + * is activated on the device, the link-local address + * remains configured. The IP configuration of an activated + * slave should not depend on the previous state. Flush + * addresses and routes on activation. + */ + ifindex = nm_device_get_ip_ifindex(self); + platform = nm_device_get_platform(self); + + if (ifindex > 0) { + gs_unref_object NMIP6Config *config = nm_device_ip6_config_new(self); + + nm_platform_ip_route_flush(platform, AF_INET6, ifindex); + nm_platform_ip_address_flush(platform, AF_INET6, ifindex); + nm_device_set_ip_config(self, AF_INET6, (NMIPConfig *) config, FALSE, NULL); + } + } else { + gboolean ipv6ll_handle_old = priv->ipv6ll_handle; + + /* When activating an IPv6 'ignore' connection we need to revert back + * to kernel IPv6LL, but the kernel won't actually assign an address + * to the interface until disable_ipv6 is bounced. + */ + set_nm_ipv6ll(self, FALSE); + if (ipv6ll_handle_old) + nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "1"); + restore_ip6_properties(self); + } + } + return NM_ACT_STAGE_RETURN_IP_DONE; + } + + /* Ensure the MTU makes sense. If it was below 1280 the kernel would not + * expose any ipv6 sysctls or allow presence of any addresses on the interface, + * including LL, which * would make it impossible to autoconfigure MTU to a + * correct value. */ + _commit_mtu(self, priv->ip_config_4); + + /* Any method past this point requires an IPv6LL address. Use NM-controlled + * IPv6LL if this is not an assumed connection, since assumed connections + * will already have IPv6 set up. + */ + if (!nm_device_sys_iface_state_is_external_or_assume(self)) + set_nm_ipv6ll(self, TRUE); + + /* Re-enable IPv6 on the interface */ + nm_device_sysctl_ip_conf_set(self, AF_INET6, "accept_ra", "0"); + set_disable_ipv6(self, "0"); + + /* Synchronize external IPv6 configuration with kernel, since + * linklocal6_start() uses the information there to determine if we can + * proceed with the selected method (SLAAC, DHCP, link-local). + */ + nm_platform_process_events(nm_device_get_platform(self)); + g_clear_object(&priv->ext_ip6_config_captured); + priv->ext_ip6_config_captured = + nm_ip6_config_capture(nm_device_get_multi_index(self), + nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + + ip6_privacy = _prop_get_ipv6_ip6_privacy(self); + + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + if (!addrconf6_start(self, ip6_privacy)) { + /* IPv6 might be disabled; allow IPv4 to proceed */ + ret = NM_ACT_STAGE_RETURN_IP_FAIL; + } else + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) { + ret = + linklocal6_start(self) ? NM_ACT_STAGE_RETURN_SUCCESS : NM_ACT_STAGE_RETURN_POSTPONE; + } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_MANAGED; + if (!dhcp6_start(self, TRUE)) { + /* IPv6 might be disabled; allow IPv4 to proceed */ + ret = NM_ACT_STAGE_RETURN_IP_FAIL; + } else + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + ret = NM_ACT_STAGE_RETURN_SUCCESS; + else + _LOGW(LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method); + + if (ret != NM_ACT_STAGE_RETURN_FAILURE + && !nm_device_sys_iface_state_is_external_or_assume(self)) { + switch (ip6_privacy) { + case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + ip6_privacy_str = "0"; + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + ip6_privacy_str = "1"; + break; + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + ip6_privacy_str = "2"; + break; + } + nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", ip6_privacy_str); + } + + return ret; + } } /** @@ -11031,41 +11201,44 @@ act_stage3_ip_config_start (NMDevice *self, * Try starting IPv4 configuration. */ gboolean -nm_device_activate_stage3_ip4_start (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret; - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - gs_unref_object NMIP4Config *ip4_config = NULL; - - g_assert (priv->ip_state_4 == NM_DEVICE_IP_STATE_WAIT); - - if (nm_device_sys_iface_state_is_external (self)) { - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - return TRUE; - } - - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_CONF); - ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, AF_INET, (gpointer *) &ip4_config, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) - nm_device_activate_schedule_ip_config_result (self, AF_INET, NM_IP_CONFIG_CAST (ip4_config)); - else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) { - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return FALSE; - } else if (ret == NM_ACT_STAGE_RETURN_IP_FAIL) { - /* Activation not wanted */ - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_FAIL); - } else if (ret == NM_ACT_STAGE_RETURN_IP_WAIT) { - /* Wait for something to try IP config again */ - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - } else - g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE); - - return TRUE; +nm_device_activate_stage3_ip4_start(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMActStageReturn ret; + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + gs_unref_object NMIP4Config *ip4_config = NULL; + + g_assert(priv->ip_state_4 == NM_DEVICE_IP_STATE_WAIT); + + if (nm_device_sys_iface_state_is_external(self)) { + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + return TRUE; + } + + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_CONF); + ret = NM_DEVICE_GET_CLASS(self)->act_stage3_ip_config_start(self, + AF_INET, + (gpointer *) &ip4_config, + &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) + nm_device_activate_schedule_ip_config_result(self, AF_INET, NM_IP_CONFIG_CAST(ip4_config)); + else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) { + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return FALSE; + } else if (ret == NM_ACT_STAGE_RETURN_IP_FAIL) { + /* Activation not wanted */ + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_FAIL); + } else if (ret == NM_ACT_STAGE_RETURN_IP_WAIT) { + /* Wait for something to try IP config again */ + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); + } else + g_assert(ret == NM_ACT_STAGE_RETURN_POSTPONE); + + return TRUE; } /** @@ -11075,48 +11248,51 @@ nm_device_activate_stage3_ip4_start (NMDevice *self) * Try starting IPv6 configuration. */ gboolean -nm_device_activate_stage3_ip6_start (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret; - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - gs_unref_object NMIP6Config *ip6_config = NULL; - - g_assert (priv->ip_state_6 == NM_DEVICE_IP_STATE_WAIT); - - if (nm_device_sys_iface_state_is_external (self)) { - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - return TRUE; - } - - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_CONF); - ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, AF_INET6, (gpointer *) &ip6_config, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - if (!ip6_config) - ip6_config = nm_device_ip6_config_new (self); - /* Here we get a static IPv6 config, like for Shared where it's - * autogenerated or from modems where it comes from ModemManager. - */ - nm_assert (!applied_config_get_current (&priv->ac_ip6_config)); - applied_config_init (&priv->ac_ip6_config, ip6_config); - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - } else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) { - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return FALSE; - } else if (ret == NM_ACT_STAGE_RETURN_IP_FAIL) { - /* Activation not wanted */ - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_FAIL); - } else if (ret == NM_ACT_STAGE_RETURN_IP_WAIT) { - /* Wait for something to try IP config again */ - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - } else - g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE); - - return TRUE; +nm_device_activate_stage3_ip6_start(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMActStageReturn ret; + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + gs_unref_object NMIP6Config *ip6_config = NULL; + + g_assert(priv->ip_state_6 == NM_DEVICE_IP_STATE_WAIT); + + if (nm_device_sys_iface_state_is_external(self)) { + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + return TRUE; + } + + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_CONF); + ret = NM_DEVICE_GET_CLASS(self)->act_stage3_ip_config_start(self, + AF_INET6, + (gpointer *) &ip6_config, + &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + if (!ip6_config) + ip6_config = nm_device_ip6_config_new(self); + /* Here we get a static IPv6 config, like for Shared where it's + * autogenerated or from modems where it comes from ModemManager. + */ + nm_assert(!applied_config_get_current(&priv->ac_ip6_config)); + applied_config_init(&priv->ac_ip6_config, ip6_config); + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + } else if (ret == NM_ACT_STAGE_RETURN_IP_DONE) { + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return FALSE; + } else if (ret == NM_ACT_STAGE_RETURN_IP_FAIL) { + /* Activation not wanted */ + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_FAIL); + } else if (ret == NM_ACT_STAGE_RETURN_IP_WAIT) { + /* Wait for something to try IP config again */ + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); + } else + g_assert(ret == NM_ACT_STAGE_RETURN_POSTPONE); + + return TRUE; } /* @@ -11126,117 +11302,117 @@ nm_device_activate_stage3_ip6_start (NMDevice *self) * */ static void -activate_stage3_ip_config_start (NMDevice *self) +activate_stage3_ip_config_start(NMDevice *self) { - int ifindex; + int ifindex; - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - _active_connection_set_state_flags (self, - NM_ACTIVATION_STATE_FLAG_LAYER2_READY); + _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_LAYER2_READY); - nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); + nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); - /* Device should be up before we can do anything with it */ - if ( (ifindex = nm_device_get_ip_ifindex (self)) > 0 - && !nm_platform_link_is_up (nm_device_get_platform (self), ifindex)) - _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); + /* Device should be up before we can do anything with it */ + if ((ifindex = nm_device_get_ip_ifindex(self)) > 0 + && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex)) + _LOGW(LOGD_DEVICE, + "interface %s not up for IP configuration", + nm_device_get_ip_iface(self)); - /* IPv4 */ - if ( nm_device_activate_ip4_state_in_wait (self) - && !nm_device_activate_stage3_ip4_start (self)) - return; + /* IPv4 */ + if (nm_device_activate_ip4_state_in_wait(self) && !nm_device_activate_stage3_ip4_start(self)) + return; - /* IPv6 */ - if ( nm_device_activate_ip6_state_in_wait (self) - && !nm_device_activate_stage3_ip6_start (self)) - return; + /* IPv6 */ + if (nm_device_activate_ip6_state_in_wait(self) && !nm_device_activate_stage3_ip6_start(self)) + return; - /* Proxy */ - nm_device_set_proxy_config (self, NULL); + /* Proxy */ + nm_device_set_proxy_config(self, NULL); - check_ip_state (self, TRUE, TRUE); + check_ip_state(self, TRUE, TRUE); } static void -fw_change_zone_cb (NMFirewallManager *firewall_manager, - NMFirewallManagerCallId *call_id, - GError *error, - gpointer user_data) +fw_change_zone_cb(NMFirewallManager * firewall_manager, + NMFirewallManagerCallId *call_id, + GError * error, + gpointer user_data) { - NMDevice *self = user_data; - NMDevicePrivate *priv; + NMDevice * self = user_data; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->fw_call != call_id) - g_return_if_reached (); + if (priv->fw_call != call_id) + g_return_if_reached(); - priv->fw_call = NULL; + priv->fw_call = NULL; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - switch (priv->fw_state) { - case FIREWALL_STATE_WAIT_STAGE_3: - priv->fw_state = FIREWALL_STATE_INITIALIZED; - nm_device_activate_schedule_stage3_ip_config_start (self); - break; - case FIREWALL_STATE_WAIT_IP_CONFIG: - priv->fw_state = FIREWALL_STATE_INITIALIZED; - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE || priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) - nm_device_start_ip_check (self); - break; - case FIREWALL_STATE_INITIALIZED: - break; - default: - g_return_if_reached (); - } + switch (priv->fw_state) { + case FIREWALL_STATE_WAIT_STAGE_3: + priv->fw_state = FIREWALL_STATE_INITIALIZED; + nm_device_activate_schedule_stage3_ip_config_start(self); + break; + case FIREWALL_STATE_WAIT_IP_CONFIG: + priv->fw_state = FIREWALL_STATE_INITIALIZED; + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE + || priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) + nm_device_start_ip_check(self); + break; + case FIREWALL_STATE_INITIALIZED: + break; + default: + g_return_if_reached(); + } } static void -fw_change_zone (NMDevice *self) +fw_change_zone(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *applied_connection; - NMSettingConnection *s_con; - const char *zone; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * applied_connection; + NMSettingConnection *s_con; + const char * zone; - nm_assert (priv->fw_state >= FIREWALL_STATE_INITIALIZED); + nm_assert(priv->fw_state >= FIREWALL_STATE_INITIALIZED); - applied_connection = nm_device_get_applied_connection (self); - nm_assert (applied_connection); + applied_connection = nm_device_get_applied_connection(self); + nm_assert(applied_connection); - s_con = nm_connection_get_setting_connection (applied_connection); - nm_assert (s_con); + s_con = nm_connection_get_setting_connection(applied_connection); + nm_assert(s_con); - if (priv->fw_call) { - nm_firewall_manager_cancel_call (priv->fw_call); - nm_assert (!priv->fw_call); - } + if (priv->fw_call) { + nm_firewall_manager_cancel_call(priv->fw_call); + nm_assert(!priv->fw_call); + } - if (G_UNLIKELY (!priv->fw_mgr)) - priv->fw_mgr = g_object_ref (nm_firewall_manager_get ()); + if (G_UNLIKELY(!priv->fw_mgr)) + priv->fw_mgr = g_object_ref(nm_firewall_manager_get()); - zone = nm_setting_connection_get_zone (s_con); + zone = nm_setting_connection_get_zone(s_con); #if WITH_FIREWALLD_ZONE - if (!zone || zone[0] == '\0') { - if ( nm_streq0 (nm_device_get_effective_ip_config_method (self, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_SHARED) - || nm_streq0 (nm_device_get_effective_ip_config_method (self, AF_INET6), - NM_SETTING_IP6_CONFIG_METHOD_SHARED)) - zone = "nm-shared"; - } + if (!zone || zone[0] == '\0') { + if (nm_streq0(nm_device_get_effective_ip_config_method(self, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_SHARED) + || nm_streq0(nm_device_get_effective_ip_config_method(self, AF_INET6), + NM_SETTING_IP6_CONFIG_METHOD_SHARED)) + zone = "nm-shared"; + } #endif - priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_mgr, - nm_device_get_ip_iface (self), - zone, - FALSE, /* change zone */ - fw_change_zone_cb, - self); + priv->fw_call = nm_firewall_manager_add_or_change_zone(priv->fw_mgr, + nm_device_get_ip_iface(self), + zone, + FALSE, /* change zone */ + fw_change_zone_cb, + self); } /* @@ -11245,51 +11421,50 @@ fw_change_zone (NMDevice *self) * Schedule IP configuration start */ void -nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) +nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); - g_return_if_fail (priv->act_request.obj); + priv = NM_DEVICE_GET_PRIVATE(self); + g_return_if_fail(priv->act_request.obj); - /* Add the interface to the specified firewall zone */ - if (priv->fw_state == FIREWALL_STATE_UNMANAGED) { - if (!nm_device_sys_iface_state_is_external (self)) { - priv->fw_state = FIREWALL_STATE_WAIT_STAGE_3; - fw_change_zone (self); - return; - } + /* Add the interface to the specified firewall zone */ + if (priv->fw_state == FIREWALL_STATE_UNMANAGED) { + if (!nm_device_sys_iface_state_is_external(self)) { + priv->fw_state = FIREWALL_STATE_WAIT_STAGE_3; + fw_change_zone(self); + return; + } - /* fake success. */ - priv->fw_state = FIREWALL_STATE_INITIALIZED; - } else if (priv->fw_state == FIREWALL_STATE_WAIT_STAGE_3) { - /* a firewall call for stage3 is pending. Return and wait. */ - return; - } + /* fake success. */ + priv->fw_state = FIREWALL_STATE_INITIALIZED; + } else if (priv->fw_state == FIREWALL_STATE_WAIT_STAGE_3) { + /* a firewall call for stage3 is pending. Return and wait. */ + return; + } - nm_assert (priv->fw_state == FIREWALL_STATE_INITIALIZED); + nm_assert(priv->fw_state == FIREWALL_STATE_INITIALIZED); - activation_source_schedule (self, activate_stage3_ip_config_start, AF_INET); + activation_source_schedule(self, activate_stage3_ip_config_start, AF_INET); } static NMActStageReturn -act_stage4_ip_config_timeout (NMDevice *self, - int addr_family, - NMDeviceStateReason *out_failure_reason) +act_stage4_ip_config_timeout(NMDevice * self, + int addr_family, + NMDeviceStateReason *out_failure_reason) { - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - if (!get_ip_config_may_fail (self, addr_family)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return NM_ACT_STAGE_RETURN_FAILURE; - } + if (!get_ip_config_may_fail(self, addr_family)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return NM_ACT_STAGE_RETURN_FAILURE; + } - return NM_ACT_STAGE_RETURN_SUCCESS; + return NM_ACT_STAGE_RETURN_SUCCESS; } - /* * nm_device_activate_stage4_ip4_config_timeout * @@ -11297,417 +11472,469 @@ act_stage4_ip_config_timeout (NMDevice *self, * */ static void -activate_stage4_ip_config_timeout_4 (NMDevice *self) +activate_stage4_ip_config_timeout_4(NMDevice *self) { - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip_config_timeout (self, AF_INET6, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - return; - else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return; - } - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + ret = NM_DEVICE_GET_CLASS(self)->act_stage4_ip_config_timeout(self, AF_INET, &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + return; + else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return; + } + g_assert(ret == NM_ACT_STAGE_RETURN_SUCCESS); - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_FAIL); + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_FAIL); - check_ip_state (self, FALSE, TRUE); + check_ip_state(self, FALSE, TRUE); } void -nm_device_activate_schedule_ip_config_timeout (NMDevice *self, - int addr_family) +nm_device_activate_schedule_ip_config_timeout(NMDevice *self, int addr_family) { - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - g_return_if_fail (priv->act_request.obj); + g_return_if_fail(priv->act_request.obj); - activation_source_schedule (self, activate_stage4_ip_config_timeout_x[IS_IPv4], addr_family); + activation_source_schedule(self, activate_stage4_ip_config_timeout_x[IS_IPv4], addr_family); } static void -activate_stage4_ip_config_timeout_6 (NMDevice *self) +activate_stage4_ip_config_timeout_6(NMDevice *self) { - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip_config_timeout (self, AF_INET6, &failure_reason); - if (ret == NM_ACT_STAGE_RETURN_POSTPONE) - return; - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, failure_reason); - return; - } - g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + ret = NM_DEVICE_GET_CLASS(self)->act_stage4_ip_config_timeout(self, AF_INET6, &failure_reason); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) + return; + if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); + return; + } + g_assert(ret == NM_ACT_STAGE_RETURN_SUCCESS); - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_FAIL); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_FAIL); - check_ip_state (self, FALSE, TRUE); + check_ip_state(self, FALSE, TRUE); } static gboolean -share_init (NMDevice *self, GError **error) -{ - char *modules[] = { "ip_tables", "iptable_nat", "nf_nat_ftp", "nf_nat_irc", - "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323", - NULL }; - char **iter; - int errsv; - - if (nm_platform_sysctl_get_int32 (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_forward"), -1) == 1) { - /* nothing to do. */ - } else if (!nm_platform_sysctl_set (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_forward"), "1")) { - errsv = errno; - _LOGD (LOGD_SHARING, "share: error enabling IPv4 forwarding: (%d) %s", - errsv, nm_strerror_native (errsv)); - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "cannot set ipv4/ip_forward: %s", nm_strerror_native (errsv)); - return FALSE; - } - - if (nm_platform_sysctl_get_int32 (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_dynaddr"), -1) == 1) { - /* nothing to do. */ - } else if (!nm_platform_sysctl_set (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_dynaddr"), "1")) { - errsv = errno; - _LOGD (LOGD_SHARING, "share: error enabling dynamic addresses: (%d) %s", - errsv, nm_strerror_native (errsv)); - } - - for (iter = modules; *iter; iter++) - nm_utils_modprobe (NULL, FALSE, *iter, NULL); - - return TRUE; -} - -#define add_share_rule(req, table, ...) \ - G_STMT_START { \ - char *_cmd = g_strdup_printf (__VA_ARGS__); \ - nm_act_request_add_share_rule (req, table, _cmd); \ - g_free (_cmd); \ - } G_STMT_END +share_init(NMDevice *self, GError **error) +{ + char * modules[] = {"ip_tables", + "iptable_nat", + "nf_nat_ftp", + "nf_nat_irc", + "nf_nat_sip", + "nf_nat_tftp", + "nf_nat_pptp", + "nf_nat_h323", + NULL}; + char **iter; + int errsv; + + if (nm_platform_sysctl_get_int32(nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/ip_forward"), + -1) + == 1) { + /* nothing to do. */ + } else if (!nm_platform_sysctl_set(nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/ip_forward"), + "1")) { + errsv = errno; + _LOGD(LOGD_SHARING, + "share: error enabling IPv4 forwarding: (%d) %s", + errsv, + nm_strerror_native(errsv)); + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "cannot set ipv4/ip_forward: %s", + nm_strerror_native(errsv)); + return FALSE; + } + + if (nm_platform_sysctl_get_int32(nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/ip_dynaddr"), + -1) + == 1) { + /* nothing to do. */ + } else if (!nm_platform_sysctl_set(nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/ip_dynaddr"), + "1")) { + errsv = errno; + _LOGD(LOGD_SHARING, + "share: error enabling dynamic addresses: (%d) %s", + errsv, + nm_strerror_native(errsv)); + } + + for (iter = modules; *iter; iter++) + nm_utils_modprobe(NULL, FALSE, *iter, NULL); + + return TRUE; +} + +#define add_share_rule(req, table, ...) \ + G_STMT_START \ + { \ + char *_cmd = g_strdup_printf(__VA_ARGS__); \ + nm_act_request_add_share_rule(req, table, _cmd); \ + g_free(_cmd); \ + } \ + G_STMT_END static gboolean -start_sharing (NMDevice *self, NMIP4Config *config, GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *req; - char str_addr[INET_ADDRSTRLEN]; - char str_mask[INET_ADDRSTRLEN]; - guint32 netmask, network; - const NMPlatformIP4Address *ip4_addr = NULL; - const char *ip_iface; - GError *local = NULL; - NMConnection *conn; - NMSettingConnection *s_con; - gboolean announce_android_metered; - - g_return_val_if_fail (config, FALSE); - - ip_iface = nm_device_get_ip_iface (self); - if (!ip_iface) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "device has no ip interface"); - return FALSE; - } - - ip4_addr = nm_ip4_config_get_first_address (config); - if (!ip4_addr || !ip4_addr->address) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "could not determine IPv4 address"); - return FALSE; - } - - if (!share_init (self, error)) - return FALSE; - - req = nm_device_get_act_request (self); - g_return_val_if_fail (req, FALSE); - - netmask = _nm_utils_ip4_prefix_to_netmask (ip4_addr->plen); - _nm_utils_inet4_ntop (netmask, str_mask); - - network = ip4_addr->address & netmask; - _nm_utils_inet4_ntop (network, str_addr); - - add_share_rule (req, "nat", "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", str_addr, str_mask, str_addr, str_mask); - add_share_rule (req, "filter", "FORWARD --destination %s/%s --out-interface %s --match state --state ESTABLISHED,RELATED --jump ACCEPT", str_addr, str_mask, ip_iface); - add_share_rule (req, "filter", "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", str_addr, str_mask, ip_iface); - add_share_rule (req, "filter", "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", ip_iface, ip_iface); - add_share_rule (req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface); - add_share_rule (req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface); - add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", ip_iface); - add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", ip_iface); - add_share_rule (req, "filter", "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", ip_iface); - add_share_rule (req, "filter", "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", ip_iface); - - nm_act_request_set_shared (req, TRUE); - - conn = nm_act_request_get_applied_connection (req); - s_con = nm_connection_get_setting_connection (conn); - - switch (nm_setting_connection_get_metered (s_con)) { - case NM_METERED_YES: - /* honor the metered flag. Note that reapply on the device does not affect - * the metered setting. This is different from other profiles, where the - * metered flag of an activated profile can be changed (reapplied). */ - announce_android_metered = TRUE; - break; - case NM_METERED_UNKNOWN: - /* we pick up the current value and announce it. But again, we cannot update - * the announced setting without restarting dnsmasq. That means, if the default - * route changes w.r.t. being metered, then the shared connection does not get - * updated before reactivating. */ - announce_android_metered = NM_IN_SET (nm_manager_get_metered (NM_MANAGER_GET), - NM_METERED_YES, - NM_METERED_GUESS_YES); - break; - default: - announce_android_metered = FALSE; - break; - } - - - if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, - config, - announce_android_metered, - &local)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "could not start dnsmasq due to %s", local->message); - g_error_free (local); - nm_act_request_set_shared (req, FALSE); - return FALSE; - } - - priv->dnsmasq_state_id = g_signal_connect (priv->dnsmasq_manager, NM_DNS_MASQ_MANAGER_STATE_CHANGED, - G_CALLBACK (dnsmasq_state_changed_cb), - self); - return TRUE; +start_sharing(NMDevice *self, NMIP4Config *config, GError **error) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMActRequest * req; + char str_addr[INET_ADDRSTRLEN]; + char str_mask[INET_ADDRSTRLEN]; + guint32 netmask, network; + const NMPlatformIP4Address *ip4_addr = NULL; + const char * ip_iface; + GError * local = NULL; + NMConnection * conn; + NMSettingConnection * s_con; + gboolean announce_android_metered; + + g_return_val_if_fail(config, FALSE); + + ip_iface = nm_device_get_ip_iface(self); + if (!ip_iface) { + g_set_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "device has no ip interface"); + return FALSE; + } + + ip4_addr = nm_ip4_config_get_first_address(config); + if (!ip4_addr || !ip4_addr->address) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "could not determine IPv4 address"); + return FALSE; + } + + if (!share_init(self, error)) + return FALSE; + + req = nm_device_get_act_request(self); + g_return_val_if_fail(req, FALSE); + + netmask = _nm_utils_ip4_prefix_to_netmask(ip4_addr->plen); + _nm_utils_inet4_ntop(netmask, str_mask); + + network = ip4_addr->address & netmask; + _nm_utils_inet4_ntop(network, str_addr); + + add_share_rule(req, + "nat", + "POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE", + str_addr, + str_mask, + str_addr, + str_mask); + add_share_rule(req, + "filter", + "FORWARD --destination %s/%s --out-interface %s --match state --state " + "ESTABLISHED,RELATED --jump ACCEPT", + str_addr, + str_mask, + ip_iface); + add_share_rule(req, + "filter", + "FORWARD --source %s/%s --in-interface %s --jump ACCEPT", + str_addr, + str_mask, + ip_iface); + add_share_rule(req, + "filter", + "FORWARD --in-interface %s --out-interface %s --jump ACCEPT", + ip_iface, + ip_iface); + add_share_rule(req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface); + add_share_rule(req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface); + add_share_rule(req, + "filter", + "INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT", + ip_iface); + add_share_rule(req, + "filter", + "INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT", + ip_iface); + add_share_rule(req, + "filter", + "INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT", + ip_iface); + add_share_rule(req, + "filter", + "INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT", + ip_iface); + + nm_act_request_set_shared(req, TRUE); + + conn = nm_act_request_get_applied_connection(req); + s_con = nm_connection_get_setting_connection(conn); + + switch (nm_setting_connection_get_metered(s_con)) { + case NM_METERED_YES: + /* honor the metered flag. Note that reapply on the device does not affect + * the metered setting. This is different from other profiles, where the + * metered flag of an activated profile can be changed (reapplied). */ + announce_android_metered = TRUE; + break; + case NM_METERED_UNKNOWN: + /* we pick up the current value and announce it. But again, we cannot update + * the announced setting without restarting dnsmasq. That means, if the default + * route changes w.r.t. being metered, then the shared connection does not get + * updated before reactivating. */ + announce_android_metered = + NM_IN_SET(nm_manager_get_metered(NM_MANAGER_GET), NM_METERED_YES, NM_METERED_GUESS_YES); + break; + default: + announce_android_metered = FALSE; + break; + } + + if (!nm_dnsmasq_manager_start(priv->dnsmasq_manager, + config, + announce_android_metered, + &local)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "could not start dnsmasq due to %s", + local->message); + g_error_free(local); + nm_act_request_set_shared(req, FALSE); + return FALSE; + } + + priv->dnsmasq_state_id = g_signal_connect(priv->dnsmasq_manager, + NM_DNS_MASQ_MANAGER_STATE_CHANGED, + G_CALLBACK(dnsmasq_state_changed_cb), + self); + return TRUE; } static void -arp_cleanup (NMDevice *self) +arp_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_clear_pointer (&priv->acd.announcing, nm_acd_manager_free); + nm_clear_pointer(&priv->acd.announcing, nm_acd_manager_free); } void -nm_device_arp_announce (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - NMSettingIPConfig *s_ip4; - guint num, i; - const guint8 *hw_addr; - size_t hw_addr_len = 0; - - arp_cleanup (self); - - hw_addr = nm_platform_link_get_address (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self), - &hw_addr_len); - - if (!hw_addr || hw_addr_len != ETH_ALEN) - return; - - /* We only care about manually-configured addresses; DHCP- and autoip-configured - * ones should already have been seen on the network at this point. - */ - connection = nm_device_get_applied_connection (self); - if (!connection) - return; - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) - return; - num = nm_setting_ip_config_get_num_addresses (s_ip4); - if (num == 0) - return; - - priv->acd.announcing = nm_acd_manager_new (nm_device_get_ip_ifindex (self), - hw_addr, - hw_addr_len, - NULL, - NULL); - - for (i = 0; i < num; i++) { - NMIPAddress *ip = nm_setting_ip_config_get_address (s_ip4, i); - in_addr_t addr; - - if (inet_pton (AF_INET, nm_ip_address_get_address (ip), &addr) == 1) - nm_acd_manager_add_address (priv->acd.announcing, addr); - else - g_warn_if_reached (); - } - - nm_acd_manager_announce_addresses (priv->acd.announcing); +nm_device_arp_announce(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + NMSettingIPConfig *s_ip4; + guint num, i; + const guint8 * hw_addr; + size_t hw_addr_len = 0; + + arp_cleanup(self); + + hw_addr = nm_platform_link_get_address(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + &hw_addr_len); + + if (!hw_addr || hw_addr_len != ETH_ALEN) + return; + + /* We only care about manually-configured addresses; DHCP- and autoip-configured + * ones should already have been seen on the network at this point. + */ + connection = nm_device_get_applied_connection(self); + if (!connection) + return; + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (!s_ip4) + return; + num = nm_setting_ip_config_get_num_addresses(s_ip4); + if (num == 0) + return; + + priv->acd.announcing = + nm_acd_manager_new(nm_device_get_ip_ifindex(self), hw_addr, hw_addr_len, NULL, NULL); + + for (i = 0; i < num; i++) { + NMIPAddress *ip = nm_setting_ip_config_get_address(s_ip4, i); + in_addr_t addr; + + if (inet_pton(AF_INET, nm_ip_address_get_address(ip), &addr) == 1) + nm_acd_manager_add_address(priv->acd.announcing, addr); + else + g_warn_if_reached(); + } + + nm_acd_manager_announce_addresses(priv->acd.announcing); } static void -activate_stage5_ip_config_result_4 (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *req; - const char *method; - int ip_ifindex; - gboolean do_announce = FALSE; - - req = nm_device_get_act_request (self); - g_assert (req); - - /* Interface must be IFF_UP before IP config can be applied */ - ip_ifindex = nm_device_get_ip_ifindex (self); - if (!nm_platform_link_is_up (nm_device_get_platform (self), ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) { - nm_platform_link_set_up (nm_device_get_platform (self), ip_ifindex, NULL); - if (!nm_platform_link_is_up (nm_device_get_platform (self), ip_ifindex)) - _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); - } - - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) { - _LOGD (LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed"); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return; - } - - /* Start IPv4 sharing if we need it */ - method = nm_device_get_effective_ip_config_method (self, AF_INET); - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - gs_free_error GError *error = NULL; - - if (!start_sharing (self, priv->ip_config_4, &error)) { - _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed: %s", error->message); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); - return; - } - } - - if (priv->dhcp_data_4.client) { - gs_free_error GError *error = NULL; - - if (!nm_dhcp_client_accept (priv->dhcp_data_4.client, &error)) { - _LOGW (LOGD_DHCP4, - "Activation: Stage 5 of 5 (IPv4 Commit) error accepting lease: %s", - error->message); - nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_DHCP_ERROR); - return; - } - } - - /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure - * dispatcher scripts get the DHCP lease information. - */ - if ( priv->dhcp_data_4.client - && nm_device_activate_ip4_state_in_conf (self) - && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) { - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE, - self, - NULL, - NULL, NULL, NULL); - } - - /* Send ARP announcements */ - - if (nm_device_is_master (self)) { - CList *iter; - SlaveInfo *info; - - /* Skip announcement if there are no device enslaved, for two reasons: - * 1) the master has a temporary MAC address until the first slave comes - * 2) announcements are going to be dropped anyway without slaves - */ - do_announce = FALSE; - - c_list_for_each (iter, &priv->slaves) { - info = c_list_entry (iter, SlaveInfo, lst_slave); - if (info->slave_is_enslaved) { - do_announce = TRUE; - break; - } - } - } else - do_announce = TRUE; - - if (do_announce) - nm_device_arp_announce (self); - - /* Enter the IP_CHECK state if this is the first method to complete */ - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); +activate_stage5_ip_config_result_4(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMActRequest * req; + const char * method; + int ip_ifindex; + gboolean do_announce = FALSE; + + req = nm_device_get_act_request(self); + g_assert(req); + + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex(self); + if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex) + && !nm_device_sys_iface_state_is_external_or_assume(self)) { + nm_platform_link_set_up(nm_device_get_platform(self), ip_ifindex, NULL); + if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex)) + _LOGW(LOGD_DEVICE, + "interface %s not up for IP configuration", + nm_device_get_ip_iface(self)); + } + + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) { + _LOGD(LOGD_DEVICE | LOGD_IP4, "Activation: Stage 5 of 5 (IPv4 Commit) failed"); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + + /* Start IPv4 sharing if we need it */ + method = nm_device_get_effective_ip_config_method(self, AF_INET); + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + gs_free_error GError *error = NULL; + + if (!start_sharing(self, priv->ip_config_4, &error)) { + _LOGW(LOGD_SHARING, + "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed: %s", + error->message); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + return; + } + } + + if (priv->dhcp_data_4.client) { + gs_free_error GError *error = NULL; + + if (!nm_dhcp_client_accept(priv->dhcp_data_4.client, &error)) { + _LOGW(LOGD_DHCP4, + "Activation: Stage 5 of 5 (IPv4 Commit) error accepting lease: %s", + error->message); + nm_device_ip_method_failed(self, AF_INET, NM_DEVICE_STATE_REASON_DHCP_ERROR); + return; + } + } + + /* If IPv4 wasn't the first to complete, and DHCP was used, then ensure + * dispatcher scripts get the DHCP lease information. + */ + if (priv->dhcp_data_4.client && nm_device_activate_ip4_state_in_conf(self) + && (nm_device_get_state(self) > NM_DEVICE_STATE_IP_CONFIG)) { + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP4_CHANGE, self, NULL, NULL, NULL, NULL); + } + + /* Send ARP announcements */ + + if (nm_device_is_master(self)) { + CList * iter; + SlaveInfo *info; + + /* Skip announcement if there are no device enslaved, for two reasons: + * 1) the master has a temporary MAC address until the first slave comes + * 2) announcements are going to be dropped anyway without slaves + */ + do_announce = FALSE; + + c_list_for_each (iter, &priv->slaves) { + info = c_list_entry(iter, SlaveInfo, lst_slave); + if (info->slave_is_enslaved) { + do_announce = TRUE; + break; + } + } + } else + do_announce = TRUE; + + if (do_announce) + nm_device_arp_announce(self); + + /* Enter the IP_CHECK state if this is the first method to complete */ + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); } void -nm_device_activate_schedule_ip_config_result (NMDevice *self, - int addr_family, - NMIPConfig *config) +nm_device_activate_schedule_ip_config_result(NMDevice *self, int addr_family, NMIPConfig *config) { - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - g_return_if_fail ( !config - || ( addr_family == AF_INET - && nm_ip_config_get_addr_family (config) == AF_INET)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + g_return_if_fail( + !config || (addr_family == AF_INET && nm_ip_config_get_addr_family(config) == AF_INET)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (IS_IPv4) { - applied_config_init (&priv->dev_ip_config_4, config); - } else { - /* If IP had previously failed, move it back to NM_DEVICE_IP_STATE_CONF since we - * clearly now have configuration. - */ - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_CONF); - } + if (IS_IPv4) { + applied_config_init(&priv->dev_ip_config_4, config); + } else { + /* If IP had previously failed, move it back to NM_DEVICE_IP_STATE_CONF since we + * clearly now have configuration. + */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL) + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_CONF); + } - activation_source_schedule (self, activate_stage5_ip_config_result_x[IS_IPv4], addr_family); + activation_source_schedule(self, activate_stage5_ip_config_result_x[IS_IPv4], addr_family); } NMDeviceIPState -nm_device_activate_get_ip_state (NMDevice *self, - int addr_family) +nm_device_activate_get_ip_state(NMDevice *self, int addr_family) { - const gboolean IS_IPv4 = (addr_family == AF_INET); + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_IP_STATE_NONE); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), NM_DEVICE_IP_STATE_NONE); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_IP_STATE_NONE); + g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), NM_DEVICE_IP_STATE_NONE); - return NM_DEVICE_GET_PRIVATE (self)->ip_state_x[IS_IPv4]; + return NM_DEVICE_GET_PRIVATE(self)->ip_state_x[IS_IPv4]; } static void -dad6_add_pending_address (NMDevice *self, - NMPlatform *platform, - int ifindex, - const struct in6_addr *address, - NMIP6Config **dad6_config) +dad6_add_pending_address(NMDevice * self, + NMPlatform * platform, + int ifindex, + const struct in6_addr *address, + NMIP6Config ** dad6_config) { - const NMPlatformIP6Address *pl_addr; + const NMPlatformIP6Address *pl_addr; - pl_addr = nm_platform_ip6_address_get (platform, - ifindex, - *address); - if ( pl_addr - && NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_TENTATIVE) - && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_DADFAILED) - && !NM_FLAGS_HAS (pl_addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { - _LOGt (LOGD_DEVICE, "IPv6 DAD: pending address %s", - nm_platform_ip6_address_to_string (pl_addr, NULL, 0)); + pl_addr = nm_platform_ip6_address_get(platform, ifindex, address); + if (pl_addr && NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_TENTATIVE) + && !NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_DADFAILED) + && !NM_FLAGS_HAS(pl_addr->n_ifa_flags, IFA_F_OPTIMISTIC)) { + _LOGt(LOGD_DEVICE, + "IPv6 DAD: pending address %s", + nm_platform_ip6_address_to_string(pl_addr, NULL, 0)); - if (!*dad6_config) - *dad6_config = nm_device_ip6_config_new (self); + if (!*dad6_config) + *dad6_config = nm_device_ip6_config_new(self); - nm_ip6_config_add_address (*dad6_config, pl_addr); - } + nm_ip6_config_add_address(*dad6_config, pl_addr); + } } /* @@ -11715,199 +11942,184 @@ dad6_add_pending_address (NMDevice *self, * have the tentative flag, or NULL if none is present. */ static NMIP6Config * -dad6_get_pending_addresses (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMIP6Config *confs[] = { (NMIP6Config *) applied_config_get_current (&priv->ac_ip6_config), - (NMIP6Config *) applied_config_get_current (&priv->dhcp6.ip6_config), - priv->con_ip_config_6, - (NMIP6Config *) applied_config_get_current (&priv->dev2_ip_config_6) }; - const NMPlatformIP6Address *addr; - NMIP6Config *dad6_config = NULL; - NMDedupMultiIter ipconf_iter; - guint i; - int ifindex; - NMPlatform *platform; - - ifindex = nm_device_get_ip_ifindex (self); - g_return_val_if_fail (ifindex > 0, NULL); - - platform = nm_device_get_platform (self); - - if (priv->ipv6ll_has) { - dad6_add_pending_address (self, - platform, - ifindex, - &priv->ipv6ll_addr, - &dad6_config); - } - - /* We are interested only in addresses that we have explicitly configured, - * not in externally added ones. - */ - for (i = 0; i < G_N_ELEMENTS (confs); i++) { - if (!confs[i]) - continue; - - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, confs[i], &addr) { - dad6_add_pending_address (self, - platform, - ifindex, - &addr->address, - &dad6_config); - } - } - - return dad6_config; +dad6_get_pending_addresses(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMIP6Config * confs[] = {(NMIP6Config *) applied_config_get_current(&priv->ac_ip6_config), + (NMIP6Config *) applied_config_get_current(&priv->dhcp6.ip6_config), + priv->con_ip_config_6, + (NMIP6Config *) applied_config_get_current(&priv->dev2_ip_config_6)}; + const NMPlatformIP6Address *addr; + NMIP6Config * dad6_config = NULL; + NMDedupMultiIter ipconf_iter; + guint i; + int ifindex; + NMPlatform * platform; + + ifindex = nm_device_get_ip_ifindex(self); + g_return_val_if_fail(ifindex > 0, NULL); + + platform = nm_device_get_platform(self); + + if (priv->ipv6ll_has) { + dad6_add_pending_address(self, platform, ifindex, &priv->ipv6ll_addr, &dad6_config); + } + + /* We are interested only in addresses that we have explicitly configured, + * not in externally added ones. + */ + for (i = 0; i < G_N_ELEMENTS(confs); i++) { + if (!confs[i]) + continue; + + nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, confs[i], &addr) { + dad6_add_pending_address(self, platform, ifindex, &addr->address, &dad6_config); + } + } + + return dad6_config; } static void -activate_stage5_ip_config_result_6 (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActRequest *req; - const char *method; - int ip_ifindex; - int errsv; - - req = nm_device_get_act_request (self); - g_assert (req); - - /* Interface must be IFF_UP before IP config can be applied */ - ip_ifindex = nm_device_get_ip_ifindex (self); - g_return_if_fail (ip_ifindex); - - if (!nm_platform_link_is_up (nm_device_get_platform (self), ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) { - nm_platform_link_set_up (nm_device_get_platform (self), ip_ifindex, NULL); - if (!nm_platform_link_is_up (nm_device_get_platform (self), ip_ifindex)) - _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); - } - - if (ip_config_merge_and_apply (self, AF_INET6, TRUE)) { - if ( priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE - && priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { - if (applied_config_get_current (&priv->dhcp6.ip6_config)) { - /* If IPv6 wasn't the first IP to complete, and DHCP was used, - * then ensure dispatcher scripts get the DHCP lease information. - */ - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE, - self, - NULL, - NULL, NULL, NULL); - } else { - /* still waiting for first dhcp6 lease. */ - return; - } - } - - /* Start IPv6 forwarding if we need it */ - method = nm_device_get_effective_ip_config_method (self, AF_INET6); - if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - if (!nm_platform_sysctl_set (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv6/conf/all/forwarding"), "1")) { - errsv = errno; - _LOGE (LOGD_SHARING, "share: error enabling IPv6 forwarding: (%d) %s", errsv, nm_strerror_native (errsv)); - nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); - } - } - - /* Check if we have to wait for DAD */ - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF && !priv->dad6_ip6_config) { - if (!priv->carrier && priv->ignore_carrier && get_ip_config_may_fail (self, AF_INET6)) - _LOGI (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: carrier missing and ignored, not delaying activation"); - else - priv->dad6_ip6_config = dad6_get_pending_addresses (self); - - if (priv->dad6_ip6_config) { - _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: awaiting termination"); - } else { - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - } - } - } else { - _LOGW (LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed"); - nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - } +activate_stage5_ip_config_result_6(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMActRequest * req; + const char * method; + int ip_ifindex; + int errsv; + + req = nm_device_get_act_request(self); + g_assert(req); + + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex(self); + g_return_if_fail(ip_ifindex); + + if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex) + && !nm_device_sys_iface_state_is_external_or_assume(self)) { + nm_platform_link_set_up(nm_device_get_platform(self), ip_ifindex, NULL); + if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex)) + _LOGW(LOGD_DEVICE, + "interface %s not up for IP configuration", + nm_device_get_ip_iface(self)); + } + + if (ip_config_merge_and_apply(self, AF_INET6, TRUE)) { + if (priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE + && priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF) { + if (applied_config_get_current(&priv->dhcp6.ip6_config)) { + /* If IPv6 wasn't the first IP to complete, and DHCP was used, + * then ensure dispatcher scripts get the DHCP lease information. + */ + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE, + self, + NULL, + NULL, + NULL, + NULL); + } else { + /* still waiting for first dhcp6 lease. */ + return; + } + } + + /* Start IPv6 forwarding if we need it */ + method = nm_device_get_effective_ip_config_method(self, AF_INET6); + if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + if (!nm_platform_sysctl_set( + nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv6/conf/all/forwarding"), + "1")) { + errsv = errno; + _LOGE(LOGD_SHARING, + "share: error enabling IPv6 forwarding: (%d) %s", + errsv, + nm_strerror_native(errsv)); + nm_device_ip_method_failed(self, + AF_INET6, + NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + } + } + + /* Check if we have to wait for DAD */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF && !priv->dad6_ip6_config) { + if (!priv->carrier && priv->ignore_carrier && get_ip_config_may_fail(self, AF_INET6)) + _LOGI(LOGD_DEVICE | LOGD_IP6, + "IPv6 DAD: carrier missing and ignored, not delaying activation"); + else + priv->dad6_ip6_config = dad6_get_pending_addresses(self); + + if (priv->dad6_ip6_config) { + _LOGD(LOGD_DEVICE | LOGD_IP6, "IPv6 DAD: awaiting termination"); + } else { + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + } + } + } else { + _LOGW(LOGD_DEVICE | LOGD_IP6, "Activation: Stage 5 of 5 (IPv6 Commit) failed"); + nm_device_ip_method_failed(self, AF_INET6, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + } } /*****************************************************************************/ static void -act_request_set (NMDevice *self, NMActRequest *act_request) -{ - NMDevicePrivate *priv; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (!act_request || NM_IS_ACT_REQUEST (act_request)); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if ( !priv->act_request.visible - && priv->act_request.obj == act_request) - return; - - /* always clear the public flag. The few callers that set a new @act_request - * don't want that the property is public yet. */ - nm_dbus_track_obj_path_set (&priv->act_request, - act_request, - FALSE); - - if (act_request) { - switch (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request))) { - case NM_ACTIVATION_TYPE_EXTERNAL: - break; - case NM_ACTIVATION_TYPE_ASSUME: - if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL) - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_ASSUME); - break; - case NM_ACTIVATION_TYPE_MANAGED: - if (NM_IN_SET_TYPED (NMDeviceSysIfaceState, - priv->sys_iface_state, - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME)) - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); - break; - } - } -} - -static void -dnsmasq_cleanup (NMDevice *self) +act_request_set(NMDevice *self, NMActRequest *act_request) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(!act_request || NM_IS_ACT_REQUEST(act_request)); - if (!priv->dnsmasq_manager) - return; + priv = NM_DEVICE_GET_PRIVATE(self); - nm_clear_g_signal_handler (priv->dnsmasq_manager, &priv->dnsmasq_state_id); + if (!priv->act_request.visible && priv->act_request.obj == act_request) + return; - nm_dnsmasq_manager_stop (priv->dnsmasq_manager); - g_object_unref (priv->dnsmasq_manager); - priv->dnsmasq_manager = NULL; + /* always clear the public flag. The few callers that set a new @act_request + * don't want that the property is public yet. */ + nm_dbus_track_obj_path_set(&priv->act_request, act_request, FALSE); + + if (act_request) { + switch (nm_active_connection_get_activation_type(NM_ACTIVE_CONNECTION(act_request))) { + case NM_ACTIVATION_TYPE_EXTERNAL: + break; + case NM_ACTIVATION_TYPE_ASSUME: + if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL) + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_ASSUME); + break; + case NM_ACTIVATION_TYPE_MANAGED: + if (NM_IN_SET_TYPED(NMDeviceSysIfaceState, + priv->sys_iface_state, + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME)) + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); + break; + } + } } static void -_update_ip4_address (NMDevice *self) +dnsmasq_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformIP4Address *address; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + if (!priv->dnsmasq_manager) + return; - g_return_if_fail (NM_IS_DEVICE (self)); + nm_clear_g_signal_handler(priv->dnsmasq_manager, &priv->dnsmasq_state_id); - if ( priv->ip_config_4 - && ip_config_valid (priv->state) - && (address = nm_ip4_config_get_first_address (priv->ip_config_4))) { - if (address->address != priv->ip4_address) { - priv->ip4_address = address->address; - _notify (self, PROP_IP4_ADDRESS); - } - } + nm_dnsmasq_manager_stop(priv->dnsmasq_manager); + g_object_unref(priv->dnsmasq_manager); + priv->dnsmasq_manager = NULL; } gboolean -nm_device_is_nm_owned (NMDevice *self) +nm_device_is_nm_owned(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->nm_owned; + return NM_DEVICE_GET_PRIVATE(self)->nm_owned; } /* @@ -11918,402 +12130,407 @@ nm_device_is_nm_owned (NMDevice *self) * of the device. */ static gboolean -delete_on_deactivate_link_delete (gpointer user_data) +delete_on_deactivate_link_delete(gpointer user_data) { - DeleteOnDeactivateData *data = user_data; - NMDevice *self = data->device; + DeleteOnDeactivateData *data = user_data; + NMDevice * self = data->device; - _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); + _LOGD(LOGD_DEVICE, + "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", + data->ifindex, + data->idle_add_id); - if (data->device) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device); - gs_free_error GError *error = NULL; + if (data->device) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(data->device); + gs_free_error GError *error = NULL; - g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device); - priv->delete_on_deactivate_data = NULL; + g_object_remove_weak_pointer(G_OBJECT(data->device), (void **) &data->device); + priv->delete_on_deactivate_data = NULL; - if (!nm_device_unrealize (data->device, TRUE, &error)) - _LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message); - } else if (data->ifindex > 0) - nm_platform_link_delete (nm_device_get_platform (self), data->ifindex); + if (!nm_device_unrealize(data->device, TRUE, &error)) + _LOGD(LOGD_DEVICE, + "delete_on_deactivate: unrealizing %d failed (%s)", + data->ifindex, + error->message); + } else if (data->ifindex > 0) + nm_platform_link_delete(nm_device_get_platform(self), data->ifindex); - g_free (data); - return FALSE; + nm_device_emit_recheck_auto_activate(self); + + g_free(data); + return FALSE; } static void -delete_on_deactivate_unschedule (NMDevice *self) +delete_on_deactivate_unschedule(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->delete_on_deactivate_data) { - DeleteOnDeactivateData *data = priv->delete_on_deactivate_data; + if (priv->delete_on_deactivate_data) { + DeleteOnDeactivateData *data = priv->delete_on_deactivate_data; - priv->delete_on_deactivate_data = NULL; + priv->delete_on_deactivate_data = NULL; - g_source_remove (data->idle_add_id); - g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device); - _LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); - g_free (data); - } + g_source_remove(data->idle_add_id); + g_object_remove_weak_pointer(G_OBJECT(self), (void **) &data->device); + _LOGD(LOGD_DEVICE, + "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", + data->ifindex, + data->idle_add_id); + g_free(data); + } } static void -delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - DeleteOnDeactivateData *data; - - if (!priv->nm_owned) - return; - if (priv->queued_act_request) - return; - if (!nm_device_is_software (self) || !nm_device_is_real (self)) - return; - if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED) - return; - if (nm_device_get_state (self) == NM_DEVICE_STATE_UNAVAILABLE) - return; - delete_on_deactivate_unschedule (self); /* always cancel and reschedule */ - - data = g_new (DeleteOnDeactivateData, 1); - g_object_add_weak_pointer (G_OBJECT (self), (void **) &data->device); - data->device = self; - data->ifindex = ifindex; - data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data); - priv->delete_on_deactivate_data = data; - - _LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)", - ifindex, data->idle_add_id); +delete_on_deactivate_check_and_schedule(NMDevice *self, int ifindex) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + DeleteOnDeactivateData *data; + + if (!priv->nm_owned) + return; + if (priv->queued_act_request) + return; + if (!nm_device_is_software(self) || !nm_device_is_real(self)) + return; + if (nm_device_get_state(self) == NM_DEVICE_STATE_UNMANAGED) + return; + if (nm_device_get_state(self) == NM_DEVICE_STATE_UNAVAILABLE) + return; + delete_on_deactivate_unschedule(self); /* always cancel and reschedule */ + + data = g_new(DeleteOnDeactivateData, 1); + g_object_add_weak_pointer(G_OBJECT(self), (void **) &data->device); + data->device = self; + data->ifindex = ifindex; + data->idle_add_id = g_idle_add(delete_on_deactivate_link_delete, data); + priv->delete_on_deactivate_data = data; + + _LOGD(LOGD_DEVICE, + "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)", + ifindex, + data->idle_add_id); } static void -_cleanup_ip_pre (NMDevice *self, int addr_family, CleanupType cleanup_type) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - - _set_ip_state (self, addr_family, NM_DEVICE_IP_STATE_NONE); - - if (nm_clear_g_source (&priv->queued_ip_config_id_x[IS_IPv4])) { - _LOGD (LOGD_DEVICE, "clearing queued IP%c config change", - nm_utils_addr_family_to_char (addr_family)); - } - - if (IS_IPv4) { - dhcp4_cleanup (self, cleanup_type, FALSE); - arp_cleanup (self); - dnsmasq_cleanup (self); - ipv4ll_cleanup (self); - g_slist_free_full (priv->acd.dad_list, (GDestroyNotify) nm_acd_manager_free); - priv->acd.dad_list = NULL; - } else { - g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); - priv->dad6_failed_addrs = NULL; - g_clear_object (&priv->dad6_ip6_config); - dhcp6_cleanup (self, cleanup_type, FALSE); - nm_clear_g_source (&priv->linklocal6_timeout_id); - addrconf6_cleanup (self); - } +_cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + + _set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_NONE); + + if (nm_clear_g_source(&priv->queued_ip_config_id_x[IS_IPv4])) { + _LOGD(LOGD_DEVICE, + "clearing queued IP%c config change", + nm_utils_addr_family_to_char(addr_family)); + } + + if (IS_IPv4) { + dhcp4_cleanup(self, cleanup_type, FALSE); + arp_cleanup(self); + dnsmasq_cleanup(self); + ipv4ll_cleanup(self); + g_slist_free_full(priv->acd.dad_list, (GDestroyNotify) nm_acd_manager_free); + priv->acd.dad_list = NULL; + } else { + g_slist_free_full(priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + priv->dad6_failed_addrs = NULL; + g_clear_object(&priv->dad6_ip6_config); + dhcp6_cleanup(self, cleanup_type, FALSE); + nm_clear_g_source(&priv->linklocal6_timeout_id); + addrconf6_cleanup(self); + } } gboolean -_nm_device_hash_check_invalid_keys (GHashTable *hash, - const char *setting_name, - GError **error, - const char *const*whitelist) +_nm_device_hash_check_invalid_keys(GHashTable * hash, + const char * setting_name, + GError ** error, + const char *const *whitelist) { - guint found_whitelisted_keys = 0; - guint i; + guint found_whitelisted_keys = 0; + guint i; - nm_assert (hash && g_hash_table_size (hash) > 0); - nm_assert (whitelist && whitelist[0]); + nm_assert(hash && g_hash_table_size(hash) > 0); + nm_assert(whitelist && whitelist[0]); #if NM_MORE_ASSERTS > 10 - /* Require whitelist to only contain unique keys. */ - { - gs_unref_hashtable GHashTable *check_dups = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, NULL); - - for (i = 0; whitelist[i]; i++) { - if (!g_hash_table_add (check_dups, (char *) whitelist[i])) - nm_assert (FALSE); - } - nm_assert (g_hash_table_size (check_dups) > 0); - } + /* Require whitelist to only contain unique keys. */ + { + gs_unref_hashtable GHashTable *check_dups = + g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, NULL); + + for (i = 0; whitelist[i]; i++) { + if (!g_hash_table_add(check_dups, (char *) whitelist[i])) + nm_assert(FALSE); + } + nm_assert(g_hash_table_size(check_dups) > 0); + } #endif - for (i = 0; whitelist[i]; i++) { - if (g_hash_table_contains (hash, whitelist[i])) - found_whitelisted_keys++; - } - - if (found_whitelisted_keys == g_hash_table_size (hash)) { - /* Good, there are only whitelisted keys in the hash. */ - return TRUE; - } - - if (error) { - GHashTableIter iter; - const char *k = NULL; - const char *first_invalid_key = NULL; - - g_hash_table_iter_init (&iter, hash); - while (g_hash_table_iter_next (&iter, (gpointer *) &k, NULL)) { - if (nm_utils_strv_find_first ((char **) whitelist, -1, k) < 0) { - first_invalid_key = k; - break; - } - } - if (setting_name) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Can't reapply changes to '%s.%s' setting", - setting_name, - first_invalid_key); - } else { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Can't reapply any changes to '%s' setting", - first_invalid_key); - } - g_return_val_if_fail (first_invalid_key, FALSE); - } - - return FALSE; + for (i = 0; whitelist[i]; i++) { + if (g_hash_table_contains(hash, whitelist[i])) + found_whitelisted_keys++; + } + + if (found_whitelisted_keys == g_hash_table_size(hash)) { + /* Good, there are only whitelisted keys in the hash. */ + return TRUE; + } + + if (error) { + GHashTableIter iter; + const char * k = NULL; + const char * first_invalid_key = NULL; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &k, NULL)) { + if (nm_utils_strv_find_first((char **) whitelist, -1, k) < 0) { + first_invalid_key = k; + break; + } + } + if (setting_name) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply changes to '%s.%s' setting", + setting_name, + first_invalid_key); + } else { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply any changes to '%s' setting", + first_invalid_key); + } + g_return_val_if_fail(first_invalid_key, FALSE); + } + + return FALSE; } void -nm_device_reactivate_ip4_config (NMDevice *self, - NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new) -{ - NMDevicePrivate *priv; - const char *method_old, *method_new; - - g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->ip_state_4 != NM_DEVICE_IP_STATE_NONE) { - g_clear_object (&priv->con_ip_config_4); - g_clear_object (&priv->ext_ip_config_4); - g_clear_object (&priv->dev_ip_config_4.current); - g_clear_object (&priv->dev2_ip_config_4.current); - priv->con_ip_config_4 = nm_device_ip4_config_new (self); - nm_ip4_config_merge_setting (priv->con_ip_config_4, - s_ip4_new, - _get_mdns (self), - _get_llmnr (self), - nm_device_get_route_table (self, AF_INET), - nm_device_get_route_metric (self, AF_INET)); - - method_old = s_ip4_old - ? nm_setting_ip_config_get_method (s_ip4_old) - : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - method_new = s_ip4_new - ? nm_setting_ip_config_get_method (s_ip4_new) - : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - - if (!nm_streq0 (method_old, method_new)) { - _cleanup_ip_pre (self, AF_INET, CLEANUP_TYPE_DECONFIGURE); - _set_ip_state (self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - if (!nm_device_activate_stage3_ip4_start (self)) - _LOGW (LOGD_IP4, "Failed to apply IPv4 configuration"); - return; - } - - if (s_ip4_old && s_ip4_new) { - gint64 metric_old, metric_new; - - /* For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is - * set at activation/renewal time using the value from static - * configuration. To support runtime change we need to update the - * dynamic configuration in place and tell the DHCP client the new - * value to use for future renewals. - */ - metric_old = nm_setting_ip_config_get_route_metric (s_ip4_old); - metric_new = nm_setting_ip_config_get_route_metric (s_ip4_new); - - if (metric_old != metric_new) { - if (priv->dev_ip_config_4.orig) { - nm_ip4_config_update_routes_metric ((NMIP4Config *) priv->dev_ip_config_4.orig, - nm_device_get_route_metric (self, AF_INET)); - } - if (priv->dev2_ip_config_4.orig) { - nm_ip4_config_update_routes_metric ((NMIP4Config *) priv->dev2_ip_config_4.orig, - nm_device_get_route_metric (self, AF_INET)); - } - if (priv->dhcp_data_4.client) { - nm_dhcp_client_set_route_metric (priv->dhcp_data_4.client, - nm_device_get_route_metric (self, AF_INET)); - } - } - } - - if ( nm_device_get_ip_ifindex (self) > 0 - && !ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "Failed to reapply IPv4 configuration"); - } +nm_device_reactivate_ip4_config(NMDevice * self, + NMSettingIPConfig *s_ip4_old, + NMSettingIPConfig *s_ip4_new) +{ + NMDevicePrivate *priv; + const char * method_old, *method_new; + + g_return_if_fail(NM_IS_DEVICE(self)); + priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->ip_state_4 != NM_DEVICE_IP_STATE_NONE) { + g_clear_object(&priv->con_ip_config_4); + g_clear_object(&priv->ext_ip_config_4); + g_clear_object(&priv->dev_ip_config_4.current); + g_clear_object(&priv->dev2_ip_config_4.current); + priv->con_ip_config_4 = nm_device_ip4_config_new(self); + nm_ip4_config_merge_setting(priv->con_ip_config_4, + s_ip4_new, + _prop_get_connection_mdns(self), + _prop_get_connection_llmnr(self), + nm_device_get_route_table(self, AF_INET), + nm_device_get_route_metric(self, AF_INET)); + + method_old = s_ip4_old ? nm_setting_ip_config_get_method(s_ip4_old) + : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + method_new = s_ip4_new ? nm_setting_ip_config_get_method(s_ip4_new) + : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + + if (!nm_streq0(method_old, method_new)) { + _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_DECONFIGURE); + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); + if (!nm_device_activate_stage3_ip4_start(self)) + _LOGW(LOGD_IP4, "Failed to apply IPv4 configuration"); + return; + } + + if (s_ip4_old && s_ip4_new) { + gint64 metric_old, metric_new; + + /* For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is + * set at activation/renewal time using the value from static + * configuration. To support runtime change we need to update the + * dynamic configuration in place and tell the DHCP client the new + * value to use for future renewals. + */ + metric_old = nm_setting_ip_config_get_route_metric(s_ip4_old); + metric_new = nm_setting_ip_config_get_route_metric(s_ip4_new); + + if (metric_old != metric_new) { + if (priv->dev_ip_config_4.orig) { + nm_ip4_config_update_routes_metric((NMIP4Config *) priv->dev_ip_config_4.orig, + nm_device_get_route_metric(self, AF_INET)); + } + if (priv->dev2_ip_config_4.orig) { + nm_ip4_config_update_routes_metric((NMIP4Config *) priv->dev2_ip_config_4.orig, + nm_device_get_route_metric(self, AF_INET)); + } + if (priv->dhcp_data_4.client) { + nm_dhcp_client_set_route_metric(priv->dhcp_data_4.client, + nm_device_get_route_metric(self, AF_INET)); + } + } + } + + if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, AF_INET, TRUE)) + _LOGW(LOGD_IP4, "Failed to reapply IPv4 configuration"); + } } void -nm_device_reactivate_ip6_config (NMDevice *self, - NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new) -{ - NMDevicePrivate *priv; - const char *method_old, *method_new; - - g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->ip_state_6 != NM_DEVICE_IP_STATE_NONE) { - g_clear_object (&priv->con_ip_config_6); - g_clear_object (&priv->ext_ip_config_6); - g_clear_object (&priv->ac_ip6_config.current); - g_clear_object (&priv->dhcp6.ip6_config.current); - g_clear_object (&priv->dev2_ip_config_6.current); - if ( priv->ipv6ll_handle - && !IN6_IS_ADDR_UNSPECIFIED (&priv->ipv6ll_addr)) - priv->ipv6ll_has = TRUE; - priv->con_ip_config_6 = nm_device_ip6_config_new (self); - nm_ip6_config_merge_setting (priv->con_ip_config_6, - s_ip6_new, - nm_device_get_route_table (self, AF_INET6), - nm_device_get_route_metric (self, AF_INET6)); - - method_old = s_ip6_old - ? nm_setting_ip_config_get_method (s_ip6_old) - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - method_new = s_ip6_new - ? nm_setting_ip_config_get_method (s_ip6_new) - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - - if (!nm_streq0 (method_old, method_new)) { - _cleanup_ip_pre (self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); - _set_ip_state (self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - if (!nm_device_activate_stage3_ip6_start (self)) - _LOGW (LOGD_IP6, "Failed to apply IPv6 configuration"); - return; - } - - if (s_ip6_old && s_ip6_new) { - gint64 metric_old, metric_new; - - /* See comment in nm_device_reactivate_ip4_config() */ - metric_old = nm_setting_ip_config_get_route_metric (s_ip6_old); - metric_new = nm_setting_ip_config_get_route_metric (s_ip6_new); - - if (metric_old != metric_new) { - if (priv->ac_ip6_config.orig) { - nm_ip6_config_update_routes_metric ((NMIP6Config *) priv->ac_ip6_config.orig, - nm_device_get_route_metric (self, AF_INET6)); - } - if (priv->dhcp6.ip6_config.orig) { - nm_ip6_config_update_routes_metric ((NMIP6Config *) priv->dhcp6.ip6_config.orig, - nm_device_get_route_metric (self, AF_INET6)); - } - if (priv->dev2_ip_config_6.orig) { - nm_ip6_config_update_routes_metric ((NMIP6Config *) priv->dev2_ip_config_6.orig, - nm_device_get_route_metric (self, AF_INET6)); - } - if (priv->dhcp_data_6.client) { - nm_dhcp_client_set_route_metric (priv->dhcp_data_6.client, - nm_device_get_route_metric (self, AF_INET6)); - } - } - } - - if ( nm_device_get_ip_ifindex (self) > 0 - && !ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP4, "Failed to reapply IPv6 configuration"); - } +nm_device_reactivate_ip6_config(NMDevice * self, + NMSettingIPConfig *s_ip6_old, + NMSettingIPConfig *s_ip6_new) +{ + NMDevicePrivate *priv; + const char * method_old, *method_new; + + g_return_if_fail(NM_IS_DEVICE(self)); + priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->ip_state_6 != NM_DEVICE_IP_STATE_NONE) { + g_clear_object(&priv->con_ip_config_6); + g_clear_object(&priv->ext_ip_config_6); + g_clear_object(&priv->ac_ip6_config.current); + g_clear_object(&priv->dhcp6.ip6_config.current); + g_clear_object(&priv->dev2_ip_config_6.current); + if (priv->ipv6ll_handle && !IN6_IS_ADDR_UNSPECIFIED(&priv->ipv6ll_addr)) + priv->ipv6ll_has = TRUE; + priv->con_ip_config_6 = nm_device_ip6_config_new(self); + nm_ip6_config_merge_setting(priv->con_ip_config_6, + s_ip6_new, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); + + method_old = s_ip6_old ? nm_setting_ip_config_get_method(s_ip6_old) + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + method_new = s_ip6_new ? nm_setting_ip_config_get_method(s_ip6_new) + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + + if (!nm_streq0(method_old, method_new)) { + _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); + if (!nm_device_activate_stage3_ip6_start(self)) + _LOGW(LOGD_IP6, "Failed to apply IPv6 configuration"); + return; + } + + if (s_ip6_old && s_ip6_new) { + gint64 metric_old, metric_new; + + /* See comment in nm_device_reactivate_ip4_config() */ + metric_old = nm_setting_ip_config_get_route_metric(s_ip6_old); + metric_new = nm_setting_ip_config_get_route_metric(s_ip6_new); + + if (metric_old != metric_new) { + if (priv->ac_ip6_config.orig) { + nm_ip6_config_update_routes_metric((NMIP6Config *) priv->ac_ip6_config.orig, + nm_device_get_route_metric(self, AF_INET6)); + } + if (priv->dhcp6.ip6_config.orig) { + nm_ip6_config_update_routes_metric((NMIP6Config *) priv->dhcp6.ip6_config.orig, + nm_device_get_route_metric(self, AF_INET6)); + } + if (priv->dev2_ip_config_6.orig) { + nm_ip6_config_update_routes_metric((NMIP6Config *) priv->dev2_ip_config_6.orig, + nm_device_get_route_metric(self, AF_INET6)); + } + if (priv->dhcp_data_6.client) { + nm_dhcp_client_set_route_metric(priv->dhcp_data_6.client, + nm_device_get_route_metric(self, AF_INET6)); + } + } + } + + if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP4, "Failed to reapply IPv6 configuration"); + } } static void -_pacrunner_manager_add (NMDevice *self) +_pacrunner_manager_add(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id); + nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id); - priv->pacrunner_conf_id = nm_pacrunner_manager_add (nm_pacrunner_manager_get (), - priv->proxy_config, - nm_device_get_ip_iface (self), - NULL, - NULL); + priv->pacrunner_conf_id = nm_pacrunner_manager_add(nm_pacrunner_manager_get(), + priv->proxy_config, + nm_device_get_ip_iface(self), + NULL, + NULL); } static void -reactivate_proxy_config (NMDevice *self) +reactivate_proxy_config(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->pacrunner_conf_id) - return; - nm_device_set_proxy_config (self, priv->dhcp4.pac_url); - _pacrunner_manager_add (self); + if (!priv->pacrunner_conf_id) + return; + nm_device_set_proxy_config(self, priv->dhcp4.pac_url); + _pacrunner_manager_add(self); } static gboolean -can_reapply_change (NMDevice *self, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) -{ - if (nm_streq (setting_name, NM_SETTING_CONNECTION_SETTING_NAME)) { - /* Whitelist allowed properties from "connection" setting which are - * allowed to differ. - * - * This includes UUID, there is no principal problem with reapplying a - * connection and changing its UUID. In fact, disallowing it makes it - * cumbersome for the user to reapply any connection but the original - * settings-connection. */ - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_CONNECTION_SETTING_NAME, - error, - NM_SETTING_CONNECTION_ID, - NM_SETTING_CONNECTION_UUID, - NM_SETTING_CONNECTION_STABLE_ID, - NM_SETTING_CONNECTION_AUTOCONNECT, - NM_SETTING_CONNECTION_ZONE, - NM_SETTING_CONNECTION_METERED, - NM_SETTING_CONNECTION_LLDP, - NM_SETTING_CONNECTION_MDNS, - NM_SETTING_CONNECTION_LLMNR); - } else if (NM_IN_STRSET (setting_name, - NM_SETTING_USER_SETTING_NAME, - NM_SETTING_PROXY_SETTING_NAME, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_SETTING_NAME)) { - return TRUE; - } else if ( nm_streq (setting_name, NM_SETTING_WIRED_SETTING_NAME) - && NM_IN_SET (NM_DEVICE_GET_CLASS (self)->get_configured_mtu, - nm_device_get_configured_mtu_wired_parent, - nm_device_get_configured_mtu_for_wired)) { - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_WIRED_SETTING_NAME, - error, - NM_SETTING_WIRED_MTU); - } else { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Can't reapply any changes to '%s' setting", - setting_name); - return FALSE; - } +can_reapply_change(NMDevice * self, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) +{ + if (nm_streq(setting_name, NM_SETTING_CONNECTION_SETTING_NAME)) { + /* Whitelist allowed properties from "connection" setting which are + * allowed to differ. + * + * This includes UUID, there is no principal problem with reapplying a + * connection and changing its UUID. In fact, disallowing it makes it + * cumbersome for the user to reapply any connection but the original + * settings-connection. */ + return nm_device_hash_check_invalid_keys(diffs, + NM_SETTING_CONNECTION_SETTING_NAME, + error, + NM_SETTING_CONNECTION_ID, + NM_SETTING_CONNECTION_UUID, + NM_SETTING_CONNECTION_STABLE_ID, + NM_SETTING_CONNECTION_AUTOCONNECT, + NM_SETTING_CONNECTION_ZONE, + NM_SETTING_CONNECTION_METERED, + NM_SETTING_CONNECTION_LLDP, + NM_SETTING_CONNECTION_MDNS, + NM_SETTING_CONNECTION_LLMNR); + } else if (NM_IN_STRSET(setting_name, + NM_SETTING_USER_SETTING_NAME, + NM_SETTING_PROXY_SETTING_NAME, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME)) { + return TRUE; + } else if (nm_streq(setting_name, NM_SETTING_WIRED_SETTING_NAME) + && NM_IN_SET(NM_DEVICE_GET_CLASS(self)->get_configured_mtu, + nm_device_get_configured_mtu_wired_parent, + nm_device_get_configured_mtu_for_wired)) { + return nm_device_hash_check_invalid_keys(diffs, + NM_SETTING_WIRED_SETTING_NAME, + error, + NM_SETTING_WIRED_MTU); + } else { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Can't reapply any changes to '%s' setting", + setting_name); + return FALSE; + } } static void -reapply_connection (NMDevice *self, NMConnection *con_old, NMConnection *con_new) -{ -} +reapply_connection(NMDevice *self, NMConnection *con_old, NMConnection *con_new) +{} /* check_and_reapply_connection: * @connection: the new connection settings to be applied or %NULL to reapply @@ -12329,823 +12546,834 @@ reapply_connection (NMDevice *self, NMConnection *con_old, NMConnection *con_new * Return: %FALSE if the new configuration can not be reapplied. */ static gboolean -check_and_reapply_connection (NMDevice *self, - NMConnection *connection, - guint64 version_id, - char **audit_args, - GError **error) -{ - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *applied = nm_device_get_applied_connection (self); - gs_unref_object NMConnection *applied_clone = NULL; - gs_unref_hashtable GHashTable *diffs = NULL; - NMConnection *con_old, *con_new; - NMSettingIPConfig *s_ip4_old, *s_ip4_new; - NMSettingIPConfig *s_ip6_old, *s_ip6_new; - GHashTableIter iter; - - if ( priv->state < NM_DEVICE_STATE_PREPARE - || priv->state > NM_DEVICE_STATE_ACTIVATED) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not activated"); - return FALSE; - } - - nm_connection_diff (connection, - applied, - NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP | - NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, - &diffs); - - if (audit_args) { - if (diffs && nm_audit_manager_audit_enabled (nm_audit_manager_get ())) - *audit_args = nm_utils_format_con_diff_for_audit (diffs); - else - *audit_args = NULL; - } - - /************************************************************************** - * check for unsupported changes and reject to reapply - *************************************************************************/ - if (diffs) { - char *setting_name; - GHashTable *setting_diff; - - g_hash_table_iter_init (&iter, diffs); - while (g_hash_table_iter_next (&iter, (gpointer *) &setting_name, (gpointer *) &setting_diff)) { - if (!klass->can_reapply_change (self, - setting_name, - nm_connection_get_setting_by_name (applied, setting_name), - nm_connection_get_setting_by_name (connection, setting_name), - setting_diff, - error)) - return FALSE; - } - } - - if ( version_id != 0 - && version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request.obj)) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_VERSION_ID_MISMATCH, - "Reapply failed because device changed in the meantime and the version-id mismatches"); - return FALSE; - } - - /************************************************************************** - * Update applied connection - *************************************************************************/ - - if (diffs) - nm_active_connection_version_id_bump ((NMActiveConnection *) priv->act_request.obj); - - _LOGD (LOGD_DEVICE, "reapply (version-id %llu%s)", - (unsigned long long) nm_active_connection_version_id_get (((NMActiveConnection *) priv->act_request.obj)), - diffs ? "" : " (unmodified)"); - - if (diffs) { - NMConnection *connection_clean = connection; - gs_unref_object NMConnection *connection_clean_free = NULL; - - { - NMSettingConnection *s_con_a, *s_con_n; - - /* we allow re-applying a connection with differing ID, UUID, STABLE_ID and AUTOCONNECT. - * This is for convenience but these values are not actually changeable. So, check - * if they changed, and if the did revert to the original values. */ - s_con_a = nm_connection_get_setting_connection (applied); - s_con_n = nm_connection_get_setting_connection (connection); - - if ( !nm_streq (nm_setting_connection_get_id (s_con_a), nm_setting_connection_get_id (s_con_n)) - || !nm_streq (nm_setting_connection_get_uuid (s_con_a), nm_setting_connection_get_uuid (s_con_n)) - || nm_setting_connection_get_autoconnect (s_con_a) != nm_setting_connection_get_autoconnect (s_con_n) - || !nm_streq0 (nm_setting_connection_get_stable_id (s_con_a), nm_setting_connection_get_stable_id (s_con_n))) { - connection_clean_free = nm_simple_connection_new_clone (connection); - connection_clean = connection_clean_free; - s_con_n = nm_connection_get_setting_connection (connection_clean); - g_object_set (s_con_n, - NM_SETTING_CONNECTION_ID, nm_setting_connection_get_id (s_con_a), - NM_SETTING_CONNECTION_UUID, nm_setting_connection_get_uuid (s_con_a), - NM_SETTING_CONNECTION_AUTOCONNECT, nm_setting_connection_get_autoconnect (s_con_a), - NM_SETTING_CONNECTION_STABLE_ID, nm_setting_connection_get_stable_id (s_con_a), - NULL); - } - } - - con_old = applied_clone = nm_simple_connection_new_clone (applied); - con_new = applied; - nm_connection_replace_settings_from_connection (applied, connection_clean); - nm_connection_clear_secrets (applied); - } else - con_old = con_new = applied; - - priv->v4_commit_first_time = TRUE; - priv->v6_commit_first_time = TRUE; - - priv->v4_route_table_initialized = FALSE; - priv->v6_route_table_initialized = FALSE; - - /************************************************************************** - * Reapply changes - * - * Note that reapply_connection() is called as very first. This is for example - * important for NMDeviceWireGuard, which implements coerce_route_table() - * and get_extra_rules(). - * That is because NMDeviceWireGuard caches settings, so during reapply that - * cache must be updated *first*. - *************************************************************************/ - klass->reapply_connection (self, con_old, con_new); - - if (priv->state >= NM_DEVICE_STATE_CONFIG) - lldp_init (self, FALSE); - - if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { - s_ip4_old = nm_connection_get_setting_ip4_config (con_old); - s_ip4_new = nm_connection_get_setting_ip4_config (con_new); - s_ip6_old = nm_connection_get_setting_ip6_config (con_old); - s_ip6_new = nm_connection_get_setting_ip6_config (con_new); - - /* Allow reapply of MTU */ - priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; - - nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new); - nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new); - - _routing_rules_sync (self, NM_TERNARY_TRUE); - - reactivate_proxy_config (self); - } - - if (priv->state >= NM_DEVICE_STATE_IP_CHECK) - nm_device_update_firewall_zone (self); - - if (priv->state >= NM_DEVICE_STATE_ACTIVATED) - nm_device_update_metered (self); - - return TRUE; +check_and_reapply_connection(NMDevice * self, + NMConnection *connection, + guint64 version_id, + char ** audit_args, + GError ** error) +{ + NMDeviceClass * klass = NM_DEVICE_GET_CLASS(self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * applied = nm_device_get_applied_connection(self); + gs_unref_object NMConnection *applied_clone = NULL; + gs_unref_hashtable GHashTable *diffs = NULL; + NMConnection * con_old, *con_new; + NMSettingIPConfig * s_ip4_old, *s_ip4_new; + NMSettingIPConfig * s_ip6_old, *s_ip6_new; + GHashTableIter iter; + + if (priv->state < NM_DEVICE_STATE_PREPARE || priv->state > NM_DEVICE_STATE_ACTIVATED) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not activated"); + return FALSE; + } + + nm_connection_diff(connection, + applied, + NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP + | NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, + &diffs); + + if (audit_args) { + if (diffs && nm_audit_manager_audit_enabled(nm_audit_manager_get())) + *audit_args = nm_utils_format_con_diff_for_audit(diffs); + else + *audit_args = NULL; + } + + /************************************************************************** + * check for unsupported changes and reject to reapply + *************************************************************************/ + if (diffs) { + char * setting_name; + GHashTable *setting_diff; + + g_hash_table_iter_init(&iter, diffs); + while ( + g_hash_table_iter_next(&iter, (gpointer *) &setting_name, (gpointer *) &setting_diff)) { + if (!klass->can_reapply_change( + self, + setting_name, + nm_connection_get_setting_by_name(applied, setting_name), + nm_connection_get_setting_by_name(connection, setting_name), + setting_diff, + error)) + return FALSE; + } + } + + if (version_id != 0 + && version_id + != nm_active_connection_version_id_get( + (NMActiveConnection *) priv->act_request.obj)) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_VERSION_ID_MISMATCH, + "Reapply failed because device changed in the meantime and the version-id mismatches"); + return FALSE; + } + + /************************************************************************** + * Update applied connection + *************************************************************************/ + + if (diffs) + nm_active_connection_version_id_bump((NMActiveConnection *) priv->act_request.obj); + + _LOGD(LOGD_DEVICE, + "reapply (version-id %llu%s)", + (unsigned long long) nm_active_connection_version_id_get( + ((NMActiveConnection *) priv->act_request.obj)), + diffs ? "" : " (unmodified)"); + + if (diffs) { + NMConnection * connection_clean = connection; + gs_unref_object NMConnection *connection_clean_free = NULL; + + { + NMSettingConnection *s_con_a, *s_con_n; + + /* we allow re-applying a connection with differing ID, UUID, STABLE_ID and AUTOCONNECT. + * This is for convenience but these values are not actually changeable. So, check + * if they changed, and if the did revert to the original values. */ + s_con_a = nm_connection_get_setting_connection(applied); + s_con_n = nm_connection_get_setting_connection(connection); + + if (!nm_streq(nm_setting_connection_get_id(s_con_a), + nm_setting_connection_get_id(s_con_n)) + || !nm_streq(nm_setting_connection_get_uuid(s_con_a), + nm_setting_connection_get_uuid(s_con_n)) + || nm_setting_connection_get_autoconnect(s_con_a) + != nm_setting_connection_get_autoconnect(s_con_n) + || !nm_streq0(nm_setting_connection_get_stable_id(s_con_a), + nm_setting_connection_get_stable_id(s_con_n))) { + connection_clean_free = nm_simple_connection_new_clone(connection); + connection_clean = connection_clean_free; + s_con_n = nm_connection_get_setting_connection(connection_clean); + g_object_set(s_con_n, + NM_SETTING_CONNECTION_ID, + nm_setting_connection_get_id(s_con_a), + NM_SETTING_CONNECTION_UUID, + nm_setting_connection_get_uuid(s_con_a), + NM_SETTING_CONNECTION_AUTOCONNECT, + nm_setting_connection_get_autoconnect(s_con_a), + NM_SETTING_CONNECTION_STABLE_ID, + nm_setting_connection_get_stable_id(s_con_a), + NULL); + } + } + + con_old = applied_clone = nm_simple_connection_new_clone(applied); + con_new = applied; + nm_connection_replace_settings_from_connection(applied, connection_clean); + nm_connection_clear_secrets(applied); + } else + con_old = con_new = applied; + + priv->v4_commit_first_time = TRUE; + priv->v6_commit_first_time = TRUE; + + priv->v4_route_table_initialized = FALSE; + priv->v6_route_table_initialized = FALSE; + + /************************************************************************** + * Reapply changes + * + * Note that reapply_connection() is called as very first. This is for example + * important for NMDeviceWireGuard, which implements coerce_route_table() + * and get_extra_rules(). + * That is because NMDeviceWireGuard caches settings, so during reapply that + * cache must be updated *first*. + *************************************************************************/ + klass->reapply_connection(self, con_old, con_new); + + if (priv->state >= NM_DEVICE_STATE_CONFIG) + lldp_init(self, FALSE); + + if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { + s_ip4_old = nm_connection_get_setting_ip4_config(con_old); + s_ip4_new = nm_connection_get_setting_ip4_config(con_new); + s_ip6_old = nm_connection_get_setting_ip6_config(con_old); + s_ip6_new = nm_connection_get_setting_ip6_config(con_new); + + /* Allow reapply of MTU */ + priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; + + nm_device_reactivate_ip4_config(self, s_ip4_old, s_ip4_new); + nm_device_reactivate_ip6_config(self, s_ip6_old, s_ip6_new); + + _routing_rules_sync(self, NM_TERNARY_TRUE); + + reactivate_proxy_config(self); + } + + if (priv->state >= NM_DEVICE_STATE_IP_CHECK) + nm_device_update_firewall_zone(self); + + if (priv->state >= NM_DEVICE_STATE_ACTIVATED) + nm_device_update_metered(self); + + return TRUE; } gboolean -nm_device_reapply (NMDevice *self, - NMConnection *connection, - GError **error) +nm_device_reapply(NMDevice *self, NMConnection *connection, GError **error) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return check_and_reapply_connection (self, - connection, - 0, - NULL, - error); + return check_and_reapply_connection(self, connection, 0, NULL, error); } typedef struct { - NMConnection *connection; - guint64 version_id; + NMConnection *connection; + guint64 version_id; } ReapplyData; static void -reapply_cb (NMDevice *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) -{ - ReapplyData *reapply_data = user_data; - guint64 version_id = 0; - gs_unref_object NMConnection *connection = NULL; - GError *local = NULL; - gs_free char *audit_args = NULL; - - if (reapply_data) { - connection = reapply_data->connection; - version_id = reapply_data->version_id; - g_slice_free (ReapplyData, reapply_data); - } - - if (error) { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, subject, error->message); - g_dbus_method_invocation_return_gerror (context, error); - return; - } - - if (nm_device_sys_iface_state_is_external (self)) - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); - - if (!check_and_reapply_connection (self, - connection ?: nm_device_get_settings_connection_get_connection (self), - version_id, - &audit_args, - &local)) { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, audit_args, subject, local->message); - g_dbus_method_invocation_take_error (context, local); - local = NULL; - } else { - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL); - g_dbus_method_invocation_return_value (context, NULL); - } +reapply_cb(NMDevice * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) +{ + ReapplyData * reapply_data = user_data; + guint64 version_id = 0; + gs_unref_object NMConnection *connection = NULL; + GError * local = NULL; + gs_free char * audit_args = NULL; + + if (reapply_data) { + connection = reapply_data->connection; + version_id = reapply_data->version_id; + g_slice_free(ReapplyData, reapply_data); + } + + if (error) { + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, + self, + FALSE, + NULL, + subject, + error->message); + g_dbus_method_invocation_return_gerror(context, error); + return; + } + + if (nm_device_sys_iface_state_is_external(self)) + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); + + if (!check_and_reapply_connection(self, + connection + ?: nm_device_get_settings_connection_get_connection(self), + version_id, + &audit_args, + &local)) { + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, + self, + FALSE, + audit_args, + subject, + local->message); + g_dbus_method_invocation_take_error(context, local); + local = NULL; + } else { + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL); + g_dbus_method_invocation_return_value(context, NULL); + } } static void -impl_device_reapply (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *dbus_connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMDevice *self = NM_DEVICE (obj); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *settings_connection; - NMConnection *connection = NULL; - GError *error = NULL; - ReapplyData *reapply_data; - gs_unref_variant GVariant *settings = NULL; - guint64 version_id; - guint32 flags; - - g_variant_get (parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &flags); - - /* No flags supported as of now. */ - if (flags != 0) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "Invalid flags specified"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - if ( priv->state < NM_DEVICE_STATE_PREPARE - || priv->state > NM_DEVICE_STATE_ACTIVATED) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not activated"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - - settings_connection = nm_device_get_settings_connection (self); - g_return_if_fail (settings_connection); - - if (settings && g_variant_n_children (settings)) { - /* New settings specified inline. */ - connection = _nm_simple_connection_new_from_dbus (settings, - NM_SETTING_PARSE_FLAGS_STRICT - | NM_SETTING_PARSE_FLAGS_NORMALIZE, - &error); - if (!connection) { - g_prefix_error (&error, "The settings specified are invalid: "); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); - g_dbus_method_invocation_take_error (invocation, error); - return; - } - nm_connection_clear_secrets (connection); - } - - if (connection || version_id) { - reapply_data = g_slice_new (ReapplyData); - reapply_data->connection = connection; - reapply_data->version_id = version_id; - } else - reapply_data = NULL; - - nm_device_auth_request (self, - invocation, - nm_device_get_applied_connection (self), - NM_AUTH_PERMISSION_NETWORK_CONTROL, - TRUE, - NULL, - reapply_cb, - reapply_data); +impl_device_reapply(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * dbus_connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMDevice * self = NM_DEVICE(obj); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingsConnection *settings_connection; + NMConnection * connection = NULL; + GError * error = NULL; + ReapplyData * reapply_data; + gs_unref_variant GVariant *settings = NULL; + guint64 version_id; + guint32 flags; + + g_variant_get(parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &flags); + + /* No flags supported as of now. */ + if (flags != 0) { + error = + g_error_new_literal(NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "Invalid flags specified"); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, + self, + FALSE, + NULL, + invocation, + error->message); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + if (priv->state < NM_DEVICE_STATE_PREPARE || priv->state > NM_DEVICE_STATE_ACTIVATED) { + error = g_error_new_literal(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not activated"); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, + self, + FALSE, + NULL, + invocation, + error->message); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + + settings_connection = nm_device_get_settings_connection(self); + g_return_if_fail(settings_connection); + + if (settings && g_variant_n_children(settings)) { + /* New settings specified inline. */ + connection = _nm_simple_connection_new_from_dbus(settings, + NM_SETTING_PARSE_FLAGS_STRICT + | NM_SETTING_PARSE_FLAGS_NORMALIZE, + &error); + if (!connection) { + g_prefix_error(&error, "The settings specified are invalid: "); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, + self, + FALSE, + NULL, + invocation, + error->message); + g_dbus_method_invocation_take_error(invocation, error); + return; + } + nm_connection_clear_secrets(connection); + } + + if (connection || version_id) { + reapply_data = g_slice_new(ReapplyData); + reapply_data->connection = connection; + reapply_data->version_id = version_id; + } else + reapply_data = NULL; + + nm_device_auth_request(self, + invocation, + nm_device_get_applied_connection(self), + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + NULL, + reapply_cb, + reapply_data); } /*****************************************************************************/ static void -get_applied_connection_cb (NMDevice *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data /* possibly dangling pointer */) -{ - NMDevicePrivate *priv; - NMConnection *applied_connection; - GVariant *settings; - - g_return_if_fail (NM_IS_DEVICE (self)); - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - return; - } - - priv = NM_DEVICE_GET_PRIVATE (self); - - applied_connection = nm_device_get_applied_connection (self); - - if (!applied_connection) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not activated"); - g_dbus_method_invocation_take_error (context, error); - return; - } - - if (applied_connection != user_data) { - /* The applied connection changed due to a race. Reauthenticate. */ - nm_device_auth_request (self, - context, - applied_connection, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - TRUE, - NULL, - get_applied_connection_cb, - applied_connection /* no need take a ref. We will not dereference this pointer. */); - return; - } - - settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); - if (!settings) - settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); - - g_dbus_method_invocation_return_value (context, - g_variant_new ("(@a{sa{sv}}t)", - settings, - nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request.obj))); -} - -static void -impl_device_get_applied_connection (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMDevice *self = NM_DEVICE (obj); - NMConnection *applied_connection; - guint32 flags; - - g_variant_get (parameters, "(u)", &flags); - - /* No flags supported as of now. */ - if (flags != 0) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "Invalid flags specified"); - return; - } - - applied_connection = nm_device_get_applied_connection (self); - if (!applied_connection) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not activated"); - return; - } - - nm_device_auth_request (self, - invocation, - applied_connection, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - TRUE, - NULL, - get_applied_connection_cb, - applied_connection /* no need take a ref. We will not dereference this pointer. */); +impl_device_get_applied_connection(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMDevice * self = NM_DEVICE(obj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + NMConnection * applied_connection; + guint32 flags; + GVariant * var_settings; + + g_variant_get(parameters, "(u)", &flags); + + /* No flags supported as of now. */ + if (flags != 0) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Invalid flags specified"); + return; + } + + applied_connection = nm_device_get_applied_connection(self); + if (!applied_connection) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not activated"); + return; + } + + if (!nm_auth_is_invocation_in_acl_set_error(applied_connection, + invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + NULL, + &error)) { + g_dbus_method_invocation_take_error(invocation, g_steal_pointer(&error)); + return; + } + + var_settings = nm_connection_to_dbus(applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + if (!var_settings) + var_settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + + g_dbus_method_invocation_return_value( + invocation, + g_variant_new( + "(@a{sa{sv}}t)", + var_settings, + nm_active_connection_version_id_get((NMActiveConnection *) priv->act_request.obj))); } /*****************************************************************************/ typedef struct { - gint64 timestamp_ms; - bool dirty; + gint64 timestamp_ms; + bool dirty; } IP6RoutesTemporaryNotAvailableData; static gboolean -_rt6_temporary_not_available_timeout (gpointer user_data) +_rt6_temporary_not_available_timeout(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->rt6_temporary_not_available_id = 0; - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); + priv->rt6_temporary_not_available_id = 0; + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean -_rt6_temporary_not_available_set (NMDevice *self, - GPtrArray *temporary_not_available) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - IP6RoutesTemporaryNotAvailableData *data; - GHashTableIter iter; - gint64 now_ms, oldest_ms; - const gint64 MAX_AGE_MS = 20000; - guint i; - gboolean success = TRUE; - - if ( !temporary_not_available - || !temporary_not_available->len) { - /* nothing outstanding. Clear tracking the routes. */ - nm_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); - nm_clear_g_source (&priv->rt6_temporary_not_available_id); - return success; - } - - if (priv->rt6_temporary_not_available) { - g_hash_table_iter_init (&iter, priv->rt6_temporary_not_available); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &data)) - data->dirty = TRUE; - } else { - priv->rt6_temporary_not_available = g_hash_table_new_full ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal, - (GDestroyNotify) nmp_object_unref, - nm_g_slice_free_fcn (IP6RoutesTemporaryNotAvailableData)); - } - - now_ms = nm_utils_get_monotonic_timestamp_msec (); - oldest_ms = now_ms; - - for (i = 0; i < temporary_not_available->len; i++) { - const NMPObject *o = temporary_not_available->pdata[i]; - - data = g_hash_table_lookup (priv->rt6_temporary_not_available, o); - if (data) { - if (!data->dirty) - continue; - data->dirty = FALSE; - nm_assert (data->timestamp_ms > 0 && data->timestamp_ms <= now_ms); - if (now_ms > data->timestamp_ms + MAX_AGE_MS) { - /* timeout. Could not add this address. */ - _LOGW (LOGD_DEVICE, "failure to add IPv6 route: %s", - nmp_object_to_string (o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); - success = FALSE; - } else - oldest_ms = MIN (data->timestamp_ms, oldest_ms); - continue; - } - - data = g_slice_new0 (IP6RoutesTemporaryNotAvailableData); - data->timestamp_ms = now_ms; - g_hash_table_insert (priv->rt6_temporary_not_available, (gpointer) nmp_object_ref (o), data); - } - - g_hash_table_iter_init (&iter, priv->rt6_temporary_not_available); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &data)) { - if (data->dirty) - g_hash_table_iter_remove (&iter); - } - - nm_clear_g_source (&priv->rt6_temporary_not_available_id); - priv->rt6_temporary_not_available_id = g_timeout_add (oldest_ms + MAX_AGE_MS - now_ms, - _rt6_temporary_not_available_timeout, - self); - - return success; +_rt6_temporary_not_available_set(NMDevice *self, GPtrArray *temporary_not_available) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + IP6RoutesTemporaryNotAvailableData *data; + GHashTableIter iter; + gint64 now_ms, oldest_ms; + const gint64 MAX_AGE_MS = 20000; + guint i; + gboolean success = TRUE; + + if (!temporary_not_available || !temporary_not_available->len) { + /* nothing outstanding. Clear tracking the routes. */ + nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref); + nm_clear_g_source(&priv->rt6_temporary_not_available_id); + return success; + } + + if (priv->rt6_temporary_not_available) { + g_hash_table_iter_init(&iter, priv->rt6_temporary_not_available); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &data)) + data->dirty = TRUE; + } else { + priv->rt6_temporary_not_available = + g_hash_table_new_full((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal, + (GDestroyNotify) nmp_object_unref, + nm_g_slice_free_fcn(IP6RoutesTemporaryNotAvailableData)); + } + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + oldest_ms = now_ms; + + for (i = 0; i < temporary_not_available->len; i++) { + const NMPObject *o = temporary_not_available->pdata[i]; + + data = g_hash_table_lookup(priv->rt6_temporary_not_available, o); + if (data) { + if (!data->dirty) + continue; + data->dirty = FALSE; + nm_assert(data->timestamp_ms > 0 && data->timestamp_ms <= now_ms); + if (now_ms > data->timestamp_ms + MAX_AGE_MS) { + /* timeout. Could not add this address. */ + _LOGW(LOGD_DEVICE, + "failure to add IPv6 route: %s", + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + success = FALSE; + } else + oldest_ms = MIN(data->timestamp_ms, oldest_ms); + continue; + } + + data = g_slice_new0(IP6RoutesTemporaryNotAvailableData); + data->timestamp_ms = now_ms; + g_hash_table_insert(priv->rt6_temporary_not_available, (gpointer) nmp_object_ref(o), data); + } + + g_hash_table_iter_init(&iter, priv->rt6_temporary_not_available); + while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &data)) { + if (data->dirty) + g_hash_table_iter_remove(&iter); + } + + nm_clear_g_source(&priv->rt6_temporary_not_available_id); + priv->rt6_temporary_not_available_id = + g_timeout_add(oldest_ms + MAX_AGE_MS - now_ms, _rt6_temporary_not_available_timeout, self); + + return success; } /*****************************************************************************/ static void -disconnect_cb (NMDevice *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GError *local = NULL; - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, error->message); - return; - } - - /* Authorized */ - if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) { - local = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not active"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, local->message); - g_dbus_method_invocation_take_error (context, local); - } else { - nm_device_autoconnect_blocked_set (self, NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT); - - nm_device_state_changed (self, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - g_dbus_method_invocation_return_value (context, NULL); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, NULL, subject, NULL); - } +disconnect_cb(NMDevice * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + GError * local = NULL; + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_DISCONNECT, + self, + FALSE, + NULL, + subject, + error->message); + return; + } + + /* Authorized */ + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) { + local = g_error_new_literal(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not active"); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_DISCONNECT, + self, + FALSE, + NULL, + subject, + local->message); + g_dbus_method_invocation_take_error(context, local); + } else { + nm_device_autoconnect_blocked_set(self, NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT); + + nm_device_state_changed(self, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + g_dbus_method_invocation_return_value(context, NULL); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_DISCONNECT, self, TRUE, NULL, subject, NULL); + } } static void -_clear_queued_act_request (NMDevicePrivate *priv, - NMActiveConnectionStateReason active_reason) +_clear_queued_act_request(NMDevicePrivate *priv, NMActiveConnectionStateReason active_reason) { - if (priv->queued_act_request) { - gs_unref_object NMActRequest *ac = NULL; + if (priv->queued_act_request) { + gs_unref_object NMActRequest *ac = NULL; - ac = g_steal_pointer (&priv->queued_act_request); - nm_active_connection_set_state_fail ((NMActiveConnection *) ac, - active_reason, - NULL); - } + ac = g_steal_pointer(&priv->queued_act_request); + nm_active_connection_set_state_fail((NMActiveConnection *) ac, active_reason, NULL); + } } static void -impl_device_disconnect (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *dbus_connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMDevice *self = NM_DEVICE (obj); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - - if (!priv->act_request.obj) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "This device is not active"); - return; - } - - connection = nm_device_get_applied_connection (self); - nm_assert (connection); - - nm_device_auth_request (self, - invocation, - connection, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - TRUE, - NULL, - disconnect_cb, - NULL); +impl_device_disconnect(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * dbus_connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMDevice * self = NM_DEVICE(obj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + + if (!priv->act_request.obj) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "This device is not active"); + return; + } + + connection = nm_device_get_applied_connection(self); + nm_assert(connection); + + nm_device_auth_request(self, + invocation, + connection, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + NULL, + disconnect_cb, + NULL); } static void -delete_cb (NMDevice *self, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) -{ - GError *local = NULL; - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, NULL, subject, error->message); - return; - } - - /* Authorized */ - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, NULL, subject, NULL); - if (nm_device_unrealize (self, TRUE, &local)) - g_dbus_method_invocation_return_value (context, NULL); - else - g_dbus_method_invocation_take_error (context, local); +delete_cb(NMDevice * self, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) +{ + GError *local = NULL; + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_DELETE, + self, + FALSE, + NULL, + subject, + error->message); + return; + } + + /* Authorized */ + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, NULL, subject, NULL); + if (nm_device_unrealize(self, TRUE, &local)) + g_dbus_method_invocation_return_value(context, NULL); + else + g_dbus_method_invocation_take_error(context, local); } static void -impl_device_delete (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - NMDevice *self = NM_DEVICE (obj); - - if ( !nm_device_is_software (self) - || !nm_device_is_real (self)) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_SOFTWARE, - "This device is not a software device or is not realized"); - return; - } - - nm_device_auth_request (self, - invocation, - NULL, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - TRUE, - NULL, - delete_cb, - NULL); +impl_device_delete(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) +{ + NMDevice *self = NM_DEVICE(obj); + + if (!nm_device_is_software(self) || !nm_device_is_real(self)) { + g_dbus_method_invocation_return_error_literal( + invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device or is not realized"); + return; + } + + nm_device_auth_request(self, + invocation, + NULL, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + NULL, + delete_cb, + NULL); } static void -_device_activate (NMDevice *self, NMActRequest *req) +_device_activate(NMDevice *self, NMActRequest *req) { - NMConnection *connection; + NMConnection *connection; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - nm_assert (nm_device_is_real (self)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + nm_assert(nm_device_is_real(self)); - /* Ensure the activation request is still valid; the master may have - * already failed in which case activation of this device should not proceed. - */ - if (nm_active_connection_get_state (NM_ACTIVE_CONNECTION (req)) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) - return; + /* Ensure the activation request is still valid; the master may have + * already failed in which case activation of this device should not proceed. + */ + if (nm_active_connection_get_state(NM_ACTIVE_CONNECTION(req)) + >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) + return; - if (!nm_device_get_managed (self, FALSE)) { - /* It's unclear why the device would be unmanaged at this point. - * Just to be sure, handle it and error out. */ - _LOGE (LOGD_DEVICE, "Activation: failed activating connection '%s' because device is still unmanaged", - nm_active_connection_get_settings_connection_id ((NMActiveConnection *) req)); - nm_active_connection_set_state_fail ((NMActiveConnection *) req, - NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, - NULL); - return; - } + if (!nm_device_get_managed(self, FALSE)) { + /* It's unclear why the device would be unmanaged at this point. + * Just to be sure, handle it and error out. */ + _LOGE(LOGD_DEVICE, + "Activation: failed activating connection '%s' because device is still unmanaged", + nm_active_connection_get_settings_connection_id((NMActiveConnection *) req)); + nm_active_connection_set_state_fail((NMActiveConnection *) req, + NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, + NULL); + return; + } - connection = nm_act_request_get_applied_connection (req); - nm_assert (connection); + connection = nm_act_request_get_applied_connection(req); + nm_assert(connection); - _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)", - nm_connection_get_id (connection), - nm_connection_get_uuid (connection)); + _LOGI(LOGD_DEVICE, + "Activation: starting connection '%s' (%s)", + nm_connection_get_id(connection), + nm_connection_get_uuid(connection)); - delete_on_deactivate_unschedule (self); + delete_on_deactivate_unschedule(self); - act_request_set (self, req); + act_request_set(self, req); - nm_device_activate_schedule_stage1_device_prepare (self, FALSE); + nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } static void -_carrier_wait_check_queued_act_request (NMDevice *self) +_carrier_wait_check_queued_act_request(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( !priv->queued_act_request - || !priv->queued_act_request_is_waiting_for_carrier) - return; + if (!priv->queued_act_request || !priv->queued_act_request_is_waiting_for_carrier) + return; - priv->queued_act_request_is_waiting_for_carrier = FALSE; - if (!priv->carrier) { - _LOGD (LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout"); - _clear_queued_act_request (priv, - NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); - } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { - gs_unref_object NMActRequest *queued_req = NULL; + priv->queued_act_request_is_waiting_for_carrier = FALSE; + if (!priv->carrier) { + _LOGD(LOGD_DEVICE, "Cancel queued activation request as we have no carrier after timeout"); + _clear_queued_act_request(priv, NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); + } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { + gs_unref_object NMActRequest *queued_req = NULL; - _LOGD (LOGD_DEVICE, "Activate queued activation request as we now have carrier"); - queued_req = g_steal_pointer (&priv->queued_act_request); - _device_activate (self, queued_req); - } + _LOGD(LOGD_DEVICE, "Activate queued activation request as we now have carrier"); + queued_req = g_steal_pointer(&priv->queued_act_request); + _device_activate(self, queued_req); + } } static gboolean -_carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - - /* If we have carrier or if we are not waiting for it, the activation - * request is not blocked waiting for carrier. */ - if (priv->carrier) - return FALSE; - if (priv->carrier_wait_id == 0) - return FALSE; - - connection = nm_act_request_get_applied_connection (req); - if (!connection_requires_carrier (connection)) - return FALSE; - - if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL, NULL)) { - /* We passed all @flags we have, and no @specific_object. - * This equals maximal availability, if a connection is not available - * in this case, it is not waiting for carrier. - * - * Actually, why are we even trying to activate it? Strange, but whatever - * the reason, don't wait for carrier. - */ - return FALSE; - } - - if (nm_device_check_connection_available (self, connection, - NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, - NULL, NULL)) { - /* The connection was available with flags ALL, and it is still available - * if we pretend not to wait for carrier. That means that the - * connection is available now, and does not wait for carrier. - * - * Since the flags increase the availability of a connection, when checking - * ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */ - return FALSE; - } - - /* The activation request must wait for carrier. */ - return TRUE; +_carrier_wait_check_act_request_must_queue(NMDevice *self, NMActRequest *req) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + + /* If we have carrier or if we are not waiting for it, the activation + * request is not blocked waiting for carrier. */ + if (priv->carrier) + return FALSE; + if (priv->carrier_wait_id == 0) + return FALSE; + + connection = nm_act_request_get_applied_connection(req); + if (!connection_requires_carrier(connection)) + return FALSE; + + if (!nm_device_check_connection_available(self, + connection, + NM_DEVICE_CHECK_CON_AVAILABLE_ALL, + NULL, + NULL)) { + /* We passed all @flags we have, and no @specific_object. + * This equals maximal availability, if a connection is not available + * in this case, it is not waiting for carrier. + * + * Actually, why are we even trying to activate it? Strange, but whatever + * the reason, don't wait for carrier. + */ + return FALSE; + } + + if (nm_device_check_connection_available( + self, + connection, + NM_DEVICE_CHECK_CON_AVAILABLE_ALL + & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, + NULL, + NULL)) { + /* The connection was available with flags ALL, and it is still available + * if we pretend not to wait for carrier. That means that the + * connection is available now, and does not wait for carrier. + * + * Since the flags increase the availability of a connection, when checking + * ALL&~WAITING_CARRIER, it means that we certainly would wait for carrier. */ + return FALSE; + } + + /* The activation request must wait for carrier. */ + return TRUE; } void -nm_device_disconnect_active_connection (NMActiveConnection *active, - NMDeviceStateReason device_reason, - NMActiveConnectionStateReason active_reason) -{ - NMDevice *self; - NMDevicePrivate *priv; - - g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); - - self = nm_active_connection_get_device (active); - if (!self) { - /* hm, no device? Just fail the active connection. */ - goto do_fail; - } - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (NM_ACTIVE_CONNECTION (priv->queued_act_request) == active) { - _clear_queued_act_request (priv, active_reason); - return; - } - - if (NM_ACTIVE_CONNECTION (priv->act_request.obj) == active) { - if (priv->state < NM_DEVICE_STATE_DEACTIVATING) { - nm_device_state_changed (self, - NM_DEVICE_STATE_DEACTIVATING, - device_reason); - } else { - /* @active is the current ac of @self, but it's going down already. - * Nothing to do. */ - } - return; - } - - /* the active connection references this device, but it's neither the - * queued_act_request nor the current act_request. Just set it to fail... */ +nm_device_disconnect_active_connection(NMActiveConnection * active, + NMDeviceStateReason device_reason, + NMActiveConnectionStateReason active_reason) +{ + NMDevice * self; + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_ACTIVE_CONNECTION(active)); + + self = nm_active_connection_get_device(active); + if (!self) { + /* hm, no device? Just fail the active connection. */ + goto do_fail; + } + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (NM_ACTIVE_CONNECTION(priv->queued_act_request) == active) { + _clear_queued_act_request(priv, active_reason); + return; + } + + if (NM_ACTIVE_CONNECTION(priv->act_request.obj) == active) { + if (priv->state < NM_DEVICE_STATE_DEACTIVATING) { + nm_device_state_changed(self, NM_DEVICE_STATE_DEACTIVATING, device_reason); + } else { + /* @active is the current ac of @self, but it's going down already. + * Nothing to do. */ + } + return; + } + + /* the active connection references this device, but it's neither the + * queued_act_request nor the current act_request. Just set it to fail... */ do_fail: - nm_active_connection_set_state_fail (active, - active_reason, - NULL); + nm_active_connection_set_state_fail(active, active_reason, NULL); } void -nm_device_queue_activation (NMDevice *self, NMActRequest *req) +nm_device_queue_activation(NMDevice *self, NMActRequest *req) { - NMDevicePrivate *priv; - gboolean must_queue; + NMDevicePrivate *priv; + gboolean must_queue; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); - nm_keep_alive_arm (nm_active_connection_get_keep_alive (NM_ACTIVE_CONNECTION (req))); + nm_keep_alive_arm(nm_active_connection_get_keep_alive(NM_ACTIVE_CONNECTION(req))); - if (nm_active_connection_get_state (NM_ACTIVE_CONNECTION (req)) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { - /* it's already deactivating. Nothing to do. */ - nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (req)), NULL, self)); - return; - } + if (nm_active_connection_get_state(NM_ACTIVE_CONNECTION(req)) + >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { + /* it's already deactivating. Nothing to do. */ + nm_assert( + NM_IN_SET(nm_active_connection_get_device(NM_ACTIVE_CONNECTION(req)), NULL, self)); + return; + } - nm_assert (self == nm_active_connection_get_device (NM_ACTIVE_CONNECTION (req))); + nm_assert(self == nm_active_connection_get_device(NM_ACTIVE_CONNECTION(req))); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - must_queue = _carrier_wait_check_act_request_must_queue (self, req); + must_queue = _carrier_wait_check_act_request_must_queue(self, req); - if ( !priv->act_request.obj - && !must_queue - && nm_device_is_real (self)) { - _device_activate (self, req); - return; - } + if (!priv->act_request.obj && !must_queue && nm_device_is_real(self)) { + _device_activate(self, req); + return; + } - /* supersede any already-queued request */ - _clear_queued_act_request (priv, - NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); - priv->queued_act_request = g_object_ref (req); - priv->queued_act_request_is_waiting_for_carrier = must_queue; + /* supersede any already-queued request */ + _clear_queued_act_request(priv, NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); + priv->queued_act_request = g_object_ref(req); + priv->queued_act_request_is_waiting_for_carrier = must_queue; - _LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect"); + _LOGD(LOGD_DEVICE, + "queue activation request waiting for %s", + must_queue ? "carrier" : "currently active connection to disconnect"); - /* Deactivate existing activation request first */ - if (priv->act_request.obj) { - _LOGI (LOGD_DEVICE, "disconnecting for new activation request."); - nm_device_state_changed (self, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_NEW_ACTIVATION); - } + /* Deactivate existing activation request first */ + if (priv->act_request.obj) { + _LOGI(LOGD_DEVICE, "disconnecting for new activation request."); + nm_device_state_changed(self, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_NEW_ACTIVATION); + } } /* @@ -13155,1293 +13383,1282 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req) * */ gboolean -nm_device_is_activating (NMDevice *self) +nm_device_is_activating(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceState state; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceState state; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - state = nm_device_get_state (self); - if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES) - return TRUE; + state = nm_device_get_state(self); + if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES) + return TRUE; - /* There's a small race between the time when stage 1 is scheduled - * and when the device actually sets STATE_PREPARE when the activation - * handler is actually run. If there's an activation handler scheduled - * we're activating anyway. - */ - return priv->activation_source_id_4 != 0; + /* There's a small race between the time when stage 1 is scheduled + * and when the device actually sets STATE_PREPARE when the activation + * handler is actually run. If there's an activation handler scheduled + * we're activating anyway. + */ + return priv->activation_source_id_4 != 0; } NMProxyConfig * -nm_device_get_proxy_config (NMDevice *self) +nm_device_get_proxy_config(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->proxy_config; + return NM_DEVICE_GET_PRIVATE(self)->proxy_config; } static void -nm_device_set_proxy_config (NMDevice *self, const char *pac_url) +nm_device_set_proxy_config(NMDevice *self, const char *pac_url) { - NMDevicePrivate *priv; - NMConnection *connection; - NMSettingProxy *s_proxy = NULL; + NMDevicePrivate *priv; + NMConnection * connection; + NMSettingProxy * s_proxy = NULL; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - g_clear_object (&priv->proxy_config); - priv->proxy_config = nm_proxy_config_new (); + g_clear_object(&priv->proxy_config); + priv->proxy_config = nm_proxy_config_new(); - if (pac_url) { - nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO); - nm_proxy_config_set_pac_url (priv->proxy_config, pac_url); - _LOGD (LOGD_PROXY, "proxy: PAC url \"%s\"", pac_url); - } else - nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE); + if (pac_url) { + nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO); + nm_proxy_config_set_pac_url(priv->proxy_config, pac_url); + _LOGD(LOGD_PROXY, "proxy: PAC url \"%s\"", pac_url); + } else + nm_proxy_config_set_method(priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE); - connection = nm_device_get_applied_connection (self); - if (connection) - s_proxy = nm_connection_get_setting_proxy (connection); + connection = nm_device_get_applied_connection(self); + if (connection) + s_proxy = nm_connection_get_setting_proxy(connection); - if (s_proxy) - nm_proxy_config_merge_setting (priv->proxy_config, s_proxy); + if (s_proxy) + nm_proxy_config_merge_setting(priv->proxy_config, s_proxy); } /* IP Configuration stuff */ NMDhcpConfig * -nm_device_get_dhcp_config (NMDevice *self, int addr_family) +nm_device_get_dhcp_config(NMDevice *self, int addr_family) { - const gboolean IS_IPv4 = (addr_family == AF_INET); + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - return NM_DEVICE_GET_PRIVATE (self)->dhcp_data_x[IS_IPv4].config; + return NM_DEVICE_GET_PRIVATE(self)->dhcp_data_x[IS_IPv4].config; } NMIP4Config * -nm_device_get_ip4_config (NMDevice *self) +nm_device_get_ip4_config(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->ip_config_4; + return NM_DEVICE_GET_PRIVATE(self)->ip_config_4; } static gboolean -nm_device_set_ip_config (NMDevice *self, - int addr_family, - NMIPConfig *new_config, - gboolean commit, - GPtrArray *ip4_dev_route_blacklist) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const gboolean IS_IPv4 = (addr_family == AF_INET); - NMIPConfig *old_config; - gboolean has_changes = FALSE; - gboolean success = TRUE; - NMSettingsConnection *settings_connection; - - nm_assert_addr_family (addr_family); - nm_assert (!new_config || nm_ip_config_get_addr_family (new_config) == addr_family); - nm_assert ( !new_config - || ( new_config - && ({ - int ip_ifindex = nm_device_get_ip_ifindex (self); - - ( ip_ifindex > 0 - && ip_ifindex == nm_ip_config_get_ifindex (new_config)); - }))); - nm_assert (IS_IPv4 || !ip4_dev_route_blacklist); - - _LOGD (LOGD_IP_from_af (addr_family), - "ip%c-config: update (commit=%d, new-config=%p)", - nm_utils_addr_family_to_char (addr_family), - commit, - new_config); - - /* Always commit to nm-platform to update lifetimes */ - if (commit && new_config) { - - _commit_mtu (self, - IS_IPv4 - ? NM_IP4_CONFIG (new_config) - : priv->ip_config_4); - - if (IS_IPv4) { - success = nm_ip4_config_commit (NM_IP4_CONFIG (new_config), - nm_device_get_platform (self), - _get_route_table_sync_mode_stateful (self, - AF_INET)); - nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), - nm_ip_config_get_ifindex (new_config), - ip4_dev_route_blacklist); - } else { - gs_unref_ptrarray GPtrArray *temporary_not_available = NULL; - - success = nm_ip6_config_commit (NM_IP6_CONFIG (new_config), - nm_device_get_platform (self), - _get_route_table_sync_mode_stateful (self, - AF_INET6), - &temporary_not_available); - - if (!_rt6_temporary_not_available_set (self, temporary_not_available)) - success = FALSE; - } - } - - old_config = priv->ip_config_x[IS_IPv4]; - - if (new_config && old_config) { - /* has_changes is set only on relevant changes, because when the configuration changes, - * this causes a re-read and reset. This should only happen for relevant changes */ - nm_ip_config_replace (old_config, new_config, &has_changes); - if (has_changes) { - _LOGD (LOGD_IP_from_af (addr_family), - "ip%c-config: update IP Config instance (%s)", - nm_utils_addr_family_to_char (addr_family), - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } - } else if (new_config /*&& !old_config*/) { - has_changes = TRUE; - priv->ip_config_x[IS_IPv4] = g_object_ref (new_config); - if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) - nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); - - _LOGD (LOGD_IP_from_af (addr_family), - "ip%c-config: set IP Config instance (%s)", - nm_utils_addr_family_to_char (addr_family), - nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); - } else if (old_config /*&& !new_config*/) { - has_changes = TRUE; - priv->ip_config_x[IS_IPv4] = NULL; - _LOGD (LOGD_IP_from_af (addr_family), - "ip%c-config: clear IP Config instance (%s)", - nm_utils_addr_family_to_char (addr_family), - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - if (IS_IPv4) { - /* Device config is invalid if combined config is invalid */ - applied_config_clear (&priv->dev_ip_config_4); - } else - priv->needs_ip6_subnet = FALSE; - } - - if (has_changes) { - - if (IS_IPv4) - _update_ip4_address (self); - - if (old_config != priv->ip_config_x[IS_IPv4]) - _notify (self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG); - - g_signal_emit (self, - signals[IS_IPv4 ? IP4_CONFIG_CHANGED : IP6_CONFIG_CHANGED], - 0, - priv->ip_config_x[IS_IPv4], - old_config); - - if (old_config != priv->ip_config_x[IS_IPv4]) - nm_dbus_object_clear_and_unexport (&old_config); - - if ( nm_device_sys_iface_state_is_external (self) - && (settings_connection = nm_device_get_settings_connection (self)) - && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), - NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL) - && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request.obj)) == NM_ACTIVATION_TYPE_EXTERNAL) { - gs_unref_object NMConnection *new_connection = NULL; - - new_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection)); - - nm_connection_add_setting (new_connection, - IS_IPv4 - ? nm_ip4_config_create_setting (priv->ip_config_4) - : nm_ip6_config_create_setting (priv->ip_config_6)); - - nm_settings_connection_update (settings_connection, - new_connection, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE, - "update-external", - NULL); - } - - nm_device_queue_recheck_assume (self); - - if (!IS_IPv4) { - if (priv->ndisc) - ndisc_set_router_config (priv->ndisc, self); - } - } - - nm_assert (!old_config || old_config == priv->ip_config_x[IS_IPv4]); - - return success; +nm_device_set_ip_config(NMDevice * self, + int addr_family, + NMIPConfig *new_config, + gboolean commit, + GPtrArray * ip4_dev_route_blacklist) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const gboolean IS_IPv4 = (addr_family == AF_INET); + NMIPConfig * old_config; + gboolean has_changes = FALSE; + gboolean success = TRUE; + NMSettingsConnection *settings_connection; + + nm_assert_addr_family(addr_family); + nm_assert(!new_config || nm_ip_config_get_addr_family(new_config) == addr_family); + nm_assert(!new_config + || (new_config && ({ + int ip_ifindex = nm_device_get_ip_ifindex(self); + + (ip_ifindex > 0 && ip_ifindex == nm_ip_config_get_ifindex(new_config)); + }))); + nm_assert(IS_IPv4 || !ip4_dev_route_blacklist); + + _LOGD(LOGD_IP_from_af(addr_family), + "ip%c-config: update (commit=%d, new-config=%p)", + nm_utils_addr_family_to_char(addr_family), + commit, + new_config); + + /* Always commit to nm-platform to update lifetimes */ + if (commit && new_config) { + _commit_mtu(self, IS_IPv4 ? NM_IP4_CONFIG(new_config) : priv->ip_config_4); + + if (IS_IPv4) { + success = nm_ip4_config_commit(NM_IP4_CONFIG(new_config), + nm_device_get_platform(self), + _get_route_table_sync_mode_stateful(self, AF_INET)); + nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), + nm_ip_config_get_ifindex(new_config), + ip4_dev_route_blacklist); + } else { + gs_unref_ptrarray GPtrArray *temporary_not_available = NULL; + + success = nm_ip6_config_commit(NM_IP6_CONFIG(new_config), + nm_device_get_platform(self), + _get_route_table_sync_mode_stateful(self, AF_INET6), + &temporary_not_available); + + if (!_rt6_temporary_not_available_set(self, temporary_not_available)) + success = FALSE; + } + } + + old_config = priv->ip_config_x[IS_IPv4]; + + if (new_config && old_config) { + /* has_changes is set only on relevant changes, because when the configuration changes, + * this causes a re-read and reset. This should only happen for relevant changes */ + nm_ip_config_replace(old_config, new_config, &has_changes); + if (has_changes) { + _LOGD(LOGD_IP_from_af(addr_family), + "ip%c-config: update IP Config instance (%s)", + nm_utils_addr_family_to_char(addr_family), + nm_dbus_object_get_path(NM_DBUS_OBJECT(old_config))); + } + } else if (new_config /*&& !old_config*/) { + has_changes = TRUE; + priv->ip_config_x[IS_IPv4] = g_object_ref(new_config); + if (!nm_dbus_object_is_exported(NM_DBUS_OBJECT(new_config))) + nm_dbus_object_export(NM_DBUS_OBJECT(new_config)); + + _LOGD(LOGD_IP_from_af(addr_family), + "ip%c-config: set IP Config instance (%s)", + nm_utils_addr_family_to_char(addr_family), + nm_dbus_object_get_path(NM_DBUS_OBJECT(new_config))); + } else if (old_config /*&& !new_config*/) { + has_changes = TRUE; + priv->ip_config_x[IS_IPv4] = NULL; + _LOGD(LOGD_IP_from_af(addr_family), + "ip%c-config: clear IP Config instance (%s)", + nm_utils_addr_family_to_char(addr_family), + nm_dbus_object_get_path(NM_DBUS_OBJECT(old_config))); + if (IS_IPv4) { + /* Device config is invalid if combined config is invalid */ + applied_config_clear(&priv->dev_ip_config_4); + } else + priv->needs_ip6_subnet = FALSE; + } + + if (has_changes) { + if (old_config != priv->ip_config_x[IS_IPv4]) + _notify(self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG); + + g_signal_emit(self, + signals[IS_IPv4 ? IP4_CONFIG_CHANGED : IP6_CONFIG_CHANGED], + 0, + priv->ip_config_x[IS_IPv4], + old_config); + + if (old_config != priv->ip_config_x[IS_IPv4]) + nm_dbus_object_clear_and_unexport(&old_config); + + if (nm_device_sys_iface_state_is_external(self) + && (settings_connection = nm_device_get_settings_connection(self)) + && NM_FLAGS_HAS(nm_settings_connection_get_flags(settings_connection), + NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL) + && nm_active_connection_get_activation_type(NM_ACTIVE_CONNECTION(priv->act_request.obj)) + == NM_ACTIVATION_TYPE_EXTERNAL) { + gs_unref_object NMConnection *new_connection = NULL; + + new_connection = nm_simple_connection_new_clone( + nm_settings_connection_get_connection(settings_connection)); + + nm_connection_add_setting( + new_connection, + IS_IPv4 ? nm_ip4_config_create_setting(priv->ip_config_4) + : nm_ip6_config_create_setting(priv->ip_config_6, + _get_maybe_ipv6_disabled(self))); + + nm_settings_connection_update(settings_connection, + new_connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE, + "update-external", + NULL); + } + + nm_device_queue_recheck_assume(self); + + if (!IS_IPv4) { + if (priv->ndisc) + ndisc_set_router_config(priv->ndisc, self); + } + } + + nm_assert(!old_config || old_config == priv->ip_config_x[IS_IPv4]); + + return success; } static gboolean -_replace_vpn_config_in_list (GSList **plist, GObject *old, GObject *new) -{ - GSList *old_link; - - /* Below, assert that @new is not yet tracked, but still behave - * correctly in any case. Don't complain for missing @old since - * it could have been removed when the parent device became - * unmanaged. */ - - if ( old - && (old_link = g_slist_find (*plist, old))) { - if (old != new) { - if (new) - old_link->data = g_object_ref (new); - else - *plist = g_slist_delete_link (*plist, old_link); - g_object_unref (old); - } - return TRUE; - } - - if (new) { - if (!g_slist_find (*plist, new)) - *plist = g_slist_append (*plist, g_object_ref (new)); - else - g_return_val_if_reached (TRUE); - return TRUE; - } - - return FALSE; +_replace_vpn_config_in_list(GSList **plist, GObject *old, GObject *new) +{ + GSList *old_link; + + /* Below, assert that @new is not yet tracked, but still behave + * correctly in any case. Don't complain for missing @old since + * it could have been removed when the parent device became + * unmanaged. */ + + if (old && (old_link = g_slist_find(*plist, old))) { + if (old != new) { + if (new) + old_link->data = g_object_ref(new); + else + *plist = g_slist_delete_link(*plist, old_link); + g_object_unref(old); + } + return TRUE; + } + + if (new) { + if (!g_slist_find(*plist, new)) + *plist = g_slist_append(*plist, g_object_ref(new)); + else + g_return_val_if_reached(TRUE); + return TRUE; + } + + return FALSE; } void -nm_device_replace_vpn4_config (NMDevice *self, NMIP4Config *old, NMIP4Config *config) +nm_device_replace_vpn4_config(NMDevice *self, NMIP4Config *old, NMIP4Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (!old || NM_IS_IP4_CONFIG (old)); - nm_assert (!config || NM_IS_IP4_CONFIG (config)); - nm_assert (!old || nm_ip4_config_get_ifindex (old) == nm_device_get_ip_ifindex (self)); - nm_assert (!config || nm_ip4_config_get_ifindex (config) == nm_device_get_ip_ifindex (self)); + nm_assert(!old || NM_IS_IP4_CONFIG(old)); + nm_assert(!config || NM_IS_IP4_CONFIG(config)); + nm_assert(!old || nm_ip4_config_get_ifindex(old) == nm_device_get_ip_ifindex(self)); + nm_assert(!config || nm_ip4_config_get_ifindex(config) == nm_device_get_ip_ifindex(self)); - if (!_replace_vpn_config_in_list (&priv->vpn_configs_4, (GObject *) old, (GObject *) config)) - return; + if (!_replace_vpn_config_in_list(&priv->vpn_configs_4, (GObject *) old, (GObject *) config)) + return; - /* NULL to use existing configs */ - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "failed to set VPN routes for device"); + /* NULL to use existing configs */ + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) + _LOGW(LOGD_IP4, "failed to set VPN routes for device"); } void -nm_device_set_dev2_ip_config (NMDevice *self, - int addr_family, - NMIPConfig *config) +nm_device_set_dev2_ip_config(NMDevice *self, int addr_family, NMIPConfig *config) { - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); + NMDevicePrivate *priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - g_return_if_fail ( !config - || nm_ip_config_get_addr_family (config) == addr_family); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + g_return_if_fail(!config || nm_ip_config_get_addr_family(config) == addr_family); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - applied_config_init (&priv->dev2_ip_config_x[IS_IPv4], config); - if (!ip_config_merge_and_apply (self, addr_family, TRUE)) { - _LOGW (LOGD_IP, "failed to set extra device IPv%c configuration", - nm_utils_addr_family_to_char (addr_family)); - } + applied_config_init(&priv->dev2_ip_config_x[IS_IPv4], config); + if (!ip_config_merge_and_apply(self, addr_family, TRUE)) { + _LOGW(LOGD_IP, + "failed to set extra device IPv%c configuration", + nm_utils_addr_family_to_char(addr_family)); + } } void -nm_device_replace_vpn6_config (NMDevice *self, NMIP6Config *old, NMIP6Config *config) +nm_device_replace_vpn6_config(NMDevice *self, NMIP6Config *old, NMIP6Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (!old || NM_IS_IP6_CONFIG (old)); - nm_assert (!config || NM_IS_IP6_CONFIG (config)); - nm_assert (!old || nm_ip6_config_get_ifindex (old) == nm_device_get_ip_ifindex (self)); - nm_assert (!config || nm_ip6_config_get_ifindex (config) == nm_device_get_ip_ifindex (self)); + nm_assert(!old || NM_IS_IP6_CONFIG(old)); + nm_assert(!config || NM_IS_IP6_CONFIG(config)); + nm_assert(!old || nm_ip6_config_get_ifindex(old) == nm_device_get_ip_ifindex(self)); + nm_assert(!config || nm_ip6_config_get_ifindex(config) == nm_device_get_ip_ifindex(self)); - if (!_replace_vpn_config_in_list (&priv->vpn_configs_6, (GObject *) old, (GObject *) config)) - return; + if (!_replace_vpn_config_in_list(&priv->vpn_configs_6, (GObject *) old, (GObject *) config)) + return; - /* NULL to use existing configs */ - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "failed to set VPN routes for device"); + /* NULL to use existing configs */ + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed to set VPN routes for device"); } NMIP6Config * -nm_device_get_ip6_config (NMDevice *self) +nm_device_get_ip6_config(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->ip_config_6; + return NM_DEVICE_GET_PRIVATE(self)->ip_config_6; } /*****************************************************************************/ static gboolean -dispatcher_cleanup (NMDevice *self) +dispatcher_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->dispatcher.call_id) - return FALSE; + if (!priv->dispatcher.call_id) + return FALSE; - nm_dispatcher_call_cancel (g_steal_pointer (&priv->dispatcher.call_id)); - priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; - priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; - return TRUE; + nm_dispatcher_call_cancel(g_steal_pointer(&priv->dispatcher.call_id)); + priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; + priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; + return TRUE; } static void -dispatcher_complete_proceed_state (NMDispatcherCallId *call_id, gpointer user_data) +dispatcher_complete_proceed_state(NMDispatcherCallId *call_id, gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - g_return_if_fail (call_id == priv->dispatcher.call_id); + g_return_if_fail(call_id == priv->dispatcher.call_id); - priv->dispatcher.call_id = NULL; - nm_device_queue_state (self, - priv->dispatcher.post_state, - priv->dispatcher.post_state_reason); - priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; - priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; + priv->dispatcher.call_id = NULL; + nm_device_queue_state(self, priv->dispatcher.post_state, priv->dispatcher.post_state_reason); + priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; + priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; } /*****************************************************************************/ static void -ip_check_pre_up (NMDevice *self) +ip_check_pre_up(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (dispatcher_cleanup (self)) - nm_assert_not_reached (); + if (dispatcher_cleanup(self)) + nm_assert_not_reached(); - priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES; - priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; - if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_UP, - self, - NULL, - dispatcher_complete_proceed_state, - self, - &priv->dispatcher.call_id)) { - /* Just proceed on errors */ - dispatcher_complete_proceed_state (0, self); - } + priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES; + priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; + if (!nm_dispatcher_call_device(NM_DISPATCHER_ACTION_PRE_UP, + self, + NULL, + dispatcher_complete_proceed_state, + self, + &priv->dispatcher.call_id)) { + /* Just proceed on errors */ + dispatcher_complete_proceed_state(0, self); + } } static void -ip_check_gw_ping_cleanup (NMDevice *self) +ip_check_gw_ping_cleanup(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_clear_g_source (&priv->gw_ping.watch); - nm_clear_g_source (&priv->gw_ping.timeout); + nm_clear_g_source(&priv->gw_ping.watch); + nm_clear_g_source(&priv->gw_ping.timeout); - if (priv->gw_ping.pid) { - nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL); - priv->gw_ping.pid = 0; - } + if (priv->gw_ping.pid) { + nm_utils_kill_child_async(priv->gw_ping.pid, + SIGTERM, + priv->gw_ping.log_domain, + "ping", + 1000, + NULL, + NULL); + priv->gw_ping.pid = 0; + } - nm_clear_g_free (&priv->gw_ping.binary); - nm_clear_g_free (&priv->gw_ping.address); + nm_clear_g_free(&priv->gw_ping.binary); + nm_clear_g_free(&priv->gw_ping.address); } static gboolean -spawn_ping (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free char *str_timeout = NULL; - gs_free char *tmp_str = NULL; - const char *args[] = { priv->gw_ping.binary, "-I", nm_device_get_ip_iface (self), - "-c", "1", "-w", NULL, priv->gw_ping.address, NULL }; - gs_free_error GError *error = NULL; - gboolean ret; - - args[6] = str_timeout = g_strdup_printf ("%u", priv->gw_ping.deadline); - tmp_str = g_strjoinv (" ", (char **) args); - _LOGD (priv->gw_ping.log_domain, "ping: running '%s'", tmp_str); - - ret = g_spawn_async ("/", - (char **) args, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD, - NULL, - NULL, - &priv->gw_ping.pid, - &error); - - if (!ret) { - _LOGW (priv->gw_ping.log_domain, "ping: could not spawn %s: %s", - priv->gw_ping.binary, error->message); - } - - return ret; +spawn_ping(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gs_free char * str_timeout = NULL; + gs_free char * tmp_str = NULL; + const char * args[] = {priv->gw_ping.binary, + "-I", + nm_device_get_ip_iface(self), + "-c", + "1", + "-w", + NULL, + priv->gw_ping.address, + NULL}; + gs_free_error GError *error = NULL; + gboolean ret; + + args[6] = str_timeout = g_strdup_printf("%u", priv->gw_ping.deadline); + tmp_str = g_strjoinv(" ", (char **) args); + _LOGD(priv->gw_ping.log_domain, "ping: running '%s'", tmp_str); + + ret = g_spawn_async("/", + (char **) args, + NULL, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &priv->gw_ping.pid, + &error); + + if (!ret) { + _LOGW(priv->gw_ping.log_domain, + "ping: could not spawn %s: %s", + priv->gw_ping.binary, + error->message); + } + + return ret; } static gboolean -respawn_ping_cb (gpointer user_data) +respawn_ping_cb(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->gw_ping.watch = 0; + priv->gw_ping.watch = 0; - if (spawn_ping (self)) { - priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, - ip_check_ping_watch_cb, self); - } else { - ip_check_gw_ping_cleanup (self); - ip_check_pre_up (self); - } + if (spawn_ping(self)) { + priv->gw_ping.watch = g_child_watch_add(priv->gw_ping.pid, ip_check_ping_watch_cb, self); + } else { + ip_check_gw_ping_cleanup(self); + ip_check_pre_up(self); + } - return FALSE; + return FALSE; } static void -ip_check_ping_watch_cb (GPid pid, int status, gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMLogDomain log_domain = priv->gw_ping.log_domain; - gboolean success = FALSE; - - if (!priv->gw_ping.watch) - return; - priv->gw_ping.watch = 0; - priv->gw_ping.pid = 0; - - if (WIFEXITED (status)) { - if (WEXITSTATUS (status) == 0) { - _LOGD (log_domain, "ping: gateway ping succeeded"); - success = TRUE; - } else { - _LOGW (log_domain, "ping: gateway ping failed with error code %d", - WEXITSTATUS (status)); - } - } else - _LOGW (log_domain, "ping: stopped unexpectedly with status %d", status); - - if (success) { - /* We've got connectivity, proceed to pre_up */ - ip_check_gw_ping_cleanup (self); - ip_check_pre_up (self); - } else { - /* If ping exited with an error it may have returned early, - * wait 1 second and restart it */ - priv->gw_ping.watch = g_timeout_add_seconds (1, respawn_ping_cb, self); - } +ip_check_ping_watch_cb(GPid pid, int status, gpointer user_data) +{ + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMLogDomain log_domain = priv->gw_ping.log_domain; + gboolean success = FALSE; + + if (!priv->gw_ping.watch) + return; + priv->gw_ping.watch = 0; + priv->gw_ping.pid = 0; + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + _LOGD(log_domain, "ping: gateway ping succeeded"); + success = TRUE; + } else { + _LOGW(log_domain, "ping: gateway ping failed with error code %d", WEXITSTATUS(status)); + } + } else + _LOGW(log_domain, "ping: stopped unexpectedly with status %d", status); + + if (success) { + /* We've got connectivity, proceed to pre_up */ + ip_check_gw_ping_cleanup(self); + ip_check_pre_up(self); + } else { + /* If ping exited with an error it may have returned early, + * wait 1 second and restart it */ + priv->gw_ping.watch = g_timeout_add_seconds(1, respawn_ping_cb, self); + } } static gboolean -ip_check_ping_timeout_cb (gpointer user_data) +ip_check_ping_timeout_cb(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->gw_ping.timeout = 0; + priv->gw_ping.timeout = 0; - _LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out"); + _LOGW(priv->gw_ping.log_domain, "ping: gateway ping timed out"); - ip_check_gw_ping_cleanup (self); - ip_check_pre_up (self); - return FALSE; + ip_check_gw_ping_cleanup(self); + ip_check_pre_up(self); + return FALSE; } static gboolean -start_ping (NMDevice *self, - NMLogDomain log_domain, - const char *binary, - const char *address, - guint timeout) +start_ping(NMDevice * self, + NMLogDomain log_domain, + const char *binary, + const char *address, + guint timeout) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE); - g_return_val_if_fail (priv->gw_ping.timeout == 0, FALSE); + g_return_val_if_fail(priv->gw_ping.watch == 0, FALSE); + g_return_val_if_fail(priv->gw_ping.timeout == 0, FALSE); - priv->gw_ping.log_domain = log_domain; - priv->gw_ping.address = g_strdup (address); - priv->gw_ping.binary = g_strdup (binary); - priv->gw_ping.deadline = timeout + 10; /* the proper termination is enforced by a timer */ + priv->gw_ping.log_domain = log_domain; + priv->gw_ping.address = g_strdup(address); + priv->gw_ping.binary = g_strdup(binary); + priv->gw_ping.deadline = timeout + 10; /* the proper termination is enforced by a timer */ - if (spawn_ping (self)) { - priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self); - priv->gw_ping.timeout = g_timeout_add_seconds (timeout, ip_check_ping_timeout_cb, self); - return TRUE; - } + if (spawn_ping(self)) { + priv->gw_ping.watch = g_child_watch_add(priv->gw_ping.pid, ip_check_ping_watch_cb, self); + priv->gw_ping.timeout = g_timeout_add_seconds(timeout, ip_check_ping_timeout_cb, self); + return TRUE; + } - ip_check_gw_ping_cleanup (self); - return FALSE; + ip_check_gw_ping_cleanup(self); + return FALSE; } static void -nm_device_start_ip_check (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; - NMSettingConnection *s_con; - guint timeout = 0; - const char *ping_binary = NULL; - char buf[NM_UTILS_INET_ADDRSTRLEN]; - NMLogDomain log_domain = LOGD_IP4; - - /* Shouldn't be any active ping here, since IP_CHECK happens after the - * first IP method completes. Any subsequently completing IP method doesn't - * get checked. - */ - g_return_if_fail (!priv->gw_ping.watch); - g_return_if_fail (!priv->gw_ping.timeout); - g_return_if_fail (!priv->gw_ping.pid); - g_return_if_fail (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE || priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE); - - connection = nm_device_get_applied_connection (self); - g_assert (connection); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - timeout = nm_setting_connection_get_gateway_ping_timeout (s_con); - - buf[0] = '\0'; - if (timeout) { - const NMPObject *gw; - - if (priv->ip_config_4 && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { - gw = nm_ip4_config_best_default_route_get (priv->ip_config_4); - if (gw) { - _nm_utils_inet4_ntop (NMP_OBJECT_CAST_IP4_ROUTE (gw)->gateway, buf); - ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL); - log_domain = LOGD_IP4; - } - } else if (priv->ip_config_6 && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { - gw = nm_ip6_config_best_default_route_get (priv->ip_config_6); - if (gw) { - _nm_utils_inet6_ntop (&NMP_OBJECT_CAST_IP6_ROUTE (gw)->gateway, buf); - ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL); - log_domain = LOGD_IP6; - } - } - } - - if (buf[0]) - start_ping (self, log_domain, ping_binary, buf, timeout); - - /* If no ping was started, just advance to pre_up */ - if (!priv->gw_ping.pid) - ip_check_pre_up (self); +nm_device_start_ip_check(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMConnection * connection; + NMSettingConnection *s_con; + guint timeout = 0; + const char * ping_binary = NULL; + char buf[NM_UTILS_INET_ADDRSTRLEN]; + NMLogDomain log_domain = LOGD_IP4; + + /* Shouldn't be any active ping here, since IP_CHECK happens after the + * first IP method completes. Any subsequently completing IP method doesn't + * get checked. + */ + g_return_if_fail(!priv->gw_ping.watch); + g_return_if_fail(!priv->gw_ping.timeout); + g_return_if_fail(!priv->gw_ping.pid); + g_return_if_fail(priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE + || priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE); + + connection = nm_device_get_applied_connection(self); + g_assert(connection); + + s_con = nm_connection_get_setting_connection(connection); + g_assert(s_con); + timeout = nm_setting_connection_get_gateway_ping_timeout(s_con); + + buf[0] = '\0'; + if (timeout) { + const NMPObject *gw; + + if (priv->ip_config_4 && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { + gw = nm_ip4_config_best_default_route_get(priv->ip_config_4); + if (gw) { + _nm_utils_inet4_ntop(NMP_OBJECT_CAST_IP4_ROUTE(gw)->gateway, buf); + ping_binary = nm_utils_find_helper("ping", "/usr/bin/ping", NULL); + log_domain = LOGD_IP4; + } + } else if (priv->ip_config_6 && priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { + gw = nm_ip6_config_best_default_route_get(priv->ip_config_6); + if (gw) { + _nm_utils_inet6_ntop(&NMP_OBJECT_CAST_IP6_ROUTE(gw)->gateway, buf); + ping_binary = nm_utils_find_helper("ping6", "/usr/bin/ping6", NULL); + log_domain = LOGD_IP6; + } + } + } + + if (buf[0]) + start_ping(self, log_domain, ping_binary, buf, timeout); + + /* If no ping was started, just advance to pre_up */ + if (!priv->gw_ping.pid) + ip_check_pre_up(self); } /*****************************************************************************/ static gboolean -carrier_wait_timeout (gpointer user_data) +carrier_wait_timeout(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->carrier_wait_id = 0; - nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); - if (!priv->carrier) - _carrier_wait_check_queued_act_request (self); - return G_SOURCE_REMOVE; + priv->carrier_wait_id = 0; + nm_device_remove_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); + if (!priv->carrier) + _carrier_wait_check_queued_act_request(self); + return G_SOURCE_REMOVE; } static gboolean -nm_device_is_up (NMDevice *self) +nm_device_is_up(NMDevice *self) { - int ifindex; + int ifindex; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - ifindex = nm_device_get_ip_ifindex (self); - return ifindex > 0 ? nm_platform_link_is_up (nm_device_get_platform (self), ifindex) : TRUE; + ifindex = nm_device_get_ip_ifindex(self); + return ifindex > 0 ? nm_platform_link_is_up(nm_device_get_platform(self), ifindex) : TRUE; } static gint64 -_get_carrier_wait_ms (NMDevice *self) +_get_carrier_wait_ms(NMDevice *self) { - gs_free char *value = NULL; + gs_free char *value = NULL; - value = nm_config_data_get_device_config (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, - self, - NULL); - return _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32, CARRIER_WAIT_TIME_MS); + value = nm_config_data_get_device_config(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + self, + NULL); + return _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT32, CARRIER_WAIT_TIME_MS); } gboolean -nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean device_is_up = FALSE; - NMDeviceCapabilities capabilities; - int ifindex; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - NM_SET_OUT (no_firmware, FALSE); - - if (!nm_device_get_enabled (self)) { - _LOGD (LOGD_PLATFORM, "bringing up device ignored due to disabled"); - return FALSE; - } - - ifindex = nm_device_get_ip_ifindex (self); - _LOGD (LOGD_PLATFORM, "bringing up device %d", ifindex); - if (ifindex <= 0) { - /* assume success. */ - } else { - if (!nm_platform_link_set_up (nm_device_get_platform (self), ifindex, no_firmware)) - return FALSE; - } - - /* Store carrier immediately. */ - nm_device_set_carrier_from_platform (self); - - device_is_up = nm_device_is_up (self); - if (block && !device_is_up) { - gint64 wait_until = nm_utils_get_monotonic_timestamp_usec () + 10000 /* microseconds */; - - do { - g_usleep (200); - if (!nm_platform_link_refresh (nm_device_get_platform (self), ifindex)) - return FALSE; - device_is_up = nm_device_is_up (self); - } while (!device_is_up && nm_utils_get_monotonic_timestamp_usec () < wait_until); - } - - if (!device_is_up) { - if (block) - _LOGW (LOGD_PLATFORM, "device not up after timeout!"); - else - _LOGD (LOGD_PLATFORM, "device not up immediately"); - return FALSE; - } - - /* some ethernet devices fail to report capabilities unless the device - * is up. Re-read the capabilities. */ - capabilities = 0; - if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) - capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); - _add_capabilities (self, capabilities); - - /* Devices that support carrier detect must be IFF_UP to report carrier - * changes; so after setting the device IFF_UP we must suppress startup - * complete (via a pending action) until either the carrier turns on, or - * a timeout is reached. - */ - if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { - gint64 now_ms, until_ms; - - /* we start a grace period of 5 seconds during which we will schedule - * a pending action whenever we have no carrier. - * - * If during that time carrier goes away, we declare the interface - * as not ready. */ - nm_clear_g_source (&priv->carrier_wait_id); - if (!priv->carrier) - nm_device_add_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); - - now_ms = nm_utils_get_monotonic_timestamp_msec (); - until_ms = NM_MAX (now_ms + _get_carrier_wait_ms (self), priv->carrier_wait_until_ms); - priv->carrier_wait_id = g_timeout_add (until_ms - now_ms, carrier_wait_timeout, self); - } - - /* Can only get HW address of some devices when they are up */ - nm_device_update_hw_address (self); - - _update_ip4_address (self); - - /* when the link comes up, we must restore IP configuration if necessary. */ - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { - if (!ip_config_merge_and_apply (self, AF_INET, TRUE)) - _LOGW (LOGD_IP4, "failed applying IP4 config after bringing link up"); - } - if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { - if (!ip_config_merge_and_apply (self, AF_INET6, TRUE)) - _LOGW (LOGD_IP6, "failed applying IP6 config after bringing link up"); - } - - return TRUE; +nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gboolean device_is_up = FALSE; + NMDeviceCapabilities capabilities; + int ifindex; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + NM_SET_OUT(no_firmware, FALSE); + + if (!nm_device_get_enabled(self)) { + _LOGD(LOGD_PLATFORM, "bringing up device ignored due to disabled"); + return FALSE; + } + + ifindex = nm_device_get_ip_ifindex(self); + _LOGD(LOGD_PLATFORM, "bringing up device %d", ifindex); + if (ifindex <= 0) { + /* assume success. */ + } else { + if (!nm_platform_link_set_up(nm_device_get_platform(self), ifindex, no_firmware)) + return FALSE; + } + + /* Store carrier immediately. */ + nm_device_set_carrier_from_platform(self); + + device_is_up = nm_device_is_up(self); + if (block && !device_is_up) { + gint64 wait_until = nm_utils_get_monotonic_timestamp_usec() + 10000 /* microseconds */; + + do { + g_usleep(200); + if (!nm_platform_link_refresh(nm_device_get_platform(self), ifindex)) + return FALSE; + device_is_up = nm_device_is_up(self); + } while (!device_is_up && nm_utils_get_monotonic_timestamp_usec() < wait_until); + } + + if (!device_is_up) { + if (block) + _LOGW(LOGD_PLATFORM, "device not up after timeout!"); + else + _LOGD(LOGD_PLATFORM, "device not up immediately"); + return FALSE; + } + + /* some ethernet devices fail to report capabilities unless the device + * is up. Re-read the capabilities. */ + capabilities = 0; + if (NM_DEVICE_GET_CLASS(self)->get_generic_capabilities) + capabilities |= NM_DEVICE_GET_CLASS(self)->get_generic_capabilities(self); + _add_capabilities(self, capabilities); + + /* Devices that support carrier detect must be IFF_UP to report carrier + * changes; so after setting the device IFF_UP we must suppress startup + * complete (via a pending action) until either the carrier turns on, or + * a timeout is reached. + */ + if (nm_device_has_capability(self, NM_DEVICE_CAP_CARRIER_DETECT)) { + gint64 now_ms, until_ms; + + /* we start a grace period of 5 seconds during which we will schedule + * a pending action whenever we have no carrier. + * + * If during that time carrier goes away, we declare the interface + * as not ready. */ + nm_clear_g_source(&priv->carrier_wait_id); + if (!priv->carrier) + nm_device_add_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); + + now_ms = nm_utils_get_monotonic_timestamp_msec(); + until_ms = NM_MAX(now_ms + _get_carrier_wait_ms(self), priv->carrier_wait_until_ms); + priv->carrier_wait_id = g_timeout_add(until_ms - now_ms, carrier_wait_timeout, self); + } + + /* Can only get HW address of some devices when they are up */ + nm_device_update_hw_address(self); + + /* when the link comes up, we must restore IP configuration if necessary. */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE) { + if (!ip_config_merge_and_apply(self, AF_INET, TRUE)) + _LOGW(LOGD_IP4, "failed applying IP4 config after bringing link up"); + } + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_DONE) { + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed applying IP6 config after bringing link up"); + } + + return TRUE; } void -nm_device_take_down (NMDevice *self, gboolean block) +nm_device_take_down(NMDevice *self, gboolean block) { - int ifindex; - gboolean device_is_up; + int ifindex; + gboolean device_is_up; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - ifindex = nm_device_get_ip_ifindex (self); - _LOGD (LOGD_PLATFORM, "taking down device %d", ifindex); - if (ifindex <= 0) { - /* devices without ifindex are always up. */ - return; - } + ifindex = nm_device_get_ip_ifindex(self); + _LOGD(LOGD_PLATFORM, "taking down device %d", ifindex); + if (ifindex <= 0) { + /* devices without ifindex are always up. */ + return; + } - if (!nm_platform_link_set_down (nm_device_get_platform (self), ifindex)) - return; + if (!nm_platform_link_set_down(nm_device_get_platform(self), ifindex)) + return; - device_is_up = nm_device_is_up (self); - if (block && device_is_up) { - gint64 wait_until = nm_utils_get_monotonic_timestamp_usec () + 10000 /* microseconds */; + device_is_up = nm_device_is_up(self); + if (block && device_is_up) { + gint64 wait_until = nm_utils_get_monotonic_timestamp_usec() + 10000 /* microseconds */; - do { - g_usleep (200); - if (!nm_platform_link_refresh (nm_device_get_platform (self), ifindex)) - return; - device_is_up = nm_device_is_up (self); - } while (device_is_up && nm_utils_get_monotonic_timestamp_usec () < wait_until); - } + do { + g_usleep(200); + if (!nm_platform_link_refresh(nm_device_get_platform(self), ifindex)) + return; + device_is_up = nm_device_is_up(self); + } while (device_is_up && nm_utils_get_monotonic_timestamp_usec() < wait_until); + } - if (device_is_up) { - if (block) - _LOGW (LOGD_PLATFORM, "device not down after timeout!"); - else - _LOGD (LOGD_PLATFORM, "device not down immediately"); - } + if (device_is_up) { + if (block) + _LOGW(LOGD_PLATFORM, "device not down after timeout!"); + else + _LOGD(LOGD_PLATFORM, "device not down immediately"); + } } void -nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing) +nm_device_set_firmware_missing(NMDevice *self, gboolean new_missing) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->firmware_missing != new_missing) { - priv->firmware_missing = new_missing; - _notify (self, PROP_FIRMWARE_MISSING); - } + priv = NM_DEVICE_GET_PRIVATE(self); + if (priv->firmware_missing != new_missing) { + priv->firmware_missing = new_missing; + _notify(self, PROP_FIRMWARE_MISSING); + } } gboolean -nm_device_get_firmware_missing (NMDevice *self) +nm_device_get_firmware_missing(NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (self)->firmware_missing; + return NM_DEVICE_GET_PRIVATE(self)->firmware_missing; } static void -intersect_ext_config (NMDevice *self, - AppliedConfig *config, - gboolean intersect_addresses, - gboolean intersect_routes) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMIPConfig *ext; - guint32 penalty; - int family; - - if (!config->orig) - return; - - family = nm_ip_config_get_addr_family (config->orig); - penalty = default_route_metric_penalty_get (self, family); - ext = family == AF_INET - ? (NMIPConfig *) priv->ext_ip_config_4 - : (NMIPConfig *) priv->ext_ip_config_6; - - if (config->current) { - nm_ip_config_intersect (config->current, - ext, - intersect_addresses, - intersect_routes, - penalty); - } else { - config->current = nm_ip_config_intersect_alloc (config->orig, - ext, - intersect_addresses, - intersect_routes, - penalty); - } +intersect_ext_config(NMDevice * self, + AppliedConfig *config, + gboolean intersect_addresses, + gboolean intersect_routes) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMIPConfig * ext; + guint32 penalty; + int family; + + if (!config->orig) + return; + + family = nm_ip_config_get_addr_family(config->orig); + penalty = default_route_metric_penalty_get(self, family); + ext = family == AF_INET ? (NMIPConfig *) priv->ext_ip_config_4 + : (NMIPConfig *) priv->ext_ip_config_6; + + if (config->current) { + nm_ip_config_intersect(config->current, + ext, + intersect_addresses, + intersect_routes, + penalty); + } else { + config->current = nm_ip_config_intersect_alloc(config->orig, + ext, + intersect_addresses, + intersect_routes, + penalty); + } } static gboolean -update_ext_ip_config (NMDevice *self, int addr_family, gboolean intersect_configs) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - int ifindex; - GSList *iter; - gboolean is_up; - - nm_assert_addr_family (addr_family); - - ifindex = nm_device_get_ip_ifindex (self); - if (!ifindex) - return FALSE; - - is_up = nm_platform_link_is_up (nm_device_get_platform (self), ifindex); - - if (addr_family == AF_INET) { - - g_clear_object (&priv->ext_ip_config_4); - priv->ext_ip_config_4 = nm_ip4_config_capture (nm_device_get_multi_index (self), - nm_device_get_platform (self), - ifindex); - if (priv->ext_ip_config_4) { - if (intersect_configs) { - /* This function was called upon external changes. Remove the configuration - * (addresses,routes) that is no longer present externally from the internal - * config. This way, we don't re-add addresses that were manually removed - * by the user. */ - if (priv->con_ip_config_4) { - nm_ip4_config_intersect (priv->con_ip_config_4, priv->ext_ip_config_4, - TRUE, - is_up, - default_route_metric_penalty_get (self, AF_INET)); - } - - intersect_ext_config (self, &priv->dev_ip_config_4, TRUE, is_up); - intersect_ext_config (self, &priv->dev2_ip_config_4, TRUE, is_up); - - for (iter = priv->vpn_configs_4; iter; iter = iter->next) - nm_ip4_config_intersect (iter->data, priv->ext_ip_config_4, TRUE, is_up, 0); - } - - /* Remove parts from ext_ip_config_4 to only contain the information that - * was configured externally -- we already have the same configuration from - * internal origins. */ - if (priv->con_ip_config_4) { - nm_ip4_config_subtract (priv->ext_ip_config_4, priv->con_ip_config_4, - default_route_metric_penalty_get (self, AF_INET)); - } - if (applied_config_get_current (&priv->dev_ip_config_4)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_4, - applied_config_get_current (&priv->dev_ip_config_4), - default_route_metric_penalty_get (self, AF_INET)); - } - if (applied_config_get_current (&priv->dev2_ip_config_4)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_4, - applied_config_get_current (&priv->dev2_ip_config_4), - default_route_metric_penalty_get (self, AF_INET)); - } - for (iter = priv->vpn_configs_4; iter; iter = iter->next) - nm_ip4_config_subtract (priv->ext_ip_config_4, iter->data, 0); - } - - } else { - nm_assert (addr_family == AF_INET6); - - g_clear_object (&priv->ext_ip_config_6); - g_clear_object (&priv->ext_ip6_config_captured); - priv->ext_ip6_config_captured = nm_ip6_config_capture (nm_device_get_multi_index (self), - nm_device_get_platform (self), - ifindex, - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - if (priv->ext_ip6_config_captured) { - - priv->ext_ip_config_6 = nm_ip6_config_new_cloned (priv->ext_ip6_config_captured); - - if (intersect_configs) { - /* This function was called upon external changes. Remove the configuration - * (addresses,routes) that is no longer present externally from the internal - * config. This way, we don't re-add addresses that were manually removed - * by the user. */ - if (priv->con_ip_config_6) { - nm_ip6_config_intersect (priv->con_ip_config_6, priv->ext_ip_config_6, - is_up, - is_up, - default_route_metric_penalty_get (self, AF_INET6)); - } - - intersect_ext_config (self, &priv->ac_ip6_config, is_up, is_up); - intersect_ext_config (self, &priv->dhcp6.ip6_config, is_up, is_up); - intersect_ext_config (self, &priv->dev2_ip_config_6, is_up, is_up); - - for (iter = priv->vpn_configs_6; iter; iter = iter->next) - nm_ip6_config_intersect (iter->data, priv->ext_ip_config_6, is_up, is_up, 0); - - if ( is_up - && priv->ipv6ll_has - && !nm_ip6_config_lookup_address (priv->ext_ip_config_6, &priv->ipv6ll_addr)) - priv->ipv6ll_has = FALSE; - } - - /* Remove parts from ext_ip_config_6 to only contain the information that - * was configured externally -- we already have the same configuration from - * internal origins. */ - if (priv->con_ip_config_6) { - nm_ip6_config_subtract (priv->ext_ip_config_6, priv->con_ip_config_6, - default_route_metric_penalty_get (self, AF_INET6)); - } - if (applied_config_get_current (&priv->ac_ip6_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, - applied_config_get_current (&priv->ac_ip6_config), - default_route_metric_penalty_get (self, AF_INET6)); - } - if (applied_config_get_current (&priv->dhcp6.ip6_config)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, - applied_config_get_current (&priv->dhcp6.ip6_config), - default_route_metric_penalty_get (self, AF_INET6)); - } - if (applied_config_get_current (&priv->dev2_ip_config_6)) { - nm_ip_config_subtract ((NMIPConfig *) priv->ext_ip_config_6, - applied_config_get_current (&priv->dev2_ip_config_6), - default_route_metric_penalty_get (self, AF_INET6)); - } - for (iter = priv->vpn_configs_6; iter; iter = iter->next) - nm_ip6_config_subtract (priv->ext_ip_config_6, iter->data, 0); - } - } - - return TRUE; +update_ext_ip_config(NMDevice *self, int addr_family, gboolean intersect_configs) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int ifindex; + GSList * iter; + gboolean is_up; + + nm_assert_addr_family(addr_family); + + ifindex = nm_device_get_ip_ifindex(self); + if (!ifindex) + return FALSE; + + is_up = nm_platform_link_is_up(nm_device_get_platform(self), ifindex); + + if (addr_family == AF_INET) { + g_clear_object(&priv->ext_ip_config_4); + priv->ext_ip_config_4 = nm_ip4_config_capture(nm_device_get_multi_index(self), + nm_device_get_platform(self), + ifindex); + if (priv->ext_ip_config_4) { + if (intersect_configs) { + /* This function was called upon external changes. Remove the configuration + * (addresses,routes) that is no longer present externally from the internal + * config. This way, we don't re-add addresses that were manually removed + * by the user. */ + if (priv->con_ip_config_4) { + nm_ip4_config_intersect(priv->con_ip_config_4, + priv->ext_ip_config_4, + TRUE, + is_up, + default_route_metric_penalty_get(self, AF_INET)); + } + + intersect_ext_config(self, &priv->dev_ip_config_4, TRUE, is_up); + intersect_ext_config(self, &priv->dev2_ip_config_4, TRUE, is_up); + + for (iter = priv->vpn_configs_4; iter; iter = iter->next) + nm_ip4_config_intersect(iter->data, priv->ext_ip_config_4, TRUE, is_up, 0); + } + + /* Remove parts from ext_ip_config_4 to only contain the information that + * was configured externally -- we already have the same configuration from + * internal origins. */ + if (priv->con_ip_config_4) { + nm_ip4_config_subtract(priv->ext_ip_config_4, + priv->con_ip_config_4, + default_route_metric_penalty_get(self, AF_INET)); + } + if (applied_config_get_current(&priv->dev_ip_config_4)) { + nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_4, + applied_config_get_current(&priv->dev_ip_config_4), + default_route_metric_penalty_get(self, AF_INET)); + } + if (applied_config_get_current(&priv->dev2_ip_config_4)) { + nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_4, + applied_config_get_current(&priv->dev2_ip_config_4), + default_route_metric_penalty_get(self, AF_INET)); + } + for (iter = priv->vpn_configs_4; iter; iter = iter->next) + nm_ip4_config_subtract(priv->ext_ip_config_4, iter->data, 0); + } + + } else { + nm_assert(addr_family == AF_INET6); + + g_clear_object(&priv->ext_ip_config_6); + g_clear_object(&priv->ext_ip6_config_captured); + priv->ext_ip6_config_captured = + nm_ip6_config_capture(nm_device_get_multi_index(self), + nm_device_get_platform(self), + ifindex, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + if (priv->ext_ip6_config_captured) { + priv->ext_ip_config_6 = nm_ip6_config_new_cloned(priv->ext_ip6_config_captured); + + if (intersect_configs) { + /* This function was called upon external changes. Remove the configuration + * (addresses,routes) that is no longer present externally from the internal + * config. This way, we don't re-add addresses that were manually removed + * by the user. */ + if (priv->con_ip_config_6) { + nm_ip6_config_intersect(priv->con_ip_config_6, + priv->ext_ip_config_6, + is_up, + is_up, + default_route_metric_penalty_get(self, AF_INET6)); + } + + intersect_ext_config(self, &priv->ac_ip6_config, is_up, is_up); + intersect_ext_config(self, &priv->dhcp6.ip6_config, is_up, is_up); + intersect_ext_config(self, &priv->dev2_ip_config_6, is_up, is_up); + + for (iter = priv->vpn_configs_6; iter; iter = iter->next) + nm_ip6_config_intersect(iter->data, priv->ext_ip_config_6, is_up, is_up, 0); + + if (is_up && priv->ipv6ll_has + && !nm_ip6_config_lookup_address(priv->ext_ip_config_6, &priv->ipv6ll_addr)) + priv->ipv6ll_has = FALSE; + } + + /* Remove parts from ext_ip_config_6 to only contain the information that + * was configured externally -- we already have the same configuration from + * internal origins. */ + if (priv->con_ip_config_6) { + nm_ip6_config_subtract(priv->ext_ip_config_6, + priv->con_ip_config_6, + default_route_metric_penalty_get(self, AF_INET6)); + } + if (applied_config_get_current(&priv->ac_ip6_config)) { + nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6, + applied_config_get_current(&priv->ac_ip6_config), + default_route_metric_penalty_get(self, AF_INET6)); + } + if (applied_config_get_current(&priv->dhcp6.ip6_config)) { + nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6, + applied_config_get_current(&priv->dhcp6.ip6_config), + default_route_metric_penalty_get(self, AF_INET6)); + } + if (applied_config_get_current(&priv->dev2_ip_config_6)) { + nm_ip_config_subtract((NMIPConfig *) priv->ext_ip_config_6, + applied_config_get_current(&priv->dev2_ip_config_6), + default_route_metric_penalty_get(self, AF_INET6)); + } + for (iter = priv->vpn_configs_6; iter; iter = iter->next) + nm_ip6_config_subtract(priv->ext_ip_config_6, iter->data, 0); + } + } + + return TRUE; } static void -update_ip_config (NMDevice *self, int addr_family) +update_ip_config(NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - if (addr_family == AF_INET) - priv->update_ip_config_completed_v4 = TRUE; - else - priv->update_ip_config_completed_v6 = TRUE; + if (addr_family == AF_INET) + priv->update_ip_config_completed_v4 = TRUE; + else + priv->update_ip_config_completed_v6 = TRUE; - if (update_ext_ip_config (self, addr_family, TRUE)) { - if (addr_family == AF_INET) { - if (priv->ext_ip_config_4) - ip_config_merge_and_apply (self, AF_INET, FALSE); - } else { - if (priv->ext_ip6_config_captured) - ip_config_merge_and_apply (self, AF_INET6, FALSE); - } - } + if (update_ext_ip_config(self, addr_family, TRUE)) { + if (addr_family == AF_INET) { + if (priv->ext_ip_config_4) + ip_config_merge_and_apply(self, AF_INET, FALSE); + } else { + if (priv->ext_ip6_config_captured) + ip_config_merge_and_apply(self, AF_INET6, FALSE); + } + } } void -nm_device_capture_initial_config (NMDevice *self) +nm_device_capture_initial_config(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->update_ip_config_completed_v4) - update_ip_config (self, AF_INET); - if (!priv->update_ip_config_completed_v6) - update_ip_config (self, AF_INET6); + if (!priv->update_ip_config_completed_v4) + update_ip_config(self, AF_INET); + if (!priv->update_ip_config_completed_v6) + update_ip_config(self, AF_INET6); } static gboolean -queued_ip_config_change (NMDevice *self, int addr_family) -{ - NMDevicePrivate *priv; - const gboolean IS_IPv4 = (addr_family == AF_INET); - - g_return_val_if_fail (NM_IS_DEVICE (self), G_SOURCE_REMOVE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - /* Wait for any queued state changes */ - if (priv->queued_state.id) - return G_SOURCE_CONTINUE; - - /* If a commit is scheduled, this function would potentially interfere with - * it changing IP configurations before they are applied. Postpone the - * update in such case. - */ - if ( priv->activation_source_id_x[IS_IPv4] != 0 - && priv->activation_source_func_x[IS_IPv4] == activate_stage5_ip_config_result_x[IS_IPv4]) - return G_SOURCE_CONTINUE; - - priv->queued_ip_config_id_x[IS_IPv4] = 0; - - update_ip_config (self, addr_family); - - if (!IS_IPv4) { - /* Check whether we need to complete waiting for link-local. - * We are also called from an idle handler, so no problem doing state transitions - * now. */ - linklocal6_check_complete (self); - } - - if (!IS_IPv4) { - NMPlatform *platform; - GSList *dad6_failed_addrs, *iter; - const NMPlatformLink *pllink; - - dad6_failed_addrs = g_steal_pointer (&priv->dad6_failed_addrs); - - if ( priv->state > NM_DEVICE_STATE_DISCONNECTED - && priv->state < NM_DEVICE_STATE_DEACTIVATING - && priv->ifindex > 0 - && !nm_device_sys_iface_state_is_external (self) - && (platform = nm_device_get_platform (self)) - && (pllink = nm_platform_link_get (platform, priv->ifindex)) - && (pllink->n_ifi_flags & IFF_UP)) { - gboolean need_ipv6ll = FALSE; - NMNDiscConfigMap ndisc_config_changed = NM_NDISC_CONFIG_NONE; - - /* Handle DAD failures */ - for (iter = dad6_failed_addrs; iter; iter = iter->next) { - const NMPObject *obj = iter->data; - const NMPlatformIP6Address *addr; - - if (!nm_ndisc_dad_addr_is_fail_candidate (platform, obj)) - continue; - - addr = NMP_OBJECT_CAST_IP6_ADDRESS (obj); - - _LOGI (LOGD_IP6, "ipv6: duplicate address check failed for the %s address", - nm_platform_ip6_address_to_string (addr, NULL, 0)); - - if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) - need_ipv6ll = TRUE; - else if (priv->ndisc) - ndisc_config_changed |= nm_ndisc_dad_failed (priv->ndisc, &addr->address, FALSE); - } - - if (ndisc_config_changed != NM_NDISC_CONFIG_NONE) - nm_ndisc_emit_config_change (priv->ndisc, ndisc_config_changed); - - /* If no IPv6 link-local address exists but other addresses do then we - * must add the LL address to remain conformant with RFC 3513 chapter 2.1 - * ("Addressing Model"): "All interfaces are required to have at least - * one link-local unicast address". - */ - if ( priv->ip_config_6 - && nm_ip6_config_get_num_addresses (priv->ip_config_6)) - need_ipv6ll = TRUE; - if (need_ipv6ll) - check_and_add_ipv6ll_addr (self); - } - - g_slist_free_full (dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); - } - - if (!IS_IPv4) { - /* Check if DAD is still pending */ - if ( priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF - && priv->dad6_ip6_config - && priv->ext_ip6_config_captured - && !nm_ip6_config_has_any_dad_pending (priv->ext_ip6_config_captured, - priv->dad6_ip6_config)) { - _LOGD (LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated"); - g_clear_object (&priv->dad6_ip6_config); - _set_ip_state (self, addr_family, NM_DEVICE_IP_STATE_DONE); - check_ip_state (self, FALSE, TRUE); - if (priv->rt6_temporary_not_available) - nm_device_activate_schedule_ip_config_result (self, AF_INET6, NULL); - } - } - - set_unmanaged_external_down (self, TRUE); - - return G_SOURCE_REMOVE; +queued_ip_config_change(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv; + const gboolean IS_IPv4 = (addr_family == AF_INET); + + g_return_val_if_fail(NM_IS_DEVICE(self), G_SOURCE_REMOVE); + + priv = NM_DEVICE_GET_PRIVATE(self); + + /* Wait for any queued state changes */ + if (priv->queued_state.id) + return G_SOURCE_CONTINUE; + + /* If a commit is scheduled, this function would potentially interfere with + * it changing IP configurations before they are applied. Postpone the + * update in such case. + */ + if (priv->activation_source_id_x[IS_IPv4] != 0 + && priv->activation_source_func_x[IS_IPv4] == activate_stage5_ip_config_result_x[IS_IPv4]) + return G_SOURCE_CONTINUE; + + priv->queued_ip_config_id_x[IS_IPv4] = 0; + + update_ip_config(self, addr_family); + + if (!IS_IPv4) { + /* Check whether we need to complete waiting for link-local. + * We are also called from an idle handler, so no problem doing state transitions + * now. */ + linklocal6_check_complete(self); + } + + if (!IS_IPv4) { + NMPlatform * platform; + GSList * dad6_failed_addrs, *iter; + const NMPlatformLink *pllink; + + dad6_failed_addrs = g_steal_pointer(&priv->dad6_failed_addrs); + + if (priv->state > NM_DEVICE_STATE_DISCONNECTED && priv->state < NM_DEVICE_STATE_DEACTIVATING + && priv->ifindex > 0 && !nm_device_sys_iface_state_is_external(self) + && (platform = nm_device_get_platform(self)) + && (pllink = nm_platform_link_get(platform, priv->ifindex)) + && (pllink->n_ifi_flags & IFF_UP)) { + gboolean need_ipv6ll = FALSE; + NMNDiscConfigMap ndisc_config_changed = NM_NDISC_CONFIG_NONE; + + /* Handle DAD failures */ + for (iter = dad6_failed_addrs; iter; iter = iter->next) { + const NMPObject * obj = iter->data; + const NMPlatformIP6Address *addr; + + if (!nm_ndisc_dad_addr_is_fail_candidate(platform, obj)) + continue; + + addr = NMP_OBJECT_CAST_IP6_ADDRESS(obj); + + _LOGI(LOGD_IP6, + "ipv6: duplicate address check failed for the %s address", + nm_platform_ip6_address_to_string(addr, NULL, 0)); + + if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) + need_ipv6ll = TRUE; + else if (priv->ndisc) + ndisc_config_changed |= nm_ndisc_dad_failed(priv->ndisc, &addr->address, FALSE); + } + + if (ndisc_config_changed != NM_NDISC_CONFIG_NONE) + nm_ndisc_emit_config_change(priv->ndisc, ndisc_config_changed); + + /* If no IPv6 link-local address exists but other addresses do then we + * must add the LL address to remain conformant with RFC 3513 chapter 2.1 + * ("Addressing Model"): "All interfaces are required to have at least + * one link-local unicast address". + */ + if (priv->ip_config_6 && nm_ip6_config_get_num_addresses(priv->ip_config_6)) + need_ipv6ll = TRUE; + if (need_ipv6ll) + check_and_add_ipv6ll_addr(self); + } + + g_slist_free_full(dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + } + + if (!IS_IPv4) { + /* Check if DAD is still pending */ + if (priv->ip_state_6 == NM_DEVICE_IP_STATE_CONF && priv->dad6_ip6_config + && priv->ext_ip6_config_captured + && !nm_ip6_config_has_any_dad_pending(priv->ext_ip6_config_captured, + priv->dad6_ip6_config)) { + _LOGD(LOGD_DEVICE | LOGD_IP6, "IPv6 DAD terminated"); + g_clear_object(&priv->dad6_ip6_config); + _set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_DONE); + check_ip_state(self, FALSE, TRUE); + if (priv->rt6_temporary_not_available) + nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); + } + } + + set_unmanaged_external_down(self, TRUE); + + return G_SOURCE_REMOVE; } static gboolean -queued_ip4_config_change (gpointer user_data) +queued_ip4_config_change(gpointer user_data) { - return queued_ip_config_change (user_data, AF_INET); + return queued_ip_config_change(user_data, AF_INET); } static gboolean -queued_ip6_config_change (gpointer user_data) +queued_ip6_config_change(gpointer user_data) { - return queued_ip_config_change (user_data, AF_INET6); + return queued_ip_config_change(user_data, AF_INET6); } static void -device_ipx_changed (NMPlatform *platform, - int obj_type_i, - int ifindex, - gconstpointer platform_object, - int change_type_i, - NMDevice *self) -{ - const NMPObjectType obj_type = obj_type_i; - const NMPlatformSignalChangeType change_type = change_type_i; - NMDevicePrivate *priv; - const NMPlatformIP6Address *addr; - - if (nm_device_get_ip_ifindex (self) != ifindex) - return; - - if (!nm_device_is_real (self)) - return; - - if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - /* ignore all platform signals until the link is initialized in platform. */ - return; - } - - priv = NM_DEVICE_GET_PRIVATE (self); - - switch (obj_type) { - case NMP_OBJECT_TYPE_IP4_ADDRESS: - case NMP_OBJECT_TYPE_IP4_ROUTE: - if (!priv->queued_ip_config_id_4) { - priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); - _LOGD (LOGD_DEVICE, "queued IP4 config change"); - } - break; - case NMP_OBJECT_TYPE_IP6_ADDRESS: - addr = platform_object; - - if ( priv->state > NM_DEVICE_STATE_DISCONNECTED - && priv->state < NM_DEVICE_STATE_DEACTIVATING - && nm_ndisc_dad_addr_is_fail_candidate_event (change_type, addr)) { - priv->dad6_failed_addrs = g_slist_prepend (priv->dad6_failed_addrs, - (gpointer) nmp_object_ref (NMP_OBJECT_UP_CAST (addr))); - } - - /* fall-through */ - case NMP_OBJECT_TYPE_IP6_ROUTE: - if (!priv->queued_ip_config_id_6) { - priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); - _LOGD (LOGD_DEVICE, "queued IP6 config change"); - } - break; - default: - g_return_if_reached (); - } +device_ipx_changed(NMPlatform * platform, + int obj_type_i, + int ifindex, + gconstpointer platform_object, + int change_type_i, + NMDevice * self) +{ + const NMPObjectType obj_type = obj_type_i; + const NMPlatformSignalChangeType change_type = change_type_i; + NMDevicePrivate * priv; + const NMPlatformIP6Address * addr; + + if (nm_device_get_ip_ifindex(self) != ifindex) + return; + + if (!nm_device_is_real(self)) + return; + + if (nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) { + /* ignore all platform signals until the link is initialized in platform. */ + return; + } + + priv = NM_DEVICE_GET_PRIVATE(self); + + switch (obj_type) { + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP4_ROUTE: + if (!priv->queued_ip_config_id_4) { + priv->queued_ip_config_id_4 = g_idle_add(queued_ip4_config_change, self); + _LOGD(LOGD_DEVICE, "queued IP4 config change"); + } + break; + case NMP_OBJECT_TYPE_IP6_ADDRESS: + addr = platform_object; + + if (priv->state > NM_DEVICE_STATE_DISCONNECTED && priv->state < NM_DEVICE_STATE_DEACTIVATING + && nm_ndisc_dad_addr_is_fail_candidate_event(change_type, addr)) { + priv->dad6_failed_addrs = + g_slist_prepend(priv->dad6_failed_addrs, + (gpointer) nmp_object_ref(NMP_OBJECT_UP_CAST(addr))); + } + + /* fall-through */ + case NMP_OBJECT_TYPE_IP6_ROUTE: + if (!priv->queued_ip_config_id_6) { + priv->queued_ip_config_id_6 = g_idle_add(queued_ip6_config_change, self); + _LOGD(LOGD_DEVICE, "queued IP6 config change"); + } + break; + default: + g_return_if_reached(); + } } /*****************************************************************************/ -NM_UTILS_FLAGS2STR_DEFINE (nm_unmanaged_flags2str, NMUnmanagedFlags, - NM_UTILS_FLAGS2STR (NM_UNMANAGED_SLEEPING, "sleeping"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_QUITTING, "quitting"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_PARENT, "parent"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_TYPE, "by-type"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_PLATFORM_INIT, "platform-init"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_EXPLICIT, "user-explicit"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_DEFAULT, "by-default"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_SETTINGS, "user-settings"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_CONF, "user-conf"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_UDEV, "user-udev"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_EXTERNAL_DOWN, "external-down"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_IS_SLAVE, "is-slave"), -); +NM_UTILS_FLAGS2STR_DEFINE(nm_unmanaged_flags2str, + NMUnmanagedFlags, + NM_UTILS_FLAGS2STR(NM_UNMANAGED_SLEEPING, "sleeping"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_QUITTING, "quitting"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_PARENT, "parent"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_BY_TYPE, "by-type"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_PLATFORM_INIT, "platform-init"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_EXPLICIT, "user-explicit"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_BY_DEFAULT, "by-default"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_SETTINGS, "user-settings"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_CONF, "user-conf"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_UDEV, "user-udev"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_EXTERNAL_DOWN, "external-down"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_IS_SLAVE, "is-slave"), ); static const char * -_unmanaged_flags2str (NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, gsize len) +_unmanaged_flags2str(NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, gsize len) { - char buf2[512]; - char *b; - char *tmp, *tmp2; - gsize l; + char buf2[512]; + char *b; + char *tmp, *tmp2; + gsize l; - nm_utils_to_string_buffer_init (&buf, &len); - if (!len) - return buf; + nm_utils_to_string_buffer_init(&buf, &len); + if (!len) + return buf; - b = buf; + b = buf; - mask |= flags; + mask |= flags; - nm_unmanaged_flags2str (flags, b, len); - l = strlen (b); - b += l; - len -= l; + nm_unmanaged_flags2str(flags, b, len); + l = strlen(b); + b += l; + len -= l; - nm_unmanaged_flags2str (mask & ~flags, buf2, sizeof (buf2)); - if (buf2[0]) { - gboolean add_separator = l > 0; + nm_unmanaged_flags2str(mask & ~flags, buf2, sizeof(buf2)); + if (buf2[0]) { + gboolean add_separator = l > 0; - tmp = buf2; - while (TRUE) { - if (add_separator) - nm_utils_strbuf_append_c (&b, &len, ','); - add_separator = TRUE; + tmp = buf2; + while (TRUE) { + if (add_separator) + nm_utils_strbuf_append_c(&b, &len, ','); + add_separator = TRUE; - tmp2 = strchr (tmp, ','); - if (tmp2) - tmp2[0] = '\0'; + tmp2 = strchr(tmp, ','); + if (tmp2) + tmp2[0] = '\0'; - nm_utils_strbuf_append_c (&b, &len, '!'); - nm_utils_strbuf_append_str (&b, &len, tmp); - if (!tmp2) - break; + nm_utils_strbuf_append_c(&b, &len, '!'); + nm_utils_strbuf_append_str(&b, &len, tmp); + if (!tmp2) + break; - tmp = &tmp2[1]; - } - } + tmp = &tmp2[1]; + } + } - return buf; + return buf; } static gboolean _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean for_user_request) { - /* Evaluate the managed state based on the unmanaged flags. - * - * Some flags are authoritative, meaning they always cause - * the device to be unmanaged (e.g. @NM_UNMANAGED_PLATFORM_INIT). - * - * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_UDEV - * is ignored once NM_UNMANAGED_USER_EXPLICIT is set. The idea is that - * the flag from the configuration has no effect once the user explicitly - * touches the unmanaged flags. */ - - if (for_user_request) { - - /* @for_user_request can make the result only ~more~ managed. - * If the flags already indicate a managed state for a non-user-request, - * then it is also managed for an explicit user-request. - * - * Effectively, this check is redundant, as the code below already - * already ensures that. Still, express this invariant explicitly here. */ - if (_get_managed_by_flags (flags, mask, FALSE)) - return TRUE; - - /* A for-user-request, is effectively the same as pretending - * that user-explicit flag is cleared. */ - mask |= NM_UNMANAGED_USER_EXPLICIT; - flags &= ~NM_UNMANAGED_USER_EXPLICIT; - } - - if ( NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_SETTINGS) - && !NM_FLAGS_ANY (flags, NM_UNMANAGED_USER_SETTINGS)) { - /* NM_UNMANAGED_USER_SETTINGS can only explicitly unmanage a device. It cannot - * *manage* it. Having NM_UNMANAGED_USER_SETTINGS explicitly not set, is the - * same as having it not set at all. */ - mask &= ~NM_UNMANAGED_USER_SETTINGS; - } - - if (NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_UDEV)) { - /* configuration from udev or nm-config overwrites the by-default flag - * which is based on the device type. - * configuration from udev overwrites external-down */ - flags &= ~( NM_UNMANAGED_BY_DEFAULT - | NM_UNMANAGED_EXTERNAL_DOWN); - } - - if (NM_FLAGS_ANY (mask, NM_UNMANAGED_USER_CONF)) { - /* configuration from NetworkManager.conf overwrites the by-default flag - * which is based on the device type. - * It also overwrites the udev configuration and external-down */ - flags &= ~( NM_UNMANAGED_BY_DEFAULT - | NM_UNMANAGED_USER_UDEV - | NM_UNMANAGED_EXTERNAL_DOWN); - } - - if ( NM_FLAGS_HAS (mask, NM_UNMANAGED_IS_SLAVE) - && !NM_FLAGS_HAS (flags, NM_UNMANAGED_IS_SLAVE)) { - /* for an enslaved device, by-default doesn't matter */ - flags &= ~NM_UNMANAGED_BY_DEFAULT; - } - - if (NM_FLAGS_HAS (mask, NM_UNMANAGED_USER_EXPLICIT)) { - /* if the device is managed by user-decision, certain other flags - * are ignored. */ - flags &= ~( NM_UNMANAGED_BY_DEFAULT - | NM_UNMANAGED_USER_UDEV - | NM_UNMANAGED_USER_CONF - | NM_UNMANAGED_EXTERNAL_DOWN); - } - - return flags == NM_UNMANAGED_NONE; + /* Evaluate the managed state based on the unmanaged flags. + * + * Some flags are authoritative, meaning they always cause + * the device to be unmanaged (e.g. @NM_UNMANAGED_PLATFORM_INIT). + * + * OTOH, some flags can be overwritten. For example NM_UNMANAGED_USER_UDEV + * is ignored once NM_UNMANAGED_USER_EXPLICIT is set. The idea is that + * the flag from the configuration has no effect once the user explicitly + * touches the unmanaged flags. */ + + if (for_user_request) { + /* @for_user_request can make the result only ~more~ managed. + * If the flags already indicate a managed state for a non-user-request, + * then it is also managed for an explicit user-request. + * + * Effectively, this check is redundant, as the code below already + * already ensures that. Still, express this invariant explicitly here. */ + if (_get_managed_by_flags(flags, mask, FALSE)) + return TRUE; + + /* A for-user-request, is effectively the same as pretending + * that user-explicit flag is cleared. */ + mask |= NM_UNMANAGED_USER_EXPLICIT; + flags &= ~NM_UNMANAGED_USER_EXPLICIT; + } + + if (NM_FLAGS_ANY(mask, NM_UNMANAGED_USER_SETTINGS) + && !NM_FLAGS_ANY(flags, NM_UNMANAGED_USER_SETTINGS)) { + /* NM_UNMANAGED_USER_SETTINGS can only explicitly unmanage a device. It cannot + * *manage* it. Having NM_UNMANAGED_USER_SETTINGS explicitly not set, is the + * same as having it not set at all. */ + mask &= ~NM_UNMANAGED_USER_SETTINGS; + } + + if (NM_FLAGS_ANY(mask, NM_UNMANAGED_USER_UDEV)) { + /* configuration from udev or nm-config overwrites the by-default flag + * which is based on the device type. + * configuration from udev overwrites external-down */ + flags &= ~(NM_UNMANAGED_BY_DEFAULT | NM_UNMANAGED_EXTERNAL_DOWN); + } + + if (NM_FLAGS_ANY(mask, NM_UNMANAGED_USER_CONF)) { + /* configuration from NetworkManager.conf overwrites the by-default flag + * which is based on the device type. + * It also overwrites the udev configuration and external-down */ + flags &= ~(NM_UNMANAGED_BY_DEFAULT | NM_UNMANAGED_USER_UDEV | NM_UNMANAGED_EXTERNAL_DOWN); + } + + if (NM_FLAGS_HAS(mask, NM_UNMANAGED_IS_SLAVE) && !NM_FLAGS_HAS(flags, NM_UNMANAGED_IS_SLAVE)) { + /* for an enslaved device, by-default doesn't matter */ + flags &= ~NM_UNMANAGED_BY_DEFAULT; + } + + if (NM_FLAGS_HAS(mask, NM_UNMANAGED_USER_EXPLICIT)) { + /* if the device is managed by user-decision, certain other flags + * are ignored. */ + flags &= ~(NM_UNMANAGED_BY_DEFAULT | NM_UNMANAGED_USER_UDEV | NM_UNMANAGED_USER_CONF + | NM_UNMANAGED_EXTERNAL_DOWN); + } + + return flags == NM_UNMANAGED_NONE; } /** @@ -14457,20 +14674,20 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo * Returns: %TRUE if the device is unmanaged because of the flags. */ gboolean -nm_device_get_managed (NMDevice *self, gboolean for_user_request) +nm_device_get_managed(NMDevice *self, gboolean for_user_request) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - if (!nm_device_is_real (self)) { - /* a unrealized device is always considered unmanaged. */ - return FALSE; - } + if (!nm_device_is_real(self)) { + /* a unrealized device is always considered unmanaged. */ + return FALSE; + } - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - return _get_managed_by_flags (priv->unmanaged_flags, priv->unmanaged_mask, for_user_request); + return _get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, for_user_request); } /** @@ -14483,12 +14700,12 @@ nm_device_get_managed (NMDevice *self, gboolean for_user_request) * Returns: the flags of the device ( & @flag) */ NMUnmanagedFlags -nm_device_get_unmanaged_mask (NMDevice *self, NMUnmanagedFlags flag) +nm_device_get_unmanaged_mask(NMDevice *self, NMUnmanagedFlags flag) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE); - g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_UNMANAGED_NONE); + g_return_val_if_fail(flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE); - return NM_DEVICE_GET_PRIVATE (self)->unmanaged_mask & flag; + return NM_DEVICE_GET_PRIVATE(self)->unmanaged_mask & flag; } /** @@ -14501,12 +14718,12 @@ nm_device_get_unmanaged_mask (NMDevice *self, NMUnmanagedFlags flag) * Returns: the flags of the device ( & @flag) */ NMUnmanagedFlags -nm_device_get_unmanaged_flags (NMDevice *self, NMUnmanagedFlags flag) +nm_device_get_unmanaged_flags(NMDevice *self, NMUnmanagedFlags flag) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_UNMANAGED_NONE); - g_return_val_if_fail (flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_UNMANAGED_NONE); + g_return_val_if_fail(flag != NM_UNMANAGED_NONE, NM_UNMANAGED_NONE); - return NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags & flag; + return NM_DEVICE_GET_PRIVATE(self)->unmanaged_flags & flag; } /** @@ -14527,122 +14744,119 @@ nm_device_get_unmanaged_flags (NMDevice *self, NMUnmanagedFlags flag) * Set the unmanaged flags of the device. **/ static void -_set_unmanaged_flags (NMDevice *self, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op, - gboolean allow_state_transition, - gboolean now, - NMDeviceStateReason reason) -{ - NMDevicePrivate *priv; - gboolean was_managed, transition_state; - NMUnmanagedFlags old_flags, old_mask; - NMDeviceState new_state; - const char *operation = NULL; - char str1[512]; - char str2[512]; - gboolean do_notify_has_pending_actions = FALSE; - gboolean had_pending_actions = FALSE; - - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (flags); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (!priv->real) - allow_state_transition = FALSE; - was_managed = allow_state_transition && nm_device_get_managed (self, FALSE); - - if ( NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_PLATFORM_INIT) - && NM_FLAGS_HAS (flags, NM_UNMANAGED_PLATFORM_INIT) - && NM_IN_SET (set_op, NM_UNMAN_FLAG_OP_SET_MANAGED)) { - /* we are clearing the platform-init flags. This triggers additional actions. */ - if (!NM_FLAGS_HAS (flags, NM_UNMANAGED_USER_SETTINGS)) { - gboolean unmanaged; - - unmanaged = nm_device_spec_match_list (self, - nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings)); - nm_device_set_unmanaged_flags (self, - NM_UNMANAGED_USER_SETTINGS, - !!unmanaged); - } - - /* trigger an initial update of IP configuration. */ - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_4)); - nm_assert_se (!nm_clear_g_source (&priv->queued_ip_config_id_6)); - priv->queued_ip_config_id_4 = g_idle_add (queued_ip4_config_change, self); - priv->queued_ip_config_id_6 = g_idle_add (queued_ip6_config_change, self); - - if (!priv->pending_actions) { - do_notify_has_pending_actions = TRUE; - had_pending_actions = nm_device_has_pending_action (self); - } - } - - old_flags = priv->unmanaged_flags; - old_mask = priv->unmanaged_mask; - - switch (set_op) { - case NM_UNMAN_FLAG_OP_FORGET: - priv->unmanaged_mask &= ~flags; - priv->unmanaged_flags &= ~flags; - operation = "forget"; - break; - case NM_UNMAN_FLAG_OP_SET_UNMANAGED: - priv->unmanaged_mask |= flags; - priv->unmanaged_flags |= flags; - operation = "set-unmanaged"; - break; - case NM_UNMAN_FLAG_OP_SET_MANAGED: - priv->unmanaged_mask |= flags; - priv->unmanaged_flags &= ~flags; - operation = "set-managed"; - break; - default: - g_return_if_reached (); - } - - if ( old_flags == priv->unmanaged_flags - && old_mask == priv->unmanaged_mask) - return; - - transition_state = allow_state_transition - && was_managed != nm_device_get_managed (self, FALSE) - && ( was_managed - || ( !was_managed - && nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED)); - - _LOGD (LOGD_DEVICE, "unmanaged: flags set to [%s%s0x%0x/0x%x/%s%s], %s [%s=0x%0x]%s%s%s)", - _unmanaged_flags2str (priv->unmanaged_flags, priv->unmanaged_mask, str1, sizeof (str1)), \ - (priv->unmanaged_flags | priv->unmanaged_mask) ? "=" : "", \ - (guint) priv->unmanaged_flags, \ - (guint) priv->unmanaged_mask, \ - (_get_managed_by_flags (priv->unmanaged_flags, priv->unmanaged_mask, FALSE) \ - ? "managed" \ - : (_get_managed_by_flags (priv->unmanaged_flags, priv->unmanaged_mask, TRUE) \ - ? "manageable" \ - : "unmanaged")), - priv->real ? "" : "/unrealized", - operation, - nm_unmanaged_flags2str (flags, str2, sizeof (str2)), - flags, - NM_PRINT_FMT_QUOTED (allow_state_transition, - ", reason ", - reason_to_string_a (reason), - transition_state ? ", transition-state" : "", - "")); - - if ( do_notify_has_pending_actions - && had_pending_actions != nm_device_has_pending_action (self)) - _notify (self, PROP_HAS_PENDING_ACTION); - - if (transition_state) { - new_state = was_managed ? NM_DEVICE_STATE_UNMANAGED : NM_DEVICE_STATE_UNAVAILABLE; - if (now) - nm_device_state_changed (self, new_state, reason); - else - nm_device_queue_state (self, new_state, reason); - } +_set_unmanaged_flags(NMDevice * self, + NMUnmanagedFlags flags, + NMUnmanFlagOp set_op, + gboolean allow_state_transition, + gboolean now, + NMDeviceStateReason reason) +{ + NMDevicePrivate *priv; + gboolean was_managed, transition_state; + NMUnmanagedFlags old_flags, old_mask; + NMDeviceState new_state; + const char * operation = NULL; + char str1[512]; + char str2[512]; + gboolean do_notify_has_pending_actions = FALSE; + gboolean had_pending_actions = FALSE; + + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(flags); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (!priv->real) + allow_state_transition = FALSE; + was_managed = allow_state_transition && nm_device_get_managed(self, FALSE); + + if (NM_FLAGS_HAS(priv->unmanaged_flags, NM_UNMANAGED_PLATFORM_INIT) + && NM_FLAGS_HAS(flags, NM_UNMANAGED_PLATFORM_INIT) + && NM_IN_SET(set_op, NM_UNMAN_FLAG_OP_SET_MANAGED)) { + /* we are clearing the platform-init flags. This triggers additional actions. */ + if (!NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_SETTINGS)) { + gboolean unmanaged; + + unmanaged = nm_device_spec_match_list( + self, + nm_settings_get_unmanaged_specs(NM_DEVICE_GET_PRIVATE(self)->settings)); + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_USER_SETTINGS, !!unmanaged); + } + + /* trigger an initial update of IP configuration. */ + nm_assert_se(!nm_clear_g_source(&priv->queued_ip_config_id_4)); + nm_assert_se(!nm_clear_g_source(&priv->queued_ip_config_id_6)); + priv->queued_ip_config_id_4 = g_idle_add(queued_ip4_config_change, self); + priv->queued_ip_config_id_6 = g_idle_add(queued_ip6_config_change, self); + + if (!priv->pending_actions) { + do_notify_has_pending_actions = TRUE; + had_pending_actions = nm_device_has_pending_action(self); + } + } + + old_flags = priv->unmanaged_flags; + old_mask = priv->unmanaged_mask; + + switch (set_op) { + case NM_UNMAN_FLAG_OP_FORGET: + priv->unmanaged_mask &= ~flags; + priv->unmanaged_flags &= ~flags; + operation = "forget"; + break; + case NM_UNMAN_FLAG_OP_SET_UNMANAGED: + priv->unmanaged_mask |= flags; + priv->unmanaged_flags |= flags; + operation = "set-unmanaged"; + break; + case NM_UNMAN_FLAG_OP_SET_MANAGED: + priv->unmanaged_mask |= flags; + priv->unmanaged_flags &= ~flags; + operation = "set-managed"; + break; + default: + g_return_if_reached(); + } + + if (old_flags == priv->unmanaged_flags && old_mask == priv->unmanaged_mask) + return; + + transition_state = + allow_state_transition && was_managed != nm_device_get_managed(self, FALSE) + && (was_managed + || (!was_managed && nm_device_get_state(self) == NM_DEVICE_STATE_UNMANAGED)); + + _LOGD(LOGD_DEVICE, + "unmanaged: flags set to [%s%s0x%0x/0x%x/%s%s], %s [%s=0x%0x]%s%s%s)", + _unmanaged_flags2str(priv->unmanaged_flags, priv->unmanaged_mask, str1, sizeof(str1)), + (priv->unmanaged_flags | priv->unmanaged_mask) ? "=" : "", + (guint) priv->unmanaged_flags, + (guint) priv->unmanaged_mask, + (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, FALSE) + ? "managed" + : (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, TRUE) + ? "manageable" + : "unmanaged")), + priv->real ? "" : "/unrealized", + operation, + nm_unmanaged_flags2str(flags, str2, sizeof(str2)), + flags, + NM_PRINT_FMT_QUOTED(allow_state_transition, + ", reason ", + reason_to_string_a(reason), + transition_state ? ", transition-state" : "", + "")); + + if (do_notify_has_pending_actions && had_pending_actions != nm_device_has_pending_action(self)) + _notify(self, PROP_HAS_PENDING_ACTION); + + if (transition_state) { + new_state = was_managed ? NM_DEVICE_STATE_UNMANAGED : NM_DEVICE_STATE_UNAVAILABLE; + if (now) + nm_device_state_changed(self, new_state, reason); + else + nm_device_queue_state(self, new_state, reason); + } } /** @@ -14655,11 +14869,9 @@ _set_unmanaged_flags (NMDevice *self, * Set the unmanaged flags of the device (does not trigger a state change). **/ void -nm_device_set_unmanaged_flags (NMDevice *self, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op) +nm_device_set_unmanaged_flags(NMDevice *self, NMUnmanagedFlags flags, NMUnmanFlagOp set_op) { - _set_unmanaged_flags (self, flags, set_op, FALSE, FALSE, NM_DEVICE_STATE_REASON_NONE); + _set_unmanaged_flags(self, flags, set_op, FALSE, FALSE, NM_DEVICE_STATE_REASON_NONE); } /** @@ -14675,21 +14887,21 @@ nm_device_set_unmanaged_flags (NMDevice *self, * Set the unmanaged flags of the device and possibly trigger a state change. **/ void -nm_device_set_unmanaged_by_flags (NMDevice *self, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op, - NMDeviceStateReason reason) +nm_device_set_unmanaged_by_flags(NMDevice * self, + NMUnmanagedFlags flags, + NMUnmanFlagOp set_op, + NMDeviceStateReason reason) { - _set_unmanaged_flags (self, flags, set_op, TRUE, TRUE, reason); + _set_unmanaged_flags(self, flags, set_op, TRUE, TRUE, reason); } void -nm_device_set_unmanaged_by_flags_queue (NMDevice *self, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op, - NMDeviceStateReason reason) +nm_device_set_unmanaged_by_flags_queue(NMDevice * self, + NMUnmanagedFlags flags, + NMUnmanFlagOp set_op, + NMDeviceStateReason reason) { - _set_unmanaged_flags (self, flags, set_op, TRUE, FALSE, reason); + _set_unmanaged_flags(self, flags, set_op, TRUE, FALSE, reason); } /** @@ -14699,378 +14911,389 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self, * or user configuration. */ gboolean -nm_device_check_unrealized_device_managed (NMDevice *self) +nm_device_check_unrealized_device_managed(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (!nm_device_is_real (self)); + nm_assert(!nm_device_is_real(self)); - if (!nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, - self, - TRUE, - TRUE)) - return FALSE; + if (!nm_config_data_get_device_config_boolean(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, + self, + TRUE, + TRUE)) + return FALSE; - if (nm_device_spec_match_list (self, nm_settings_get_unmanaged_specs (priv->settings))) - return FALSE; + if (nm_device_spec_match_list(self, nm_settings_get_unmanaged_specs(priv->settings))) + return FALSE; - return TRUE; + return TRUE; } void -nm_device_set_unmanaged_by_user_settings (NMDevice *self) +nm_device_set_unmanaged_by_user_settings(NMDevice *self) { - gboolean unmanaged; + gboolean unmanaged; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - /* the device is already unmanaged due to platform-init. - * - * We want to delay evaluating the device spec, because it will freeze - * the permanent MAC address. That should not be done, before the platform - * link is fully initialized (via UDEV). - * - * Note that when clearing NM_UNMANAGED_PLATFORM_INIT, we will re-evaluate - * whether the device is unmanaged by user-settings. */ - return; - } + if (nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) { + /* the device is already unmanaged due to platform-init. + * + * We want to delay evaluating the device spec, because it will freeze + * the permanent MAC address. That should not be done, before the platform + * link is fully initialized (via UDEV). + * + * Note that when clearing NM_UNMANAGED_PLATFORM_INIT, we will re-evaluate + * whether the device is unmanaged by user-settings. */ + return; + } - unmanaged = nm_device_spec_match_list (self, - nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings)); + unmanaged = nm_device_spec_match_list( + self, + nm_settings_get_unmanaged_specs(NM_DEVICE_GET_PRIVATE(self)->settings)); - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_USER_SETTINGS, - !!unmanaged, - unmanaged - ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED - : NM_DEVICE_STATE_REASON_NOW_MANAGED); + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_USER_SETTINGS, + !!unmanaged, + unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED + : NM_DEVICE_STATE_REASON_NOW_MANAGED); } void -nm_device_set_unmanaged_by_user_udev (NMDevice *self) +nm_device_set_unmanaged_by_user_udev(NMDevice *self) { - int ifindex; - gboolean platform_unmanaged = FALSE; + int ifindex; + gboolean platform_unmanaged = FALSE; - ifindex = self->_priv->ifindex; + ifindex = self->_priv->ifindex; - if ( ifindex <= 0 - || !nm_platform_link_get_unmanaged (nm_device_get_platform (self), ifindex, &platform_unmanaged)) - return; + if (ifindex <= 0 + || !nm_platform_link_get_unmanaged(nm_device_get_platform(self), + ifindex, + &platform_unmanaged)) + return; - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_USER_UDEV, - platform_unmanaged, - NM_DEVICE_STATE_REASON_USER_REQUESTED); + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_USER_UDEV, + platform_unmanaged, + NM_DEVICE_STATE_REASON_USER_REQUESTED); } void -nm_device_set_unmanaged_by_user_conf (NMDevice *self) -{ - gboolean value; - NMUnmanFlagOp set_op; - - value = nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, - self, - -1, - TRUE); - switch (value) { - case TRUE: - set_op = NM_UNMAN_FLAG_OP_SET_MANAGED; - break; - case FALSE: - set_op = NM_UNMAN_FLAG_OP_SET_UNMANAGED; - break; - default: - set_op = NM_UNMAN_FLAG_OP_FORGET; - break; - } - - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_USER_CONF, - set_op, - NM_DEVICE_STATE_REASON_USER_REQUESTED); +nm_device_set_unmanaged_by_user_conf(NMDevice *self) +{ + gboolean value; + NMUnmanFlagOp set_op; + + value = nm_config_data_get_device_config_boolean(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, + self, + -1, + TRUE); + switch (value) { + case TRUE: + set_op = NM_UNMAN_FLAG_OP_SET_MANAGED; + break; + case FALSE: + set_op = NM_UNMAN_FLAG_OP_SET_UNMANAGED; + break; + default: + set_op = NM_UNMAN_FLAG_OP_FORGET; + break; + } + + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_USER_CONF, + set_op, + NM_DEVICE_STATE_REASON_USER_REQUESTED); } void -nm_device_set_unmanaged_by_quitting (NMDevice *self) +nm_device_set_unmanaged_by_quitting(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean need_deactivate = nm_device_is_activating (self) || - priv->state == NM_DEVICE_STATE_ACTIVATED; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean need_deactivate = + nm_device_is_activating(self) || priv->state == NM_DEVICE_STATE_ACTIVATED; - /* It's OK to block here because we're quitting */ - if (need_deactivate) - _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NOW_UNMANAGED, TRUE); + /* It's OK to block here because we're quitting */ + if (need_deactivate) + _set_state_full(self, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_NOW_UNMANAGED, + TRUE); - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_QUITTING, - TRUE, - need_deactivate ? NM_DEVICE_STATE_REASON_REMOVED - : NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + nm_device_set_unmanaged_by_flags(self, + NM_UNMANAGED_QUITTING, + TRUE, + need_deactivate ? NM_DEVICE_STATE_REASON_REMOVED + : NM_DEVICE_STATE_REASON_NOW_UNMANAGED); } /*****************************************************************************/ void -nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) +nm_device_set_dhcp_anycast_address(NMDevice *self, const char *addr) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(!addr || nm_utils_hwaddr_valid(addr, ETH_ALEN)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - g_free (priv->dhcp_anycast_address); - priv->dhcp_anycast_address = g_strdup (addr); + g_free(priv->dhcp_anycast_address); + priv->dhcp_anycast_address = g_strdup(addr); } void -nm_device_reapply_settings_immediately (NMDevice *self) +nm_device_reapply_settings_immediately(NMDevice *self) { - NMConnection *applied_connection; - NMSettingsConnection *settings_connection; - NMDeviceState state; - NMSettingConnection *s_con_settings; - NMSettingConnection *s_con_applied; - const char *zone; - NMMetered metered; - guint64 version_id; + NMConnection * applied_connection; + NMSettingsConnection *settings_connection; + NMDeviceState state; + NMSettingConnection * s_con_settings; + NMSettingConnection * s_con_applied; + const char * zone; + NMMetered metered; + guint64 version_id; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - state = nm_device_get_state (self); - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state > NM_DEVICE_STATE_ACTIVATED) - return; + state = nm_device_get_state(self); + if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_ACTIVATED) + return; - applied_connection = nm_device_get_applied_connection (self); - settings_connection = nm_device_get_settings_connection (self); + applied_connection = nm_device_get_applied_connection(self); + settings_connection = nm_device_get_settings_connection(self); - if (!nm_settings_connection_has_unmodified_applied_connection (settings_connection, - applied_connection, - NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)) - return; + if (!nm_settings_connection_has_unmodified_applied_connection( + settings_connection, + applied_connection, + NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)) + return; - s_con_settings = nm_connection_get_setting_connection (nm_settings_connection_get_connection (settings_connection)); - s_con_applied = nm_connection_get_setting_connection (applied_connection); + s_con_settings = nm_connection_get_setting_connection( + nm_settings_connection_get_connection(settings_connection)); + s_con_applied = nm_connection_get_setting_connection(applied_connection); - if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)), - nm_setting_connection_get_zone (s_con_applied)) != 0) { + if (!nm_streq0((zone = nm_setting_connection_get_zone(s_con_settings)), + nm_setting_connection_get_zone(s_con_applied))) { + version_id = nm_active_connection_version_id_bump( + (NMActiveConnection *) self->_priv->act_request.obj); + _LOGD(LOGD_DEVICE, + "reapply setting: zone = %s%s%s (version-id %llu)", + NM_PRINT_FMT_QUOTE_STRING(zone), + (unsigned long long) version_id); - version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->_priv->act_request.obj); - _LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id %llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (unsigned long long) version_id); + g_object_set(G_OBJECT(s_con_applied), NM_SETTING_CONNECTION_ZONE, zone, NULL); - g_object_set (G_OBJECT (s_con_applied), - NM_SETTING_CONNECTION_ZONE, zone, - NULL); + nm_device_update_firewall_zone(self); + } - nm_device_update_firewall_zone (self); - } + if ((metered = nm_setting_connection_get_metered(s_con_settings)) + != nm_setting_connection_get_metered(s_con_applied)) { + version_id = nm_active_connection_version_id_bump( + (NMActiveConnection *) self->_priv->act_request.obj); + _LOGD(LOGD_DEVICE, + "reapply setting: metered = %d (version-id %llu)", + (int) metered, + (unsigned long long) version_id); - if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) { + g_object_set(G_OBJECT(s_con_applied), NM_SETTING_CONNECTION_METERED, metered, NULL); - version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->_priv->act_request.obj); - _LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id %llu)", (int) metered, (unsigned long long) version_id); - - g_object_set (G_OBJECT (s_con_applied), - NM_SETTING_CONNECTION_METERED, metered, - NULL); - - nm_device_update_metered (self); - } + nm_device_update_metered(self); + } } void -nm_device_update_firewall_zone (NMDevice *self) +nm_device_update_firewall_zone(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if ( priv->fw_state >= FIREWALL_STATE_INITIALIZED - && !nm_device_sys_iface_state_is_external (self)) - fw_change_zone (self); + if (priv->fw_state >= FIREWALL_STATE_INITIALIZED + && !nm_device_sys_iface_state_is_external(self)) + fw_change_zone(self); } void -nm_device_update_metered (NMDevice *self) +nm_device_update_metered(NMDevice *self) { #define NM_METERED_INVALID ((NMMetered) -1) - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingConnection *setting; - NMMetered conn_value, value = NM_METERED_INVALID; - NMConnection *connection = NULL; - NMDeviceState state; - - g_return_if_fail (NM_IS_DEVICE (self)); - - state = nm_device_get_state (self); - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state > NM_DEVICE_STATE_ACTIVATED) - value = NM_METERED_UNKNOWN; - - if (value == NM_METERED_INVALID) { - connection = nm_device_get_applied_connection (self); - if (connection) { - setting = nm_connection_get_setting_connection (connection); - if (setting) { - conn_value = nm_setting_connection_get_metered (setting); - if (conn_value != NM_METERED_UNKNOWN) - value = conn_value; - } - } - } - - if ( value == NM_METERED_INVALID - && NM_DEVICE_GET_CLASS (self)->get_guessed_metered - && NM_DEVICE_GET_CLASS (self)->get_guessed_metered (self)) - value = NM_METERED_GUESS_YES; - - /* Try to guess a value using the metered flag in IP configuration */ - if (value == NM_METERED_INVALID) { - if ( priv->ip_config_4 - && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE - && nm_ip4_config_get_metered (priv->ip_config_4)) - value = NM_METERED_GUESS_YES; - } - - /* Otherwise look at connection type. For Bluetooth, we look at the type of - * Bluetooth sharing: for PANU/DUN (where we are receiving internet from - * another device) we set GUESS_YES; for NAP (where we are sharing internet - * to another device) we set GUESS_NO. We ignore WiMAX here as it’s no - * longer supported by NetworkManager. */ - if ( value == NM_METERED_INVALID - && nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { - - if (_nm_connection_get_setting_bluetooth_for_nap (connection)) { - /* NAP types are not metered, but other types are. */ - value = NM_METERED_GUESS_NO; - } else - value = NM_METERED_GUESS_YES; - } - - if (value == NM_METERED_INVALID) { - if ( nm_connection_is_type (connection, NM_SETTING_GSM_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_CDMA_SETTING_NAME)) - value = NM_METERED_GUESS_YES; - else - value = NM_METERED_GUESS_NO; - } - - if (value != priv->metered) { - _LOGD (LOGD_DEVICE, "set metered value %d", value); - priv->metered = value; - _notify (self, PROP_METERED); - } + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingConnection *setting; + NMMetered conn_value, value = NM_METERED_INVALID; + NMConnection * connection = NULL; + NMDeviceState state; + + g_return_if_fail(NM_IS_DEVICE(self)); + + state = nm_device_get_state(self); + if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_ACTIVATED) + value = NM_METERED_UNKNOWN; + + if (value == NM_METERED_INVALID) { + connection = nm_device_get_applied_connection(self); + if (connection) { + setting = nm_connection_get_setting_connection(connection); + if (setting) { + conn_value = nm_setting_connection_get_metered(setting); + if (conn_value != NM_METERED_UNKNOWN) + value = conn_value; + } + } + } + + if (value == NM_METERED_INVALID && NM_DEVICE_GET_CLASS(self)->get_guessed_metered + && NM_DEVICE_GET_CLASS(self)->get_guessed_metered(self)) + value = NM_METERED_GUESS_YES; + + /* Try to guess a value using the metered flag in IP configuration */ + if (value == NM_METERED_INVALID) { + if (priv->ip_config_4 && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE + && nm_ip4_config_get_metered(priv->ip_config_4)) + value = NM_METERED_GUESS_YES; + } + + /* Otherwise, look at connection type. For Bluetooth, we look at the type of + * Bluetooth sharing: for PANU/DUN (where we are receiving internet from + * another device) we set GUESS_YES; for NAP (where we are sharing internet + * to another device) we set GUESS_NO. We ignore WiMAX here as it’s no + * longer supported by NetworkManager. */ + if (value == NM_METERED_INVALID + && nm_connection_is_type(connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { + if (_nm_connection_get_setting_bluetooth_for_nap(connection)) { + /* NAP types are not metered, but other types are. */ + value = NM_METERED_GUESS_NO; + } else + value = NM_METERED_GUESS_YES; + } + + if (value == NM_METERED_INVALID) { + if (nm_connection_is_type(connection, NM_SETTING_GSM_SETTING_NAME) + || nm_connection_is_type(connection, NM_SETTING_CDMA_SETTING_NAME)) + value = NM_METERED_GUESS_YES; + else + value = NM_METERED_GUESS_NO; + } + + if (value != priv->metered) { + _LOGD(LOGD_DEVICE, "set metered value %d", value); + priv->metered = value; + _notify(self, PROP_METERED); + } } static NMDeviceCheckDevAvailableFlags -_device_check_dev_available_flags_from_con (NMDeviceCheckConAvailableFlags con_flags) +_device_check_dev_available_flags_from_con(NMDeviceCheckConAvailableFlags con_flags) { - NMDeviceCheckDevAvailableFlags dev_flags; + NMDeviceCheckDevAvailableFlags dev_flags; - dev_flags = NM_DEVICE_CHECK_DEV_AVAILABLE_NONE; + dev_flags = NM_DEVICE_CHECK_DEV_AVAILABLE_NONE; - if (NM_FLAGS_HAS (con_flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)) - dev_flags |= _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER; + if (NM_FLAGS_HAS(con_flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER)) + dev_flags |= _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER; - return dev_flags; + return dev_flags; } static gboolean -_nm_device_check_connection_available (NMDevice *self, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) -{ - NMDeviceState state; - GError *local = NULL; - - /* an unrealized software device is always available, hardware devices never. */ - if (!nm_device_is_real (self)) { - if (nm_device_is_software (self)) { - if (!nm_device_check_connection_compatible (self, connection, - error ? &local : NULL)) { - if (error) { - g_return_val_if_fail (local, FALSE); - nm_utils_error_set (error, - local->domain == NM_UTILS_ERROR - ? local->code - : NM_UTILS_ERROR_UNKNOWN, - "profile is not compatible with software device (%s)", - local->message); - g_error_free (local); - } - return FALSE; - } - return TRUE; - } - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "hardware device is not realized"); - return FALSE; - } - - state = nm_device_get_state (self); - if (state < NM_DEVICE_STATE_UNMANAGED) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is in unknown state"); - return FALSE; - } - if (state < NM_DEVICE_STATE_UNAVAILABLE) { - if (nm_device_get_managed (self, FALSE)) { - /* device is managed, both for user-requests and non-user-requests alike. */ - } else { - if (!nm_device_get_managed (self, TRUE)) { - /* device is strictly unmanaged by authoritative unmanaged reasons. */ - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is strictly unmanaged"); - return FALSE; - } - if (!NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED)) { - /* device could be managed for an explict user-request, but this is not such a request. */ - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is currently unmanaged"); - return FALSE; - } - } - } - if ( state < NM_DEVICE_STATE_DISCONNECTED - && !nm_device_is_software (self)) { - if (!nm_device_is_available (self, _device_check_dev_available_flags_from_con (flags))) { - if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device is not available"); - } else { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device is not available for internal request"); - } - return FALSE; - } - } - - if (!nm_device_check_connection_compatible (self, connection, - error ? &local : NULL)) { - if (error) { - nm_utils_error_set (error, - local->domain == NM_UTILS_ERROR - ? local->code - : NM_UTILS_ERROR_UNKNOWN, - "profile is not compatible with device (%s)", - local->message); - g_error_free (local); - } - return FALSE; - } - - return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object, error); +_nm_device_check_connection_available(NMDevice * self, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) +{ + NMDeviceState state; + GError * local = NULL; + + /* an unrealized software device is always available, hardware devices never. */ + if (!nm_device_is_real(self)) { + if (nm_device_is_software(self)) { + if (!nm_device_check_connection_compatible(self, connection, error ? &local : NULL)) { + if (error) { + g_return_val_if_fail(local, FALSE); + nm_utils_error_set(error, + local->domain == NM_UTILS_ERROR ? local->code + : NM_UTILS_ERROR_UNKNOWN, + "profile is not compatible with software device (%s)", + local->message); + g_error_free(local); + } + return FALSE; + } + return TRUE; + } + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, + "hardware device is not realized"); + return FALSE; + } + + state = nm_device_get_state(self); + if (state < NM_DEVICE_STATE_UNMANAGED) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, + "device is in unknown state"); + return FALSE; + } + if (state < NM_DEVICE_STATE_UNAVAILABLE) { + if (nm_device_get_managed(self, FALSE)) { + /* device is managed, both for user-requests and non-user-requests alike. */ + } else { + if (!nm_device_get_managed(self, TRUE)) { + /* device is strictly unmanaged by authoritative unmanaged reasons. */ + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, + "device is strictly unmanaged"); + return FALSE; + } + if (!NM_FLAGS_HAS(flags, + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED)) { + /* device could be managed for an explict user-request, but this is not such a request. */ + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, + "device is currently unmanaged"); + return FALSE; + } + } + } + if (state < NM_DEVICE_STATE_DISCONNECTED && !nm_device_is_software(self)) { + if (!nm_device_is_available(self, _device_check_dev_available_flags_from_con(flags))) { + if (NM_FLAGS_HAS(flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device is not available"); + } else { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device is not available for internal request"); + } + return FALSE; + } + } + + if (!nm_device_check_connection_compatible(self, connection, error ? &local : NULL)) { + if (error) { + nm_utils_error_set(error, + local->domain == NM_UTILS_ERROR ? local->code + : NM_UTILS_ERROR_UNKNOWN, + "profile is not compatible with device (%s)", + local->message); + g_error_free(local); + } + return FALSE; + } + + return NM_DEVICE_GET_CLASS(self)->check_connection_available(self, + connection, + flags, + specific_object, + error); } /** @@ -15090,147 +15313,148 @@ _nm_device_check_connection_available (NMDevice *self, * Returns: %TRUE if @connection can be activated on @self */ gboolean -nm_device_check_connection_available (NMDevice *self, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) +nm_device_check_connection_available(NMDevice * self, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) { - gboolean available; + gboolean available; - available = _nm_device_check_connection_available (self, connection, flags, specific_object, error); + available = + _nm_device_check_connection_available(self, connection, flags, specific_object, error); #if NM_MORE_ASSERTS >= 2 - { - /* The meaning of the flags is so that *adding* a flag relaxes a condition, thus making - * the device *more* available. Assert against that requirement by testing all the flags. */ - NMDeviceCheckConAvailableFlags i, j, k; - gboolean available_all[NM_DEVICE_CHECK_CON_AVAILABLE_ALL + 1] = { FALSE }; - - for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) - available_all[i] = _nm_device_check_connection_available (self, connection, i, specific_object, NULL); - - for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) { - for (j = 1; j <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; j <<= 1) { - if (NM_FLAGS_ANY (i, j)) { - k = i & ~j; - nm_assert ( available_all[i] == available_all[k] - || available_all[i]); - } - } - } - } + { + /* The meaning of the flags is so that *adding* a flag relaxes a condition, thus making + * the device *more* available. Assert against that requirement by testing all the flags. */ + NMDeviceCheckConAvailableFlags i, j, k; + gboolean available_all[NM_DEVICE_CHECK_CON_AVAILABLE_ALL + 1] = {FALSE}; + + for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) + available_all[i] = + _nm_device_check_connection_available(self, connection, i, specific_object, NULL); + + for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) { + for (j = 1; j <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; j <<= 1) { + if (NM_FLAGS_ANY(i, j)) { + k = i & ~j; + nm_assert(available_all[i] == available_all[k] || available_all[i]); + } + } + } + } #endif - return available; + return available; } static gboolean -available_connections_del_all (NMDevice *self) +available_connections_del_all(NMDevice *self) { - if (g_hash_table_size (self->_priv->available_connections) == 0) - return FALSE; - g_hash_table_remove_all (self->_priv->available_connections); - return TRUE; + if (g_hash_table_size(self->_priv->available_connections) == 0) + return FALSE; + g_hash_table_remove_all(self->_priv->available_connections); + return TRUE; } static gboolean -available_connections_add (NMDevice *self, NMSettingsConnection *sett_conn) +available_connections_add(NMDevice *self, NMSettingsConnection *sett_conn) { - return g_hash_table_add (self->_priv->available_connections, g_object_ref (sett_conn)); + return g_hash_table_add(self->_priv->available_connections, g_object_ref(sett_conn)); } static gboolean -available_connections_del (NMDevice *self, NMSettingsConnection *sett_conn) +available_connections_del(NMDevice *self, NMSettingsConnection *sett_conn) { - return g_hash_table_remove (self->_priv->available_connections, sett_conn); + return g_hash_table_remove(self->_priv->available_connections, sett_conn); } static gboolean -check_connection_available (NMDevice *self, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - /* Connections which require a network connection are not available when - * the device has no carrier, even with ignore-carrer=TRUE. - */ - if ( priv->carrier - || !connection_requires_carrier (connection)) - return TRUE; - - if ( NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER) - && priv->carrier_wait_id != 0) { - /* The device has no carrier though the connection requires it. - * - * If we are still waiting for carrier, the connection is available - * for an explicit user-request. */ - return TRUE; - } - - /* master types are always available even without carrier. - * Making connection non-available would un-enslave slaves which - * is not desired. */ - if (nm_device_is_master (self)) - return TRUE; - - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no carrier"); - return FALSE; +check_connection_available(NMDevice * self, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + /* Connections which require a network connection are not available when + * the device has no carrier, even with ignore-carrer=TRUE. + */ + if (priv->carrier || !connection_requires_carrier(connection)) + return TRUE; + + if (NM_FLAGS_HAS(flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER) + && priv->carrier_wait_id != 0) { + /* The device has no carrier though the connection requires it. + * + * If we are still waiting for carrier, the connection is available + * for an explicit user-request. */ + return TRUE; + } + + /* master types are always available even without carrier. + * Making connection non-available would un-enslave slaves which + * is not desired. */ + if (nm_device_is_master(self)) + return TRUE; + + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has no carrier"); + return FALSE; } void -nm_device_recheck_available_connections (NMDevice *self) -{ - NMDevicePrivate *priv; - NMSettingsConnection *const*connections; - gboolean changed = FALSE; - GHashTableIter h_iter; - NMSettingsConnection *sett_conn; - guint i; - gs_unref_hashtable GHashTable *prune_list = NULL; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE(self); - - if (g_hash_table_size (priv->available_connections) > 0) { - prune_list = g_hash_table_new (nm_direct_hash, NULL); - g_hash_table_iter_init (&h_iter, priv->available_connections); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &sett_conn, NULL)) - g_hash_table_add (prune_list, sett_conn); - } - - connections = nm_settings_get_connections (priv->settings, NULL); - for (i = 0; connections[i]; i++) { - sett_conn = connections[i]; - - if (nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), - NM_DEVICE_CHECK_CON_AVAILABLE_NONE, - NULL, - NULL)) { - if (available_connections_add (self, sett_conn)) - changed = TRUE; - if (prune_list) - g_hash_table_remove (prune_list, sett_conn); - } - } - - if (prune_list) { - g_hash_table_iter_init (&h_iter, prune_list); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &sett_conn, NULL)) { - if (available_connections_del (self, sett_conn)) - changed = TRUE; - } - } - - if (changed) - _notify (self, PROP_AVAILABLE_CONNECTIONS); - available_connections_check_delete_unrealized (self); +nm_device_recheck_available_connections(NMDevice *self) +{ + NMDevicePrivate * priv; + NMSettingsConnection *const *connections; + gboolean changed = FALSE; + GHashTableIter h_iter; + NMSettingsConnection * sett_conn; + guint i; + gs_unref_hashtable GHashTable *prune_list = NULL; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (g_hash_table_size(priv->available_connections) > 0) { + prune_list = g_hash_table_new(nm_direct_hash, NULL); + g_hash_table_iter_init(&h_iter, priv->available_connections); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &sett_conn, NULL)) + g_hash_table_add(prune_list, sett_conn); + } + + connections = nm_settings_get_connections(priv->settings, NULL); + for (i = 0; connections[i]; i++) { + sett_conn = connections[i]; + + if (nm_device_check_connection_available(self, + nm_settings_connection_get_connection(sett_conn), + NM_DEVICE_CHECK_CON_AVAILABLE_NONE, + NULL, + NULL)) { + if (available_connections_add(self, sett_conn)) + changed = TRUE; + if (prune_list) + g_hash_table_remove(prune_list, sett_conn); + } + } + + if (prune_list) { + g_hash_table_iter_init(&h_iter, prune_list); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &sett_conn, NULL)) { + if (available_connections_del(self, sett_conn)) + changed = TRUE; + } + } + + if (changed) + _notify(self, PROP_AVAILABLE_CONNECTIONS); + available_connections_check_delete_unrealized(self); } /** @@ -15245,99 +15469,104 @@ nm_device_recheck_available_connections (NMDevice *self) * Returns: the #NMSettingsConnection or %NULL (setting an @error) */ NMSettingsConnection * -nm_device_get_best_connection (NMDevice *self, - const char *specific_object, - GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *sett_conn = NULL; - NMSettingsConnection *candidate; - guint64 best_timestamp = 0; - GHashTableIter iter; - - g_hash_table_iter_init (&iter, priv->available_connections); - while (g_hash_table_iter_next (&iter, (gpointer) &candidate, NULL)) { - guint64 candidate_timestamp = 0; - - /* If a specific object is given, only include connections that are - * compatible with it. - */ - if ( specific_object /* << Optimization: we know that the connection is available without @specific_object. */ - && !nm_device_check_connection_available (self, - nm_settings_connection_get_connection (candidate), - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - specific_object, - NULL)) - continue; - - nm_settings_connection_get_timestamp (candidate, &candidate_timestamp); - if (!sett_conn || (candidate_timestamp > best_timestamp)) { - sett_conn = candidate; - best_timestamp = candidate_timestamp; - } - } - - if (!sett_conn) { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "The device '%s' has no connections available for activation.", - nm_device_get_iface (self)); - } - - return sett_conn; +nm_device_get_best_connection(NMDevice *self, const char *specific_object, GError **error) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *candidate; + guint64 best_timestamp = 0; + GHashTableIter iter; + + g_hash_table_iter_init(&iter, priv->available_connections); + while (g_hash_table_iter_next(&iter, (gpointer) &candidate, NULL)) { + guint64 candidate_timestamp = 0; + + /* If a specific object is given, only include connections that are + * compatible with it. + */ + if (specific_object /* << Optimization: we know that the connection is available without @specific_object. */ + && !nm_device_check_connection_available( + self, + nm_settings_connection_get_connection(candidate), + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, + specific_object, + NULL)) + continue; + + nm_settings_connection_get_timestamp(candidate, &candidate_timestamp); + if (!sett_conn || (candidate_timestamp > best_timestamp)) { + sett_conn = candidate; + best_timestamp = candidate_timestamp; + } + } + + if (!sett_conn) { + g_set_error(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_CONNECTION, + "The device '%s' has no connections available for activation.", + nm_device_get_iface(self)); + } + + return sett_conn; } static void -cp_connection_added_or_updated (NMDevice *self, NMSettingsConnection *sett_conn) +cp_connection_added_or_updated(NMDevice *self, NMSettingsConnection *sett_conn) { - gboolean changed; + gboolean changed; - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); + g_return_if_fail(NM_IS_DEVICE(self)); + g_return_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn)); - if (nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, - NULL)) - changed = available_connections_add (self, sett_conn); - else - changed = available_connections_del (self, sett_conn); + if (nm_device_check_connection_available(self, + nm_settings_connection_get_connection(sett_conn), + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, + NULL, + NULL)) + changed = available_connections_add(self, sett_conn); + else + changed = available_connections_del(self, sett_conn); - if (changed) { - _notify (self, PROP_AVAILABLE_CONNECTIONS); - available_connections_check_delete_unrealized (self); - } + if (changed) { + _notify(self, PROP_AVAILABLE_CONNECTIONS); + available_connections_check_delete_unrealized(self); + } } static void -cp_connection_added (NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +cp_connection_added(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) { - cp_connection_added_or_updated (user_data, sett_conn); + cp_connection_added_or_updated(user_data, sett_conn); } static void -cp_connection_updated (NMSettings *settings, NMSettingsConnection *sett_conn, guint update_reason_u, gpointer user_data) +cp_connection_updated(NMSettings * settings, + NMSettingsConnection *sett_conn, + guint update_reason_u, + gpointer user_data) { - cp_connection_added_or_updated (user_data, sett_conn); + cp_connection_added_or_updated(user_data, sett_conn); } static void -cp_connection_removed (NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +cp_connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) { - NMDevice *self = user_data; + NMDevice *self = user_data; - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail(NM_IS_DEVICE(self)); - if (available_connections_del (self, sett_conn)) { - _notify (self, PROP_AVAILABLE_CONNECTIONS); - available_connections_check_delete_unrealized (self); - } + if (available_connections_del(self, sett_conn)) { + _notify(self, PROP_AVAILABLE_CONNECTIONS); + available_connections_check_delete_unrealized(self); + } } gboolean -nm_device_supports_vlans (NMDevice *self) +nm_device_supports_vlans(NMDevice *self) { - return nm_platform_link_supports_vlans (nm_device_get_platform (self), nm_device_get_ifindex (self)); + return nm_platform_link_supports_vlans(nm_device_get_platform(self), + nm_device_get_ifindex(self)); } /** @@ -15356,39 +15585,43 @@ nm_device_supports_vlans (NMDevice *self) * a second time. */ gboolean -nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending) +nm_device_add_pending_action(NMDevice *self, const char *action, gboolean assert_not_yet_pending) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GSList *iter; - guint count = 0; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + GSList * iter; + guint count = 0; - g_return_val_if_fail (action, FALSE); + g_return_val_if_fail(action, FALSE); - /* Check if the action is already pending. Cannot add duplicate actions */ - for (iter = priv->pending_actions; iter; iter = iter->next) { - if (!strcmp (action, iter->data)) { - if (assert_not_yet_pending) { - _LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending", - count + g_slist_length (iter), action); - g_return_val_if_reached (FALSE); - } else { - _LOGT (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)", - count + g_slist_length (iter), action); - } - return FALSE; - } - count++; - } + /* Check if the action is already pending. Cannot add duplicate actions */ + for (iter = priv->pending_actions; iter; iter = iter->next) { + if (nm_streq(action, iter->data)) { + if (assert_not_yet_pending) { + _LOGW(LOGD_DEVICE, + "add_pending_action (%d): '%s' already pending", + count + g_slist_length(iter), + action); + g_return_val_if_reached(FALSE); + } else { + _LOGT(LOGD_DEVICE, + "add_pending_action (%d): '%s' already pending (expected)", + count + g_slist_length(iter), + action); + } + return FALSE; + } + count++; + } - priv->pending_actions = g_slist_prepend (priv->pending_actions, (char *) action); - count++; + priv->pending_actions = g_slist_prepend(priv->pending_actions, (char *) action); + count++; - _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); + _LOGD(LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); - if (count == 1) - _notify (self, PROP_HAS_PENDING_ACTION); + if (count == 1) + _notify(self, PROP_HAS_PENDING_ACTION); - return TRUE; + return TRUE; } /** @@ -15404,198 +15637,195 @@ nm_device_add_pending_action (NMDevice *self, const char *action, gboolean asser * Returns: whether the @action was pending and is now removed. */ gboolean -nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending) -{ - NMDevicePrivate *priv; - GSList *iter, *next; - guint count = 0; - - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (action, FALSE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - for (iter = priv->pending_actions; iter; iter = next) { - next = iter->next; - if (!strcmp (action, iter->data)) { - _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'", - count + g_slist_length (iter->next), /* length excluding 'iter' */ - action); - priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); - if (priv->pending_actions == NULL) - _notify (self, PROP_HAS_PENDING_ACTION); - return TRUE; - } - count++; - } - - if (assert_is_pending) { - _LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action); - g_return_val_if_reached (FALSE); - } else - _LOGT (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action); - - return FALSE; +nm_device_remove_pending_action(NMDevice *self, const char *action, gboolean assert_is_pending) +{ + NMDevicePrivate *priv; + GSList * iter, *next; + guint count = 0; + + g_return_val_if_fail(self, FALSE); + g_return_val_if_fail(action, FALSE); + + priv = NM_DEVICE_GET_PRIVATE(self); + + for (iter = priv->pending_actions; iter; iter = next) { + next = iter->next; + if (nm_streq(action, iter->data)) { + _LOGD(LOGD_DEVICE, + "remove_pending_action (%d): '%s'", + count + g_slist_length(iter->next), /* length excluding 'iter' */ + action); + priv->pending_actions = g_slist_delete_link(priv->pending_actions, iter); + if (priv->pending_actions == NULL) + _notify(self, PROP_HAS_PENDING_ACTION); + return TRUE; + } + count++; + } + + if (assert_is_pending) { + _LOGW(LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action); + g_return_val_if_reached(FALSE); + } else + _LOGT(LOGD_DEVICE, + "remove_pending_action (%d): '%s' not pending (expected)", + count, + action); + + return FALSE; } const char * -nm_device_has_pending_action_reason (NMDevice *self) +nm_device_has_pending_action_reason(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->pending_actions) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( !priv->pending_actions->next - && nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED - && nm_streq (priv->pending_actions->data, NM_PENDING_ACTION_CARRIER_WAIT)) { - /* if the device is already in activated state, and the only reason - * why it appears still busy is "carrier-wait", then we are already complete. */ - return NULL; - } + if (priv->pending_actions) { + if (!priv->pending_actions->next && nm_device_get_state(self) == NM_DEVICE_STATE_ACTIVATED + && nm_streq(priv->pending_actions->data, NM_PENDING_ACTION_CARRIER_WAIT)) { + /* if the device is already in activated state, and the only reason + * why it appears still busy is "carrier-wait", then we are already complete. */ + return NULL; + } - return priv->pending_actions->data; - } + return priv->pending_actions->data; + } - if ( nm_device_is_real (self) - && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { - /* as long as the platform link is not yet initialized, we have a pending - * action. */ - return NM_PENDING_ACTION_LINK_INIT; - } + if (nm_device_is_real(self) + && nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT)) { + /* as long as the platform link is not yet initialized, we have a pending + * action. */ + return NM_PENDING_ACTION_LINK_INIT; + } - return NULL; + return NULL; } /*****************************************************************************/ static void -_cancel_activation (NMDevice *self) +_cancel_activation(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->fw_call) { - nm_firewall_manager_cancel_call (priv->fw_call); - nm_assert (!priv->fw_call); - priv->fw_call = NULL; - priv->fw_state = FIREWALL_STATE_INITIALIZED; - } + if (priv->fw_call) { + nm_firewall_manager_cancel_call(priv->fw_call); + nm_assert(!priv->fw_call); + priv->fw_call = NULL; + priv->fw_state = FIREWALL_STATE_INITIALIZED; + } - ip_check_gw_ping_cleanup (self); + ip_check_gw_ping_cleanup(self); - /* Break the activation chain */ - activation_source_clear (self, AF_INET); - activation_source_clear (self, AF_INET6); + /* Break the activation chain */ + activation_source_clear(self, AF_INET); + activation_source_clear(self, AF_INET6); } static void -_cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) +_cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - _cancel_activation (self); + _cancel_activation(self); - priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_INIT; + priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_INIT; - if (cleanup_type != CLEANUP_TYPE_KEEP) { - nm_manager_device_route_metric_clear (NM_MANAGER_GET, - nm_device_get_ip_ifindex (self)); - } + if (cleanup_type != CLEANUP_TYPE_KEEP) { + nm_manager_device_route_metric_clear(NM_MANAGER_GET, nm_device_get_ip_ifindex(self)); + } - if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE - && priv->fw_state >= FIREWALL_STATE_INITIALIZED - && priv->fw_mgr - && !nm_device_sys_iface_state_is_external (self)) { - nm_firewall_manager_remove_from_zone (priv->fw_mgr, - nm_device_get_ip_iface (self), - NULL, - NULL, - NULL); - } - priv->fw_state = FIREWALL_STATE_UNMANAGED; - g_clear_object (&priv->fw_mgr); + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE && priv->fw_state >= FIREWALL_STATE_INITIALIZED + && priv->fw_mgr && !nm_device_sys_iface_state_is_external(self)) { + nm_firewall_manager_remove_from_zone(priv->fw_mgr, + nm_device_get_ip_iface(self), + NULL, + NULL, + NULL); + } + priv->fw_state = FIREWALL_STATE_UNMANAGED; + g_clear_object(&priv->fw_mgr); - queued_state_clear (self); + queued_state_clear(self); - _cleanup_ip_pre (self, AF_INET, cleanup_type); - _cleanup_ip_pre (self, AF_INET6, cleanup_type); + nm_clear_pointer(&priv->shared_ip_handle, nm_netns_shared_ip_release); + + _cleanup_ip_pre(self, AF_INET, cleanup_type); + _cleanup_ip_pre(self, AF_INET6, cleanup_type); } static void -_cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - priv->v4_commit_first_time = TRUE; - priv->v6_commit_first_time = TRUE; - - priv->v4_route_table_initialized = FALSE; - priv->v6_route_table_initialized = FALSE; - - priv->v4_route_table_all_sync_before = FALSE; - priv->v6_route_table_all_sync_before = FALSE; - - priv->default_route_metric_penalty_ip4_has = FALSE; - priv->default_route_metric_penalty_ip6_has = FALSE; - - priv->linklocal6_dad_counter = 0; - - /* Clean up IP configs; this does not actually deconfigure the - * interface; the caller must flush routes and addresses explicitly. - */ - nm_device_set_ip_config (self, AF_INET, NULL, TRUE, NULL); - nm_device_set_ip_config (self, AF_INET6, NULL, TRUE, NULL); - g_clear_object (&priv->proxy_config); - g_clear_object (&priv->con_ip_config_4); - applied_config_clear (&priv->dev_ip_config_4); - applied_config_clear (&priv->dev2_ip_config_4); - g_clear_object (&priv->ext_ip_config_4); - g_clear_object (&priv->ip_config_4); - g_clear_object (&priv->con_ip_config_6); - applied_config_clear (&priv->ac_ip6_config); - g_clear_object (&priv->ext_ip_config_6); - g_clear_object (&priv->ext_ip6_config_captured); - applied_config_clear (&priv->dev2_ip_config_6); - g_clear_object (&priv->ip_config_6); - g_clear_object (&priv->dad6_ip6_config); - priv->ipv6ll_has = FALSE; - memset (&priv->ipv6ll_addr, 0, sizeof (priv->ipv6ll_addr)); - - nm_clear_pointer (&priv->rt6_temporary_not_available, g_hash_table_unref); - nm_clear_g_source (&priv->rt6_temporary_not_available_id); - - g_slist_free_full (priv->vpn_configs_4, g_object_unref); - priv->vpn_configs_4 = NULL; - g_slist_free_full (priv->vpn_configs_6, g_object_unref); - priv->vpn_configs_6 = NULL; - - /* We no longer accept the delegations. nm_device_set_ip_config(NULL) - * above disables them. */ - nm_assert (priv->needs_ip6_subnet == FALSE); - - if (priv->act_request.obj) { - nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request.obj), AF_INET, FALSE); - nm_clear_g_signal_handler (priv->act_request.obj, &priv->master_ready_id); - act_request_set (self, NULL); - } - - /* Clear legacy IPv4 address property */ - if (priv->ip4_address) { - priv->ip4_address = 0; - _notify (self, PROP_IP4_ADDRESS); - } - - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - /* Check if the device was deactivated, and if so, delete_link. - * Don't call delete_link synchronously because we are currently - * handling a state change -- which is not reentrant. */ - delete_on_deactivate_check_and_schedule (self, nm_device_get_ip_ifindex (self)); - } - - /* ip_iface should be cleared after flushing all routes and addresses, since - * those are identified by ip_iface, not by iface (which might be a tty - * or ATM device). - */ - _set_ip_ifindex (self, 0, NULL); +_cleanup_generic_post(NMDevice *self, CleanupType cleanup_type) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + priv->v4_commit_first_time = TRUE; + priv->v6_commit_first_time = TRUE; + + priv->v4_route_table_initialized = FALSE; + priv->v6_route_table_initialized = FALSE; + + priv->v4_route_table_all_sync_before = FALSE; + priv->v6_route_table_all_sync_before = FALSE; + + priv->default_route_metric_penalty_ip4_has = FALSE; + priv->default_route_metric_penalty_ip6_has = FALSE; + + priv->linklocal6_dad_counter = 0; + + /* Clean up IP configs; this does not actually deconfigure the + * interface; the caller must flush routes and addresses explicitly. + */ + nm_device_set_ip_config(self, AF_INET, NULL, TRUE, NULL); + nm_device_set_ip_config(self, AF_INET6, NULL, TRUE, NULL); + g_clear_object(&priv->proxy_config); + g_clear_object(&priv->con_ip_config_4); + applied_config_clear(&priv->dev_ip_config_4); + applied_config_clear(&priv->dev2_ip_config_4); + g_clear_object(&priv->ext_ip_config_4); + g_clear_object(&priv->ip_config_4); + g_clear_object(&priv->con_ip_config_6); + applied_config_clear(&priv->ac_ip6_config); + g_clear_object(&priv->ext_ip_config_6); + g_clear_object(&priv->ext_ip6_config_captured); + applied_config_clear(&priv->dev2_ip_config_6); + g_clear_object(&priv->ip_config_6); + g_clear_object(&priv->dad6_ip6_config); + priv->ipv6ll_has = FALSE; + memset(&priv->ipv6ll_addr, 0, sizeof(priv->ipv6ll_addr)); + + nm_clear_pointer(&priv->rt6_temporary_not_available, g_hash_table_unref); + nm_clear_g_source(&priv->rt6_temporary_not_available_id); + + g_slist_free_full(priv->vpn_configs_4, g_object_unref); + priv->vpn_configs_4 = NULL; + g_slist_free_full(priv->vpn_configs_6, g_object_unref); + priv->vpn_configs_6 = NULL; + + /* We no longer accept the delegations. nm_device_set_ip_config(NULL) + * above disables them. */ + nm_assert(priv->needs_ip6_subnet == FALSE); + + if (priv->act_request.obj) { + nm_active_connection_set_default(NM_ACTIVE_CONNECTION(priv->act_request.obj), + AF_INET, + FALSE); + nm_clear_g_signal_handler(priv->act_request.obj, &priv->master_ready_id); + act_request_set(self, NULL); + } + + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { + /* Check if the device was deactivated, and if so, delete_link. + * Don't call delete_link synchronously because we are currently + * handling a state change -- which is not reentrant. */ + delete_on_deactivate_check_and_schedule(self, nm_device_get_ip_ifindex(self)); + } + + /* ip_iface should be cleared after flushing all routes and addresses, since + * those are identified by ip_iface, not by iface (which might be a tty + * or ATM device). + */ + _set_ip_ifindex(self, 0, NULL); } /* @@ -15605,1418 +15835,1332 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) * */ static void -nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type) -{ - NMDevicePrivate *priv; - int ifindex; - - g_return_if_fail (NM_IS_DEVICE (self)); - - if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) - _LOGD (LOGD_DEVICE, "preparing device"); - else - _LOGD (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string_a (reason), reason); - - /* Save whether or not we tried IPv6 for later */ - priv = NM_DEVICE_GET_PRIVATE (self); - - _cleanup_generic_pre (self, cleanup_type); - - /* Turn off kernel IPv6 */ - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - set_disable_ipv6 (self, "1"); - nm_device_sysctl_ip_conf_set (self, AF_INET6, "use_tempaddr", "0"); - } - - /* Call device type-specific deactivation */ - if (NM_DEVICE_GET_CLASS (self)->deactivate) - NM_DEVICE_GET_CLASS (self)->deactivate (self); - - ifindex = nm_device_get_ip_ifindex (self); - - if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - /* master: release slaves */ - nm_device_master_release_slaves (self); - - /* Take out any entries in the routing table and any IP address the device had. */ - if (ifindex > 0) { - NMPlatform *platform = nm_device_get_platform (self); - NMUtilsIPv6IfaceId iid = { }; - - nm_platform_ip_route_flush (platform, AF_UNSPEC, ifindex); - nm_platform_ip_address_flush (platform, AF_UNSPEC, ifindex); - nm_platform_tfilter_sync (platform, ifindex, NULL); - nm_platform_qdisc_sync (platform, ifindex, NULL); - set_ipv6_token (self, iid, "::"); - } - } - - _routing_rules_sync (self, - cleanup_type == CLEANUP_TYPE_KEEP - ? NM_TERNARY_DEFAULT - : NM_TERNARY_FALSE); - - if (ifindex > 0) - nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), ifindex, NULL); - - /* slave: mark no longer enslaved */ - if ( priv->master - && priv->ifindex > 0 - && nm_platform_link_get_master (nm_device_get_platform (self), priv->ifindex) <= 0) - nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - - if (priv->lldp_listener) - nm_lldp_listener_stop (priv->lldp_listener); - - nm_device_update_metered (self); - - if (ifindex > 0) { - /* during device cleanup, we want to reset the MAC address of the device - * to the initial state. - * - * We certainly want to do that when reaching the UNMANAGED state... */ - if (nm_device_get_state (self) <= NM_DEVICE_STATE_UNMANAGED) - nm_device_hw_addr_reset (self, "unmanage"); - else { - /* for other device states (UNAVAILABLE, DISCONNECTED), allow the - * device to overwrite the reset behavior, so that Wi-Fi can set - * a randomized MAC address used during scanning. */ - NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self); - } - } - - priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; - priv->ip6_mtu = 0; - if (priv->mtu_initial || priv->ip6_mtu_initial) { - ifindex = nm_device_get_ip_ifindex (self); - - if ( ifindex > 0 - && cleanup_type == CLEANUP_TYPE_DECONFIGURE) { - _LOGT (LOGD_DEVICE, "mtu: reset device-mtu: %u, ipv6-mtu: %u, ifindex: %d", - (guint) priv->mtu_initial, (guint) priv->ip6_mtu_initial, ifindex); - if (priv->mtu_initial) { - nm_platform_link_set_mtu (nm_device_get_platform (self), ifindex, priv->mtu_initial); - priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_msec () + CARRIER_WAIT_TIME_AFTER_MTU_MS; - } - if (priv->ip6_mtu_initial) { - char sbuf[64]; - - nm_device_sysctl_ip_conf_set (self, AF_INET6, "mtu", - nm_sprintf_buf (sbuf, "%u", (unsigned) priv->ip6_mtu_initial)); - } - } - priv->mtu_initial = 0; - priv->ip6_mtu_initial = 0; - } - - _ethtool_state_reset (self); - - _cleanup_generic_post (self, cleanup_type); +nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type) +{ + NMDevicePrivate *priv; + int ifindex; + + g_return_if_fail(NM_IS_DEVICE(self)); + + if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) + _LOGD(LOGD_DEVICE, "preparing device"); + else + _LOGD(LOGD_DEVICE, + "deactivating device (reason '%s') [%d]", + reason_to_string_a(reason), + reason); + + /* Save whether or not we tried IPv6 for later */ + priv = NM_DEVICE_GET_PRIVATE(self); + + _cleanup_generic_pre(self, cleanup_type); + + /* Turn off kernel IPv6 */ + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { + set_disable_ipv6(self, "1"); + nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", "0"); + } + + /* Call device type-specific deactivation */ + if (NM_DEVICE_GET_CLASS(self)->deactivate) + NM_DEVICE_GET_CLASS(self)->deactivate(self); + + ifindex = nm_device_get_ip_ifindex(self); + + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { + /* master: release slaves */ + nm_device_master_release_slaves(self); + + /* Take out any entries in the routing table and any IP address the device had. */ + if (ifindex > 0) { + NMPlatform * platform = nm_device_get_platform(self); + NMUtilsIPv6IfaceId iid = {}; + + nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); + nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); + nm_platform_tfilter_sync(platform, ifindex, NULL); + nm_platform_qdisc_sync(platform, ifindex, NULL); + set_ipv6_token(self, iid, "::"); + } + } + + _routing_rules_sync(self, + cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE); + + if (ifindex > 0) + nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), ifindex, NULL); + + /* slave: mark no longer enslaved */ + if (priv->master && priv->ifindex > 0 + && nm_platform_link_get_master(nm_device_get_platform(self), priv->ifindex) <= 0) + nm_device_master_release_one_slave(priv->master, + self, + FALSE, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + + if (priv->lldp_listener) + nm_lldp_listener_stop(priv->lldp_listener); + + nm_device_update_metered(self); + + if (ifindex > 0) { + /* during device cleanup, we want to reset the MAC address of the device + * to the initial state. + * + * We certainly want to do that when reaching the UNMANAGED state... */ + if (nm_device_get_state(self) <= NM_DEVICE_STATE_UNMANAGED) + nm_device_hw_addr_reset(self, "unmanage"); + else { + /* for other device states (UNAVAILABLE, DISCONNECTED), allow the + * device to overwrite the reset behavior, so that Wi-Fi can set + * a randomized MAC address used during scanning. */ + NM_DEVICE_GET_CLASS(self)->deactivate_reset_hw_addr(self); + } + } + + priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; + priv->ip6_mtu = 0; + if (priv->mtu_initial || priv->ip6_mtu_initial) { + ifindex = nm_device_get_ip_ifindex(self); + + if (ifindex > 0 && cleanup_type == CLEANUP_TYPE_DECONFIGURE) { + _LOGT(LOGD_DEVICE, + "mtu: reset device-mtu: %u, ipv6-mtu: %u, ifindex: %d", + (guint) priv->mtu_initial, + (guint) priv->ip6_mtu_initial, + ifindex); + if (priv->mtu_initial) { + nm_platform_link_set_mtu(nm_device_get_platform(self), ifindex, priv->mtu_initial); + priv->carrier_wait_until_ms = + nm_utils_get_monotonic_timestamp_msec() + CARRIER_WAIT_TIME_AFTER_MTU_MS; + } + if (priv->ip6_mtu_initial) { + char sbuf[64]; + + nm_device_sysctl_ip_conf_set( + self, + AF_INET6, + "mtu", + nm_sprintf_buf(sbuf, "%u", (unsigned) priv->ip6_mtu_initial)); + } + } + priv->mtu_initial = 0; + priv->ip6_mtu_initial = 0; + } + + _ethtool_state_reset(self); + + _cleanup_generic_post(self, cleanup_type); } static void -deactivate_reset_hw_addr (NMDevice *self) +deactivate_reset_hw_addr(NMDevice *self) { - nm_device_hw_addr_reset (self, "deactivate"); + nm_device_hw_addr_reset(self, "deactivate"); } static char * -find_dhcp4_address (NMDevice *self) +find_dhcp4_address(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const NMPlatformIP4Address *a; - NMDedupMultiIter ipconf_iter; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const NMPlatformIP4Address *a; + NMDedupMultiIter ipconf_iter; - if (!priv->ip_config_4) - return NULL; + if (!priv->ip_config_4) + return NULL; - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, priv->ip_config_4, &a) { - if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP) - return nm_utils_inet4_ntop_dup (a->address); - } - return NULL; + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, priv->ip_config_4, &a) { + if (a->addr_source == NM_IP_CONFIG_SOURCE_DHCP) + return nm_utils_inet4_ntop_dup(a->address); + } + return NULL; } void -nm_device_spawn_iface_helper (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean configured = FALSE; - NMConnection *connection; - GError *error = NULL; - const char *method; - GPtrArray *argv; - gs_free char *dhcp4_address = NULL; - char *logging_backend; - NMUtilsStableType stable_type; - const char *stable_id; - - if (priv->state != NM_DEVICE_STATE_ACTIVATED) - return; - if (!nm_device_can_assume_connections (self)) - return; - - connection = nm_device_get_applied_connection (self); - - g_return_if_fail (connection); - - argv = g_ptr_array_sized_new (10); - g_ptr_array_set_free_func (argv, g_free); - - g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/nm-iface-helper")); - g_ptr_array_add (argv, g_strdup ("--ifname")); - g_ptr_array_add (argv, g_strdup (nm_device_get_ip_iface (self))); - g_ptr_array_add (argv, g_strdup ("--uuid")); - g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection))); - - stable_id = _get_stable_id (self, connection, &stable_type); - if (stable_type != NM_UTILS_STABLE_TYPE_UUID) { - g_ptr_array_add (argv, g_strdup ("--stable-id")); - g_ptr_array_add (argv, g_strdup_printf ("%d %s", (int) stable_type, stable_id)); - } - - logging_backend = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_LOGGING, - NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, - NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); - if (logging_backend) { - g_ptr_array_add (argv, g_strdup ("--logging-backend")); - g_ptr_array_add (argv, logging_backend); - } - - g_ptr_array_add (argv, g_strdup ("--log-level")); - g_ptr_array_add (argv, g_strdup (nm_logging_level_to_string ())); - - g_ptr_array_add (argv, g_strdup ("--log-domains")); - g_ptr_array_add (argv, g_strdup (nm_logging_domains_to_string ())); - - dhcp4_address = find_dhcp4_address (self); - - method = nm_device_get_effective_ip_config_method (self, AF_INET); - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - NMSettingIPConfig *s_ip4; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - nm_assert (s_ip4); - - g_ptr_array_add (argv, g_strdup ("--priority4")); - g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_route_metric (self, AF_INET))); - - g_ptr_array_add (argv, g_strdup ("--dhcp4")); - g_ptr_array_add (argv, g_strdup (dhcp4_address)); - if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE) - g_ptr_array_add (argv, g_strdup ("--dhcp4-required")); - - if (priv->dhcp_data_4.client) { - const char *hostname; - GBytes *client_id; - - client_id = nm_dhcp_client_get_client_id (priv->dhcp_data_4.client); - if (client_id) { - g_ptr_array_add (argv, g_strdup ("--dhcp4-clientid")); - g_ptr_array_add (argv, - nm_utils_bin2hexstr_full (g_bytes_get_data (client_id, NULL), - g_bytes_get_size (client_id), - ':', - FALSE, - NULL)); - } - - hostname = nm_dhcp_client_get_hostname (priv->dhcp_data_4.client); - if (hostname) { - if (nm_dhcp_client_get_use_fqdn (priv->dhcp_data_4.client)) - g_ptr_array_add (argv, g_strdup ("--dhcp4-fqdn")); - else - g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); - g_ptr_array_add (argv, g_strdup (hostname)); - } - } - - configured = TRUE; - } - - method = nm_utils_get_ip_config_method (connection, AF_INET6); - if (nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - NMSettingIPConfig *s_ip6; - NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - - g_ptr_array_add (argv, g_strdup ("--priority6")); - g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_route_metric (self, AF_INET6))); - - g_ptr_array_add (argv, g_strdup ("--slaac")); - - if (nm_setting_ip_config_get_may_fail (s_ip6) == FALSE) - g_ptr_array_add (argv, g_strdup ("--slaac-required")); - - g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr")); - g_ptr_array_add (argv, g_strdup_printf ("%d", priv->ndisc_use_tempaddr)); - - if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { - g_ptr_array_add (argv, g_strdup ("--iid")); - g_ptr_array_add (argv, - nm_utils_bin2hexstr_full (iid.id_u8, - sizeof (NMUtilsIPv6IfaceId), - ':', - FALSE, - NULL)); - } - - g_ptr_array_add (argv, g_strdup ("--addr-gen-mode")); - g_ptr_array_add (argv, g_strdup_printf ("%d", nm_setting_ip6_config_get_addr_gen_mode (NM_SETTING_IP6_CONFIG (s_ip6)))); - - configured = TRUE; - } - - if (configured) { - GPid pid; - - g_ptr_array_add (argv, NULL); - - if (nm_logging_enabled (LOGL_DEBUG, LOGD_DEVICE)) { - char *tmp; - - tmp = g_strjoinv (" ", (char **) argv->pdata); - _LOGD (LOGD_DEVICE, "running '%s'", tmp); - g_free (tmp); - } - - if (g_spawn_async (NULL, (char **) argv->pdata, NULL, - G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) { - _LOGI (LOGD_DEVICE, "spawned helper PID %u", (guint) pid); - } else { - _LOGW (LOGD_DEVICE, "failed to spawn helper: %s", error->message); - g_error_free (error); - } - } - - g_ptr_array_unref (argv); +nm_device_spawn_iface_helper(NMDevice *self) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gboolean configured = FALSE; + NMConnection * connection; + GError * error = NULL; + const char * method; + GPtrArray * argv; + gs_free char * dhcp4_address = NULL; + char * logging_backend; + NMUtilsStableType stable_type; + const char * stable_id; + + if (priv->state != NM_DEVICE_STATE_ACTIVATED) + return; + if (!nm_device_can_assume_connections(self)) + return; + + connection = nm_device_get_applied_connection(self); + + g_return_if_fail(connection); + + argv = g_ptr_array_sized_new(10); + g_ptr_array_set_free_func(argv, g_free); + + g_ptr_array_add(argv, g_strdup(LIBEXECDIR "/nm-iface-helper")); + g_ptr_array_add(argv, g_strdup("--ifname")); + g_ptr_array_add(argv, g_strdup(nm_device_get_ip_iface(self))); + g_ptr_array_add(argv, g_strdup("--uuid")); + g_ptr_array_add(argv, g_strdup(nm_connection_get_uuid(connection))); + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + if (stable_type != NM_UTILS_STABLE_TYPE_UUID) { + g_ptr_array_add(argv, g_strdup("--stable-id")); + g_ptr_array_add(argv, g_strdup_printf("%d %s", (int) stable_type, stable_id)); + } + + logging_backend = + nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_LOGGING, + NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); + if (logging_backend) { + g_ptr_array_add(argv, g_strdup("--logging-backend")); + g_ptr_array_add(argv, logging_backend); + } + + g_ptr_array_add(argv, g_strdup("--log-level")); + g_ptr_array_add(argv, g_strdup(nm_logging_level_to_string())); + + g_ptr_array_add(argv, g_strdup("--log-domains")); + g_ptr_array_add(argv, g_strdup(nm_logging_domains_to_string())); + + dhcp4_address = find_dhcp4_address(self); + + method = nm_device_get_effective_ip_config_method(self, AF_INET); + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + NMSettingIPConfig *s_ip4; + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + nm_assert(s_ip4); + + g_ptr_array_add(argv, g_strdup("--priority4")); + g_ptr_array_add(argv, g_strdup_printf("%u", nm_device_get_route_metric(self, AF_INET))); + + g_ptr_array_add(argv, g_strdup("--dhcp4")); + g_ptr_array_add(argv, g_strdup(dhcp4_address)); + if (nm_setting_ip_config_get_may_fail(s_ip4) == FALSE) + g_ptr_array_add(argv, g_strdup("--dhcp4-required")); + + if (priv->dhcp_data_4.client) { + const char *hostname; + GBytes * client_id; + + client_id = nm_dhcp_client_get_client_id(priv->dhcp_data_4.client); + if (client_id) { + g_ptr_array_add(argv, g_strdup("--dhcp4-clientid")); + g_ptr_array_add(argv, + nm_utils_bin2hexstr_full(g_bytes_get_data(client_id, NULL), + g_bytes_get_size(client_id), + ':', + FALSE, + NULL)); + } + + hostname = nm_dhcp_client_get_hostname(priv->dhcp_data_4.client); + if (hostname) { + if (nm_dhcp_client_get_use_fqdn(priv->dhcp_data_4.client)) + g_ptr_array_add(argv, g_strdup("--dhcp4-fqdn")); + else + g_ptr_array_add(argv, g_strdup("--dhcp4-hostname")); + g_ptr_array_add(argv, g_strdup(hostname)); + } + } + + configured = TRUE; + } + + method = nm_utils_get_ip_config_method(connection, AF_INET6); + if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + NMSettingIPConfig *s_ip6; + NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + + g_ptr_array_add(argv, g_strdup("--priority6")); + g_ptr_array_add(argv, g_strdup_printf("%u", nm_device_get_route_metric(self, AF_INET6))); + + g_ptr_array_add(argv, g_strdup("--slaac")); + + if (nm_setting_ip_config_get_may_fail(s_ip6) == FALSE) + g_ptr_array_add(argv, g_strdup("--slaac-required")); + + g_ptr_array_add(argv, g_strdup("--slaac-tempaddr")); + g_ptr_array_add(argv, g_strdup_printf("%d", priv->ndisc_use_tempaddr)); + + if (nm_device_get_ip_iface_identifier(self, &iid, FALSE)) { + g_ptr_array_add(argv, g_strdup("--iid")); + g_ptr_array_add( + argv, + nm_utils_bin2hexstr_full(iid.id_u8, sizeof(NMUtilsIPv6IfaceId), ':', FALSE, NULL)); + } + + g_ptr_array_add(argv, g_strdup("--addr-gen-mode")); + g_ptr_array_add( + argv, + g_strdup_printf("%d", + nm_setting_ip6_config_get_addr_gen_mode(NM_SETTING_IP6_CONFIG(s_ip6)))); + + configured = TRUE; + } + + if (configured) { + GPid pid; + + g_ptr_array_add(argv, NULL); + + if (nm_logging_enabled(LOGL_DEBUG, LOGD_DEVICE)) { + char *tmp; + + tmp = g_strjoinv(" ", (char **) argv->pdata); + _LOGD(LOGD_DEVICE, "running '%s'", tmp); + g_free(tmp); + } + + if (g_spawn_async(NULL, + (char **) argv->pdata, + NULL, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &pid, + &error)) { + _LOGI(LOGD_DEVICE, "spawned helper PID %u", (guint) pid); + } else { + _LOGW(LOGD_DEVICE, "failed to spawn helper: %s", error->message); + g_error_free(error); + } + } + + g_ptr_array_unref(argv); } /*****************************************************************************/ static gboolean -ip_config_valid (NMDeviceState state) +ip_config_valid(NMDeviceState state) { - return (state == NM_DEVICE_STATE_UNMANAGED) || - (state >= NM_DEVICE_STATE_IP_CHECK && - state <= NM_DEVICE_STATE_DEACTIVATING); + return (state == NM_DEVICE_STATE_UNMANAGED) + || (state >= NM_DEVICE_STATE_IP_CHECK && state <= NM_DEVICE_STATE_DEACTIVATING); } static void -notify_ip_properties (NMDevice *self) +notify_ip_properties(NMDevice *self) { - _notify (self, PROP_IP_IFACE); - _notify (self, PROP_IP4_CONFIG); - _notify (self, PROP_DHCP4_CONFIG); - _notify (self, PROP_IP6_CONFIG); - _notify (self, PROP_DHCP6_CONFIG); + _notify(self, PROP_IP_IFACE); + _notify(self, PROP_IP4_CONFIG); + _notify(self, PROP_DHCP4_CONFIG); + _notify(self, PROP_IP6_CONFIG); + _notify(self, PROP_DHCP6_CONFIG); } static void -ip6_managed_setup (NMDevice *self) +ip6_managed_setup(NMDevice *self) { - set_nm_ipv6ll (self, TRUE); - set_disable_ipv6 (self, "1"); - nm_device_sysctl_ip_conf_set (self, AF_INET6, "accept_ra", "0"); - nm_device_sysctl_ip_conf_set (self, AF_INET6, "use_tempaddr", "0"); - nm_device_sysctl_ip_conf_set (self, AF_INET6, "forwarding", "0"); + set_nm_ipv6ll(self, TRUE); + set_disable_ipv6(self, "1"); + nm_device_sysctl_ip_conf_set(self, AF_INET6, "accept_ra", "0"); + nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", "0"); + nm_device_sysctl_ip_conf_set(self, AF_INET6, "forwarding", "0"); } static void -deactivate_ready (NMDevice *self, NMDeviceStateReason reason) +deactivate_ready(NMDevice *self, NMDeviceStateReason reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->dispatcher.call_id) - return; + if (priv->dispatcher.call_id) + return; - if (priv->sriov_reset_pending > 0) - return; + if (priv->sriov_reset_pending > 0) + return; - if (priv->state == NM_DEVICE_STATE_DEACTIVATING) - nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason); + if (priv->state == NM_DEVICE_STATE_DEACTIVATING) + nm_device_queue_state(self, NM_DEVICE_STATE_DISCONNECTED, reason); } static void -sriov_reset_on_deactivate_cb (GError *error, gpointer user_data) +sriov_reset_on_deactivate_cb(GError *error, gpointer user_data) { - NMDevice *self; - NMDevicePrivate *priv; - gpointer reason; + NMDevice * self; + NMDevicePrivate *priv; + gpointer reason; - nm_utils_user_data_unpack (user_data, &self, &reason); - priv = NM_DEVICE_GET_PRIVATE (self); - nm_assert (priv->sriov_reset_pending > 0); - priv->sriov_reset_pending--; + nm_utils_user_data_unpack(user_data, &self, &reason); + priv = NM_DEVICE_GET_PRIVATE(self); + nm_assert(priv->sriov_reset_pending > 0); + priv->sriov_reset_pending--; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - deactivate_ready (self, (NMDeviceStateReason) reason); + deactivate_ready(self, GPOINTER_TO_INT(reason)); } static void -sriov_reset_on_failure_cb (GError *error, gpointer user_data) +sriov_reset_on_failure_cb(GError *error, gpointer user_data) { - NMDevice *self = user_data; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = user_data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert (priv->sriov_reset_pending > 0); - priv->sriov_reset_pending--; + nm_assert(priv->sriov_reset_pending > 0); + priv->sriov_reset_pending--; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - if (priv->state == NM_DEVICE_STATE_FAILED) { - nm_device_queue_state (self, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_NONE); - } + if (priv->state == NM_DEVICE_STATE_FAILED) { + nm_device_queue_state(self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + } } static void -deactivate_async_ready (NMDevice *self, - GError *error, - gpointer user_data) +deactivate_async_ready(NMDevice *self, GError *error, gpointer user_data) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceStateReason reason = GPOINTER_TO_UINT (user_data); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceStateReason reason = GPOINTER_TO_UINT(user_data); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - _LOGD (LOGD_DEVICE, "Deactivation cancelled"); - return; - } + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + _LOGD(LOGD_DEVICE, "Deactivation cancelled"); + return; + } - g_clear_object (&priv->deactivating_cancellable); + g_clear_object(&priv->deactivating_cancellable); - /* In every other case, transition to the DISCONNECTED state */ - if (error) { - _LOGW (LOGD_DEVICE, "Deactivation failed: %s", - error->message); - } + /* In every other case, transition to the DISCONNECTED state */ + if (error) { + _LOGW(LOGD_DEVICE, "Deactivation failed: %s", error->message); + } - deactivate_ready (self, reason); + deactivate_ready(self, reason); } static void -deactivate_dispatcher_complete (NMDispatcherCallId *call_id, gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceStateReason reason; - - g_return_if_fail (call_id == priv->dispatcher.call_id); - g_return_if_fail (priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED); - - reason = priv->state_reason; - - priv->dispatcher.call_id = NULL; - priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; - priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; - - if (nm_clear_g_cancellable (&priv->deactivating_cancellable)) - nm_assert_not_reached (); - - if (NM_DEVICE_GET_CLASS (self)->deactivate_async) { - /* FIXME: the virtual function deactivate_async() has only this caller here. - * And the NMDevice subtypes are well aware of the circumstances when they - * are called. We shall make the function less generic and thus (as the scope - * is narrower) more convenient. - * - * - Drop the callback argument. Instead, when deactivate_async() completes, the - * subtype shall call a method _nm_device_deactivate_async_done(). Because as - * it is currently, subtypes need to pretend this callback and the user-data - * would be opaque, and carry it around. When it's in fact very clear what this - * is. - * - * - Also drop the GCancellable argument. Upon cancellation, NMDevice shall - * call another virtual function deactivate_async_abort(). As it is currently, - * callers need to register to the cancelled signal of the cancellable. It - * seems simpler to just implement the deactivate_async_abort() function. - * On the other hand, some implementations actually use the GCancellable. - * So, NMDevice shall do both: it shall both pass a cancellable, but also - * invoke deactivate_async_abort(). It allow the implementation to honor - * whatever is simpler for their purpose. - * - * - sometimes, the subclass can complete right away. Scheduling the completion - * in an idle handler is cumbersome. Allow the function to return FALSE to - * indicate that the device is already deactivated and the callback (or - * _nm_device_deactivate_async_done()) won't be invoked. - */ - priv->deactivating_cancellable = g_cancellable_new (); - NM_DEVICE_GET_CLASS (self)->deactivate_async (self, - priv->deactivating_cancellable, - deactivate_async_ready, - GUINT_TO_POINTER (reason)); - } else - deactivate_ready (self, reason); +deactivate_dispatcher_complete(NMDispatcherCallId *call_id, gpointer user_data) +{ + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceStateReason reason; + + g_return_if_fail(call_id == priv->dispatcher.call_id); + g_return_if_fail(priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED); + + reason = priv->state_reason; + + priv->dispatcher.call_id = NULL; + priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN; + priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; + + if (nm_clear_g_cancellable(&priv->deactivating_cancellable)) + nm_assert_not_reached(); + + if (NM_DEVICE_GET_CLASS(self)->deactivate_async) { + /* FIXME: the virtual function deactivate_async() has only this caller here. + * And the NMDevice subtypes are well aware of the circumstances when they + * are called. We shall make the function less generic and thus (as the scope + * is narrower) more convenient. + * + * - Drop the callback argument. Instead, when deactivate_async() completes, the + * subtype shall call a method _nm_device_deactivate_async_done(). Because as + * it is currently, subtypes need to pretend this callback and the user-data + * would be opaque, and carry it around. When it's in fact very clear what this + * is. + * + * - Also drop the GCancellable argument. Upon cancellation, NMDevice shall + * call another virtual function deactivate_async_abort(). As it is currently, + * callers need to register to the cancelled signal of the cancellable. It + * seems simpler to just implement the deactivate_async_abort() function. + * On the other hand, some implementations actually use the GCancellable. + * So, NMDevice shall do both: it shall both pass a cancellable, but also + * invoke deactivate_async_abort(). It allow the implementation to honor + * whatever is simpler for their purpose. + * + * - sometimes, the subclass can complete right away. Scheduling the completion + * in an idle handler is cumbersome. Allow the function to return FALSE to + * indicate that the device is already deactivated and the callback (or + * _nm_device_deactivate_async_done()) won't be invoked. + */ + priv->deactivating_cancellable = g_cancellable_new(); + NM_DEVICE_GET_CLASS(self)->deactivate_async(self, + priv->deactivating_cancellable, + deactivate_async_ready, + GUINT_TO_POINTER(reason)); + } else + deactivate_ready(self, reason); } static void -_set_state_full (NMDevice *self, - NMDeviceState state, - NMDeviceStateReason reason, - gboolean quitting) -{ - NMDevicePrivate *priv; - NMDeviceState old_state; - gs_unref_object NMActRequest *req = NULL; - gboolean no_firmware = FALSE; - NMSettingsConnection *sett_conn; - NMSettingSriov *s_sriov; - gboolean concheck_now; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - - /* Track re-entry */ - g_warn_if_fail (priv->in_state_changed == FALSE); - - old_state = priv->state; - - if ( state == NM_DEVICE_STATE_FAILED - && nm_device_sys_iface_state_is_external_or_assume (self)) { - /* Avoid tearing down assumed connection, assume it's connected */ - state = NM_DEVICE_STATE_ACTIVATED; - reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; - } - - /* Do nothing if state isn't changing, but as a special case allow - * re-setting UNAVAILABLE if the device is missing firmware so that we - * can retry device initialization. - */ - if ( (priv->state == state) - && ( state != NM_DEVICE_STATE_UNAVAILABLE - || !priv->firmware_missing)) { - _LOGD (LOGD_DEVICE, "state change: %s -> %s (reason '%s', sys-iface-state: '%s'%s)", - nm_device_state_to_str (old_state), - nm_device_state_to_str (state), - reason_to_string_a (reason), - _sys_iface_state_to_str (priv->sys_iface_state), - priv->firmware_missing ? ", missing firmware" : ""); - return; - } - - _LOGI (LOGD_DEVICE, "state change: %s -> %s (reason '%s', sys-iface-state: '%s')", - nm_device_state_to_str (old_state), - nm_device_state_to_str (state), - reason_to_string_a (reason), - _sys_iface_state_to_str (priv->sys_iface_state)); - - /* in order to prevent triggering any callback caused - * by the device not having any pending action anymore - * we add one here that gets removed at the end of the function */ - nm_device_add_pending_action (self, - NM_PENDING_ACTION_IN_STATE_CHANGE, - TRUE); - priv->in_state_changed = TRUE; - - priv->state = state; - priv->state_reason = reason; - - queued_state_clear (self); - - dispatcher_cleanup (self); - - nm_clear_g_cancellable (&priv->deactivating_cancellable); - - /* Cache the activation request for the dispatcher */ - req = nm_g_object_ref (priv->act_request.obj); - - if ( state > NM_DEVICE_STATE_UNMANAGED - && state <= NM_DEVICE_STATE_ACTIVATED - && nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NOW_MANAGED - && NM_IN_SET_TYPED (NMDeviceSysIfaceState, - priv->sys_iface_state, - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME)) - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); - - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state >= NM_DEVICE_STATE_ACTIVATED) - priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET; - - if (state > NM_DEVICE_STATE_DISCONNECTED) - nm_device_assume_state_reset (self); - - if (state <= NM_DEVICE_STATE_UNAVAILABLE) { - if (available_connections_del_all (self)) - _notify (self, PROP_AVAILABLE_CONNECTIONS); - if (old_state > NM_DEVICE_STATE_UNAVAILABLE) { - _clear_queued_act_request (priv, - NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); - } - } - - /* Update the available connections list when a device first becomes available */ - if (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) - nm_device_recheck_available_connections (self); - - if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_DEACTIVATING) { - if (nm_clear_g_free (&priv->current_stable_id)) - _LOGT (LOGD_DEVICE, "stable-id: clear"); - } - - /* Handle the new state here; but anything that could trigger - * another state change should be done below. - */ - switch (state) { - case NM_DEVICE_STATE_UNMANAGED: - nm_device_set_firmware_missing (self, FALSE); - if (old_state > NM_DEVICE_STATE_UNMANAGED) { - if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) { - nm_device_cleanup (self, reason, - priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED - ? CLEANUP_TYPE_REMOVED - : CLEANUP_TYPE_KEEP); - } else { - /* Clean up if the device is now unmanaged but was activated */ - if (nm_device_get_act_request (self)) - nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); - nm_device_take_down (self, TRUE); - nm_device_hw_addr_reset (self, "unmanage"); - set_nm_ipv6ll (self, FALSE); - restore_ip6_properties (self); - break; - } - } - break; - case NM_DEVICE_STATE_UNAVAILABLE: - if (old_state == NM_DEVICE_STATE_UNMANAGED) { - save_ip6_properties (self); - if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) - ip6_managed_setup (self); - device_init_static_sriov_num_vfs (self); - } - - if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) { - if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { - if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) - _LOGW (LOGD_PLATFORM, "firmware may be missing."); - nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); - } - - /* Ensure the device gets deactivated in response to stuff like - * carrier changes or rfkill. But don't deactivate devices that are - * about to assume a connection since that defeats the purpose of - * assuming the device's existing connection. - * - * Note that we "deactivate" the device even when coming from - * UNMANAGED, to ensure that it's in a clean state. - */ - nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); - } - break; - case NM_DEVICE_STATE_DISCONNECTED: - if (old_state > NM_DEVICE_STATE_DISCONNECTED) { - /* Ensure devices that previously assumed a connection now have - * userspace IPv6LL enabled. - */ - set_nm_ipv6ll (self, TRUE); - - nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); - } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { - if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) { - /* Ensure IPv6 is set up as it may not have been done when - * entering the UNAVAILABLE state depending on the reason. - */ - ip6_managed_setup (self); - } - } - break; - case NM_DEVICE_STATE_PREPARE: - nm_device_update_initial_hw_address (self); - break; - case NM_DEVICE_STATE_NEED_AUTH: - if (old_state > NM_DEVICE_STATE_NEED_AUTH) { - /* Clean up any half-done IP operations if the device's layer2 - * finds out it needs authentication during IP config. - */ - _cleanup_ip_pre (self, AF_INET, CLEANUP_TYPE_DECONFIGURE); - _cleanup_ip_pre (self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); - } - break; - default: - break; - } - - /* Reset intern autoconnect flags when the device is activating or connected. */ - if ( state >= NM_DEVICE_STATE_PREPARE - && state <= NM_DEVICE_STATE_ACTIVATED) - nm_device_autoconnect_blocked_unset (self, NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL); - - _notify (self, PROP_STATE); - _notify (self, PROP_STATE_REASON); - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), - &interface_info_device, - &signal_info_state_changed, - "(uuu)", - (guint32) state, - (guint32) old_state, - (guint32) reason); - g_signal_emit (self, signals[STATE_CHANGED], 0, (guint) state, (guint) old_state, (guint) reason); - - /* Post-process the event after internal notification */ - - switch (state) { - case NM_DEVICE_STATE_UNAVAILABLE: - /* If the device can activate now (ie, it's got a carrier, the supplicant - * is active, or whatever) schedule a delayed transition to DISCONNECTED - * to get things rolling. The device can't transition immediately because - * we can't change states again from the state handler for a variety of - * reasons. - */ - if (nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { - nm_device_queue_recheck_available (self, - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_NONE); - } else { - _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED"); - } - break; - case NM_DEVICE_STATE_DEACTIVATING: - _cancel_activation (self); - - /* We cache the ignore_carrier state to not react on config-reloads while the connection - * is active. But on deactivating, reset the ignore-carrier flag to the current state. */ - priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self); - - if (quitting) { - nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_PRE_DOWN, - self, req); - } else { - priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; - priv->dispatcher.post_state_reason = reason; - if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_DOWN, - self, - req, - deactivate_dispatcher_complete, - self, - &priv->dispatcher.call_id)) { - /* Just proceed on errors */ - deactivate_dispatcher_complete (0, self); - } - - if ( priv->ifindex > 0 - && (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) { - priv->sriov_reset_pending++; - sriov_op_queue (self, - 0, - NM_TERNARY_TRUE, - sriov_reset_on_deactivate_cb, - nm_utils_user_data_pack (self, (gpointer) reason)); - } - } - - nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id); - break; - case NM_DEVICE_STATE_DISCONNECTED: - if ( priv->queued_act_request - && !priv->queued_act_request_is_waiting_for_carrier) { - gs_unref_object NMActRequest *queued_req = NULL; - - queued_req = g_steal_pointer (&priv->queued_act_request); - _device_activate (self, queued_req); - } - break; - case NM_DEVICE_STATE_ACTIVATED: - _LOGI (LOGD_DEVICE, "Activation: successful, device activated."); - nm_device_update_metered (self); - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_UP, - self, - req, - NULL, NULL, NULL); - - if (priv->proxy_config) - _pacrunner_manager_add (self); - break; - case NM_DEVICE_STATE_FAILED: - /* Usually upon failure the activation chain is interrupted in - * one of the stages; but in some cases the device fails for - * external events (as a failure of master connection) while - * the activation sequence is running and so we need to ensure - * that the chain is terminated here. - */ - _cancel_activation (self); - - sett_conn = nm_device_get_settings_connection (self); - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: failed for connection '%s'", - sett_conn ? nm_settings_connection_get_id (sett_conn) : ""); - - /* Notify any slaves of the unexpected failure */ - nm_device_master_release_slaves (self); - - /* If the connection doesn't yet have a timestamp, set it to zero so that - * we can distinguish between connections we've tried to activate and have - * failed (zero timestamp), connections that succeeded (non-zero timestamp), - * and those we haven't tried yet (no timestamp). - */ - if (sett_conn && !nm_settings_connection_get_timestamp (sett_conn, NULL)) - nm_settings_connection_update_timestamp (sett_conn, (guint64) 0); - - if ( priv->ifindex > 0 - && (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) { - priv->sriov_reset_pending++; - sriov_op_queue (self, - 0, - NM_TERNARY_TRUE, - sriov_reset_on_failure_cb, - self); - break; - } - /* Schedule the transition to DISCONNECTED. The device can't transition - * immediately because we can't change states again from the state - * handler for a variety of reasons. - */ - nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); - break; - case NM_DEVICE_STATE_IP_CHECK: - if ( priv->fw_state >= FIREWALL_STATE_INITIALIZED - && priv->ip_iface - && !nm_device_sys_iface_state_is_external (self)) { - priv->fw_state = FIREWALL_STATE_WAIT_IP_CONFIG; - fw_change_zone (self); - } else - nm_device_start_ip_check (self); - - /* IP-related properties are only valid when the device has IP configuration; - * now that it does, ensure their change notifications are emitted. - */ - notify_ip_properties (self); - break; - case NM_DEVICE_STATE_SECONDARIES: - ip_check_gw_ping_cleanup (self); - _LOGD (LOGD_DEVICE, "device entered SECONDARIES state"); - break; - default: - break; - } - - if (state > NM_DEVICE_STATE_DISCONNECTED) - delete_on_deactivate_unschedule (self); - - if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING) - && (state != NM_DEVICE_STATE_DEACTIVATING)) { - if (quitting) { - nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_DOWN, - self, req); - } else { - nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DOWN, - self, - req, - NULL, NULL, NULL); - } - } - - /* IP-related properties are only valid when the device has IP configuration. - * If it no longer does, ensure their change notifications are emitted. - */ - if ( ip_config_valid (old_state) - && !ip_config_valid (state)) - notify_ip_properties (self); - - concheck_now = NM_IN_SET (state, NM_DEVICE_STATE_ACTIVATED, - NM_DEVICE_STATE_DISCONNECTED) - || old_state >= NM_DEVICE_STATE_ACTIVATED; - concheck_update_interval (self, AF_INET, concheck_now); - concheck_update_interval (self, AF_INET6, concheck_now); - - priv->in_state_changed = FALSE; - nm_device_remove_pending_action (self, - NM_PENDING_ACTION_IN_STATE_CHANGE, - TRUE); - - if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED)) - _notify (self, PROP_MANAGED); +_set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting) +{ + NMDevicePrivate *priv; + NMDeviceState old_state; + gs_unref_object NMActRequest *req = NULL; + gboolean no_firmware = FALSE; + NMSettingsConnection * sett_conn; + NMSettingSriov * s_sriov; + gboolean concheck_now; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + /* Track re-entry */ + g_warn_if_fail(priv->in_state_changed == FALSE); + + old_state = priv->state; + + if (state == NM_DEVICE_STATE_FAILED && nm_device_sys_iface_state_is_external_or_assume(self)) { + /* Avoid tearing down assumed connection, assume it's connected */ + state = NM_DEVICE_STATE_ACTIVATED; + reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; + } + + /* Do nothing if state isn't changing, but as a special case allow + * re-setting UNAVAILABLE if the device is missing firmware so that we + * can retry device initialization. + */ + if ((priv->state == state) + && (state != NM_DEVICE_STATE_UNAVAILABLE || !priv->firmware_missing)) { + _LOGD(LOGD_DEVICE, + "state change: %s -> %s (reason '%s', sys-iface-state: '%s'%s)", + nm_device_state_to_str(old_state), + nm_device_state_to_str(state), + reason_to_string_a(reason), + _sys_iface_state_to_str(priv->sys_iface_state), + priv->firmware_missing ? ", missing firmware" : ""); + return; + } + + _LOGI(LOGD_DEVICE, + "state change: %s -> %s (reason '%s', sys-iface-state: '%s')", + nm_device_state_to_str(old_state), + nm_device_state_to_str(state), + reason_to_string_a(reason), + _sys_iface_state_to_str(priv->sys_iface_state)); + + /* in order to prevent triggering any callback caused + * by the device not having any pending action anymore + * we add one here that gets removed at the end of the function */ + nm_device_add_pending_action(self, NM_PENDING_ACTION_IN_STATE_CHANGE, TRUE); + priv->in_state_changed = TRUE; + + priv->state = state; + priv->state_reason = reason; + + queued_state_clear(self); + + dispatcher_cleanup(self); + + nm_clear_g_cancellable(&priv->deactivating_cancellable); + + /* Cache the activation request for the dispatcher */ + req = nm_g_object_ref(priv->act_request.obj); + + if (state > NM_DEVICE_STATE_UNMANAGED && state <= NM_DEVICE_STATE_ACTIVATED + && nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_NOW_MANAGED + && NM_IN_SET_TYPED(NMDeviceSysIfaceState, + priv->sys_iface_state, + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME)) + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); + + if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_ACTIVATED) + priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET; + + if (state > NM_DEVICE_STATE_DISCONNECTED) + nm_device_assume_state_reset(self); + + if (state <= NM_DEVICE_STATE_UNAVAILABLE) { + if (available_connections_del_all(self)) + _notify(self, PROP_AVAILABLE_CONNECTIONS); + if (old_state > NM_DEVICE_STATE_UNAVAILABLE) { + _clear_queued_act_request(priv, NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); + } + } + + /* Update the available connections list when a device first becomes available */ + if (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) + nm_device_recheck_available_connections(self); + + if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_DEACTIVATING) { + if (nm_clear_g_free(&priv->current_stable_id)) + _LOGT(LOGD_DEVICE, "stable-id: clear"); + } + + /* Handle the new state here; but anything that could trigger + * another state change should be done below. + */ + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + nm_device_set_firmware_missing(self, FALSE); + if (old_state > NM_DEVICE_STATE_UNMANAGED) { + if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) { + nm_device_cleanup(self, + reason, + priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED + ? CLEANUP_TYPE_REMOVED + : CLEANUP_TYPE_KEEP); + } else { + /* Clean up if the device is now unmanaged but was activated */ + if (nm_device_get_act_request(self)) + nm_device_cleanup(self, reason, CLEANUP_TYPE_DECONFIGURE); + nm_device_take_down(self, TRUE); + nm_device_hw_addr_reset(self, "unmanage"); + set_nm_ipv6ll(self, FALSE); + restore_ip6_properties(self); + break; + } + } + break; + case NM_DEVICE_STATE_UNAVAILABLE: + if (old_state == NM_DEVICE_STATE_UNMANAGED) { + save_ip6_properties(self); + if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) + ip6_managed_setup(self); + device_init_static_sriov_num_vfs(self); + } + + if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) { + if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { + if (!nm_device_bring_up(self, TRUE, &no_firmware) && no_firmware) + _LOGW(LOGD_PLATFORM, "firmware may be missing."); + nm_device_set_firmware_missing(self, no_firmware ? TRUE : FALSE); + } + + /* Ensure the device gets deactivated in response to stuff like + * carrier changes or rfkill. But don't deactivate devices that are + * about to assume a connection since that defeats the purpose of + * assuming the device's existing connection. + * + * Note that we "deactivate" the device even when coming from + * UNMANAGED, to ensure that it's in a clean state. + */ + nm_device_cleanup(self, reason, CLEANUP_TYPE_DECONFIGURE); + } + break; + case NM_DEVICE_STATE_DISCONNECTED: + if (old_state > NM_DEVICE_STATE_DISCONNECTED) { + /* Ensure devices that previously assumed a connection now have + * userspace IPv6LL enabled. + */ + set_nm_ipv6ll(self, TRUE); + + nm_device_cleanup(self, reason, CLEANUP_TYPE_DECONFIGURE); + } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { + if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) { + /* Ensure IPv6 is set up as it may not have been done when + * entering the UNAVAILABLE state depending on the reason. + */ + ip6_managed_setup(self); + } + } + break; + case NM_DEVICE_STATE_PREPARE: + nm_device_update_initial_hw_address(self); + break; + case NM_DEVICE_STATE_NEED_AUTH: + if (old_state > NM_DEVICE_STATE_NEED_AUTH) { + /* Clean up any half-done IP operations if the device's layer2 + * finds out it needs authentication during IP config. + */ + _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_DECONFIGURE); + _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); + } + break; + default: + break; + } + + /* Reset intern autoconnect flags when the device is activating or connected. */ + if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) + nm_device_autoconnect_blocked_unset(self, NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL); + + _notify(self, PROP_STATE); + _notify(self, PROP_STATE_REASON); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), + &interface_info_device, + &signal_info_state_changed, + "(uuu)", + (guint32) state, + (guint32) old_state, + (guint32) reason); + g_signal_emit(self, + signals[STATE_CHANGED], + 0, + (guint) state, + (guint) old_state, + (guint) reason); + + /* Post-process the event after internal notification */ + + switch (state) { + case NM_DEVICE_STATE_UNAVAILABLE: + /* If the device can activate now (ie, it's got a carrier, the supplicant + * is active, or whatever) schedule a delayed transition to DISCONNECTED + * to get things rolling. The device can't transition immediately because + * we can't change states again from the state handler for a variety of + * reasons. + */ + if (nm_device_is_available(self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { + nm_device_queue_recheck_available(self, + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_NONE); + } else { + _LOGD(LOGD_DEVICE, "device not yet available for transition to DISCONNECTED"); + } + break; + case NM_DEVICE_STATE_DEACTIVATING: + _cancel_activation(self); + + /* We cache the ignore_carrier state to not react on config-reloads while the connection + * is active. But on deactivating, reset the ignore-carrier flag to the current state. */ + priv->ignore_carrier = nm_config_data_get_ignore_carrier(NM_CONFIG_GET_DATA, self); + + if (quitting) { + nm_dispatcher_call_device_sync(NM_DISPATCHER_ACTION_PRE_DOWN, self, req); + } else { + priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; + priv->dispatcher.post_state_reason = reason; + if (!nm_dispatcher_call_device(NM_DISPATCHER_ACTION_PRE_DOWN, + self, + req, + deactivate_dispatcher_complete, + self, + &priv->dispatcher.call_id)) { + /* Just proceed on errors */ + deactivate_dispatcher_complete(0, self); + } + + if (priv->ifindex > 0 + && (s_sriov = nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV))) { + priv->sriov_reset_pending++; + sriov_op_queue(self, + 0, + NM_TERNARY_TRUE, + sriov_reset_on_deactivate_cb, + nm_utils_user_data_pack(self, GINT_TO_POINTER(reason))); + } + } + + nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id); + break; + case NM_DEVICE_STATE_DISCONNECTED: + if (priv->queued_act_request && !priv->queued_act_request_is_waiting_for_carrier) { + gs_unref_object NMActRequest *queued_req = NULL; + + queued_req = g_steal_pointer(&priv->queued_act_request); + _device_activate(self, queued_req); + } + break; + case NM_DEVICE_STATE_ACTIVATED: + _LOGI(LOGD_DEVICE, "Activation: successful, device activated."); + nm_device_update_metered(self); + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_UP, self, req, NULL, NULL, NULL); + + if (priv->proxy_config) + _pacrunner_manager_add(self); + break; + case NM_DEVICE_STATE_FAILED: + /* Usually upon failure the activation chain is interrupted in + * one of the stages; but in some cases the device fails for + * external events (as a failure of master connection) while + * the activation sequence is running and so we need to ensure + * that the chain is terminated here. + */ + _cancel_activation(self); + + sett_conn = nm_device_get_settings_connection(self); + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: failed for connection '%s'", + sett_conn ? nm_settings_connection_get_id(sett_conn) : ""); + + /* Notify any slaves of the unexpected failure */ + nm_device_master_release_slaves(self); + + /* If the connection doesn't yet have a timestamp, set it to zero so that + * we can distinguish between connections we've tried to activate and have + * failed (zero timestamp), connections that succeeded (non-zero timestamp), + * and those we haven't tried yet (no timestamp). + */ + if (sett_conn && !nm_settings_connection_get_timestamp(sett_conn, NULL)) + nm_settings_connection_update_timestamp(sett_conn, (guint64) 0); + + if (priv->ifindex > 0 + && (s_sriov = nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV))) { + priv->sriov_reset_pending++; + sriov_op_queue(self, 0, NM_TERNARY_TRUE, sriov_reset_on_failure_cb, self); + break; + } + /* Schedule the transition to DISCONNECTED. The device can't transition + * immediately because we can't change states again from the state + * handler for a variety of reasons. + */ + nm_device_queue_state(self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + break; + case NM_DEVICE_STATE_IP_CHECK: + if (priv->fw_state >= FIREWALL_STATE_INITIALIZED && priv->ip_iface + && !nm_device_sys_iface_state_is_external(self)) { + priv->fw_state = FIREWALL_STATE_WAIT_IP_CONFIG; + fw_change_zone(self); + } else + nm_device_start_ip_check(self); + + /* IP-related properties are only valid when the device has IP configuration; + * now that it does, ensure their change notifications are emitted. + */ + notify_ip_properties(self); + break; + case NM_DEVICE_STATE_SECONDARIES: + ip_check_gw_ping_cleanup(self); + _LOGD(LOGD_DEVICE, "device entered SECONDARIES state"); + break; + default: + break; + } + + if (state > NM_DEVICE_STATE_DISCONNECTED) + delete_on_deactivate_unschedule(self); + + if ((old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING) + && (state != NM_DEVICE_STATE_DEACTIVATING)) { + if (quitting) { + nm_dispatcher_call_device_sync(NM_DISPATCHER_ACTION_DOWN, self, req); + } else { + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DOWN, self, req, NULL, NULL, NULL); + } + } + + /* IP-related properties are only valid when the device has IP configuration. + * If it no longer does, ensure their change notifications are emitted. + */ + if (ip_config_valid(old_state) && !ip_config_valid(state)) + notify_ip_properties(self); + + concheck_now = NM_IN_SET(state, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_DISCONNECTED) + || old_state >= NM_DEVICE_STATE_ACTIVATED; + concheck_update_interval(self, AF_INET, concheck_now); + concheck_update_interval(self, AF_INET6, concheck_now); + + priv->in_state_changed = FALSE; + nm_device_remove_pending_action(self, NM_PENDING_ACTION_IN_STATE_CHANGE, TRUE); + + if ((old_state > NM_DEVICE_STATE_UNMANAGED) != (state > NM_DEVICE_STATE_UNMANAGED)) + _notify(self, PROP_MANAGED); } void -nm_device_state_changed (NMDevice *self, - NMDeviceState state, - NMDeviceStateReason reason) +nm_device_state_changed(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason) { - _set_state_full (self, state, reason, FALSE); + _set_state_full(self, state, reason, FALSE); } static gboolean -queued_state_set (gpointer user_data) +queued_state_set(gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMDeviceState new_state; - NMDeviceStateReason new_reason; + NMDevice * self = NM_DEVICE(user_data); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceState new_state; + NMDeviceStateReason new_reason; - nm_assert (priv->queued_state.id); + nm_assert(priv->queued_state.id); - _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str (priv->queued_state.state), - reason_to_string_a (priv->queued_state.reason), - priv->queued_state.id, - "change state"); + _LOGD(LOGD_DEVICE, + "queue-state[%s, reason:%s, id:%u]: %s", + nm_device_state_to_str(priv->queued_state.state), + reason_to_string_a(priv->queued_state.reason), + priv->queued_state.id, + "change state"); - /* Clear queued state struct before triggering state change, since - * the state change may queue another state. - */ - priv->queued_state.id = 0; - new_state = priv->queued_state.state; - new_reason = priv->queued_state.reason; + /* Clear queued state struct before triggering state change, since + * the state change may queue another state. + */ + priv->queued_state.id = 0; + new_state = priv->queued_state.state; + new_reason = priv->queued_state.reason; - nm_device_state_changed (self, new_state, new_reason); - nm_device_remove_pending_action (self, queued_state_to_string (new_state), TRUE); + nm_device_state_changed(self, new_state, new_reason); + nm_device_remove_pending_action(self, queued_state_to_string(new_state), TRUE); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } void -nm_device_queue_state (NMDevice *self, - NMDeviceState state, - NMDeviceStateReason reason) -{ - NMDevicePrivate *priv; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->queued_state.id && priv->queued_state.state == state) { - _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s%s%s%s", - nm_device_state_to_str (priv->queued_state.state), - reason_to_string_a (priv->queued_state.reason), - priv->queued_state.id, - "ignore queuing same state change", - NM_PRINT_FMT_QUOTED (priv->queued_state.reason != reason, - " (reason differs: ", reason_to_string_a (reason), ")", "")); - return; - } - - /* Add pending action for the new state before clearing the queued states, so - * that we don't accidentally pop all pending states and reach 'startup complete' */ - nm_device_add_pending_action (self, queued_state_to_string (state), TRUE); - - /* We should only ever have one delayed state transition at a time */ - if (priv->queued_state.id) { - _LOGW (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str (priv->queued_state.state), - reason_to_string_a (priv->queued_state.reason), - priv->queued_state.id, - "replace previously queued state change"); - nm_clear_g_source (&priv->queued_state.id); - nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); - } - - priv->queued_state.state = state; - priv->queued_state.reason = reason; - priv->queued_state.id = g_idle_add (queued_state_set, self); - - _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str (state), - reason_to_string_a (reason), - priv->queued_state.id, - "queue state change"); +nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason) +{ + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (priv->queued_state.id && priv->queued_state.state == state) { + _LOGD(LOGD_DEVICE, + "queue-state[%s, reason:%s, id:%u]: %s%s%s%s", + nm_device_state_to_str(priv->queued_state.state), + reason_to_string_a(priv->queued_state.reason), + priv->queued_state.id, + "ignore queuing same state change", + NM_PRINT_FMT_QUOTED(priv->queued_state.reason != reason, + " (reason differs: ", + reason_to_string_a(reason), + ")", + "")); + return; + } + + /* Add pending action for the new state before clearing the queued states, so + * that we don't accidentally pop all pending states and reach 'startup complete' */ + nm_device_add_pending_action(self, queued_state_to_string(state), TRUE); + + /* We should only ever have one delayed state transition at a time */ + if (priv->queued_state.id) { + _LOGW(LOGD_DEVICE, + "queue-state[%s, reason:%s, id:%u]: %s", + nm_device_state_to_str(priv->queued_state.state), + reason_to_string_a(priv->queued_state.reason), + priv->queued_state.id, + "replace previously queued state change"); + nm_clear_g_source(&priv->queued_state.id); + nm_device_remove_pending_action(self, + queued_state_to_string(priv->queued_state.state), + TRUE); + } + + priv->queued_state.state = state; + priv->queued_state.reason = reason; + priv->queued_state.id = g_idle_add(queued_state_set, self); + + _LOGD(LOGD_DEVICE, + "queue-state[%s, reason:%s, id:%u]: %s", + nm_device_state_to_str(state), + reason_to_string_a(reason), + priv->queued_state.id, + "queue state change"); } static void -queued_state_clear (NMDevice *self) +queued_state_clear(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (!priv->queued_state.id) - return; + if (!priv->queued_state.id) + return; - _LOGD (LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str (priv->queued_state.state), - reason_to_string_a (priv->queued_state.reason), - priv->queued_state.id, - "clear queued state change"); - nm_clear_g_source (&priv->queued_state.id); - nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); + _LOGD(LOGD_DEVICE, + "queue-state[%s, reason:%s, id:%u]: %s", + nm_device_state_to_str(priv->queued_state.state), + reason_to_string_a(priv->queued_state.reason), + priv->queued_state.id, + "clear queued state change"); + nm_clear_g_source(&priv->queued_state.id); + nm_device_remove_pending_action(self, queued_state_to_string(priv->queued_state.state), TRUE); } NMDeviceState -nm_device_get_state (NMDevice *self) +nm_device_get_state(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN); + g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_STATE_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (self)->state; + return NM_DEVICE_GET_PRIVATE(self)->state; } /*****************************************************************************/ /* NMConfigDevice interface related stuff */ const char * -nm_device_get_hw_address (NMDevice *self) +nm_device_get_hw_address(NMDevice *self) { - NMDevicePrivate *priv; - char buf[NM_UTILS_HWADDR_LEN_MAX]; - gsize l; + NMDevicePrivate *priv; + char buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert ( (!priv->hw_addr && priv->hw_addr_len == 0) - || ( priv->hw_addr - && _nm_utils_hwaddr_aton (priv->hw_addr, buf, sizeof (buf), &l) - && l == priv->hw_addr_len)); + nm_assert((!priv->hw_addr && priv->hw_addr_len == 0) + || (priv->hw_addr && _nm_utils_hwaddr_aton(priv->hw_addr, buf, sizeof(buf), &l) + && l == priv->hw_addr_len)); - return priv->hw_addr; + return priv->hw_addr; } gboolean -nm_device_update_hw_address (NMDevice *self) -{ - NMDevicePrivate *priv; - const guint8 *hwaddr; - gsize hwaddrlen = 0; - - priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->ifindex <= 0) - return FALSE; - - hwaddr = nm_platform_link_get_address (nm_device_get_platform (self), priv->ifindex, &hwaddrlen); - - if ( priv->type == NM_DEVICE_TYPE_ETHERNET - && hwaddr - && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth))) - hwaddrlen = 0; - - if (!hwaddrlen) - return FALSE; - - if ( priv->hw_addr_len - && priv->hw_addr_len != hwaddrlen) { - char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR]; - - /* we cannot change the address length of a device once it is set (except - * unrealizing the device). - * - * The reason is that the permanent and initial MAC addresses also must have the - * same address length, so it's unclear what it would mean that the length changes. */ - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, - "hw-addr: read a MAC address with differing length (%s vs. %s)", - priv->hw_addr, - nm_utils_hwaddr_ntoa_buf (hwaddr, hwaddrlen, TRUE, s_buf, sizeof (s_buf))); - return FALSE; - } - - if ( priv->hw_addr - && nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) - return FALSE; - - g_free (priv->hw_addr); - priv->hw_addr_len_ = hwaddrlen; - priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); - _notify (self, PROP_HW_ADDRESS); - - if ( !priv->hw_addr_initial - || ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET - && priv->state < NM_DEVICE_STATE_PREPARE - && !nm_device_is_activating (self))) { - /* when we get a hw_addr the first time or while the device - * is not activated (with no explicit hw address set), always - * update our initial hw-address as well. */ - nm_device_update_initial_hw_address (self); - } - return TRUE; +nm_device_update_hw_address(NMDevice *self) +{ + NMDevicePrivate *priv; + const guint8 * hwaddr; + gsize hwaddrlen = 0; + + priv = NM_DEVICE_GET_PRIVATE(self); + if (priv->ifindex <= 0) + return FALSE; + + hwaddr = nm_platform_link_get_address(nm_device_get_platform(self), priv->ifindex, &hwaddrlen); + + if (priv->type == NM_DEVICE_TYPE_ETHERNET && hwaddr + && nm_utils_hwaddr_matches(hwaddr, + hwaddrlen, + &nm_ether_addr_zero, + sizeof(nm_ether_addr_zero))) + hwaddrlen = 0; + + if (!hwaddrlen) + return FALSE; + + if (priv->hw_addr_len && priv->hw_addr_len != hwaddrlen) { + char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR]; + + /* we cannot change the address length of a device once it is set (except + * unrealizing the device). + * + * The reason is that the permanent and initial MAC addresses also must have the + * same address length, so it's unclear what it would mean that the length changes. */ + _LOGD(LOGD_PLATFORM | LOGD_DEVICE, + "hw-addr: read a MAC address with differing length (%s vs. %s)", + priv->hw_addr, + _nm_utils_hwaddr_ntoa(hwaddr, hwaddrlen, TRUE, s_buf, sizeof(s_buf))); + return FALSE; + } + + if (priv->hw_addr && nm_utils_hwaddr_matches(priv->hw_addr, -1, hwaddr, hwaddrlen)) + return FALSE; + + g_free(priv->hw_addr); + priv->hw_addr_len_ = hwaddrlen; + priv->hw_addr = nm_utils_hwaddr_ntoa(hwaddr, hwaddrlen); + + _LOGD(LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); + _notify(self, PROP_HW_ADDRESS); + + if (!priv->hw_addr_initial + || (priv->hw_addr_type == HW_ADDR_TYPE_UNSET && priv->state < NM_DEVICE_STATE_PREPARE + && !nm_device_is_activating(self))) { + /* when we get a hw_addr the first time or while the device + * is not activated (with no explicit hw address set), always + * update our initial hw-address as well. */ + nm_device_update_initial_hw_address(self); + } + return TRUE; } void -nm_device_update_initial_hw_address (NMDevice *self) +nm_device_update_initial_hw_address(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if ( priv->hw_addr - && !nm_streq0 (priv->hw_addr_initial, priv->hw_addr)) { - if ( priv->hw_addr_initial - && priv->hw_addr_type != HW_ADDR_TYPE_UNSET) { - /* once we have the initial hw address set, we only allow - * update if the currently type is "unset". */ - return; - } - g_free (priv->hw_addr_initial); - priv->hw_addr_initial = g_strdup (priv->hw_addr); - _LOGD (LOGD_DEVICE, "hw-addr: update initial MAC address %s", - priv->hw_addr_initial); - } + if (priv->hw_addr && !nm_streq0(priv->hw_addr_initial, priv->hw_addr)) { + if (priv->hw_addr_initial && priv->hw_addr_type != HW_ADDR_TYPE_UNSET) { + /* once we have the initial hw address set, we only allow + * update if the currently type is "unset". */ + return; + } + g_free(priv->hw_addr_initial); + priv->hw_addr_initial = g_strdup(priv->hw_addr); + _LOGD(LOGD_DEVICE, "hw-addr: update initial MAC address %s", priv->hw_addr_initial); + } } void -nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; - size_t len = 0; - gboolean success_read; - int ifindex; - const NMPlatformLink *pllink; - const NMConfigDeviceStateData *dev_state; - - if (priv->hw_addr_perm) { - /* the permanent hardware address is only read once and not - * re-read later. - * - * Except during unrealize/realize cycles, where we clear the permanent - * hardware address during unrealization. */ - return; - } - - ifindex = priv->ifindex; - if (ifindex <= 0) - return; - - /* the user is advised to configure stable MAC addresses for software devices via - * UDEV. Thus, check whether the link is fully initialized. */ - pllink = nm_platform_link_get (nm_device_get_platform (self), ifindex); - if ( !pllink - || !pllink->initialized) { - if (!force_freeze) { - /* we can afford to wait. Back off and leave the permanent MAC address - * undecided for now. */ - return; - } - /* try to refresh the link just to give UDEV a bit more time... */ - nm_platform_link_refresh (nm_device_get_platform (self), ifindex); - /* maybe the MAC address changed... */ - nm_device_update_hw_address (self); - } else if (!priv->hw_addr_len) - nm_device_update_hw_address (self); - - if (!priv->hw_addr_len) { - /* we need the current MAC address because we require the permanent MAC address - * to have the same length as the current address. - * - * Abort if there is no current MAC address. */ - return; - } - - success_read = nm_platform_link_get_permanent_address (nm_device_get_platform (self), ifindex, buf, &len); - if (success_read && priv->hw_addr_len == len) { - priv->hw_addr_perm_fake = FALSE; - priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); - _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", - priv->hw_addr_perm); - goto notify_and_out; - } - - /* we failed to read a permanent MAC address, thus we use a fake address, - * that is the current MAC address of the device. - * - * Note that the permanet MAC address of a NMDevice instance does not change - * after being set once. Thus, we use now a fake address and stick to that - * (until we unrealize the device). */ - priv->hw_addr_perm_fake = TRUE; - - /* We also persist our choice of the fake address to the device state - * file to use the same address on restart of NetworkManager. - * First, try to reload the address from the state file. */ - dev_state = nm_config_device_state_get (nm_config_get (), ifindex); - if ( dev_state - && dev_state->perm_hw_addr_fake - && nm_utils_hwaddr_aton (dev_state->perm_hw_addr_fake, buf, priv->hw_addr_len) - && !nm_utils_hwaddr_matches (buf, priv->hw_addr_len, priv->hw_addr, -1)) { - _LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use from statefile: %s, current: %s)", - success_read - ? "read HW addr length of permanent MAC address differs" - : "unable to read permanent MAC address", - dev_state->perm_hw_addr_fake, - priv->hw_addr); - priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len); - goto notify_and_out; - } - - _LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)", - success_read - ? "read HW addr length of permanent MAC address differs" - : "unable to read permanent MAC address", - priv->hw_addr); - priv->hw_addr_perm = g_strdup (priv->hw_addr); +nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_freeze) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + size_t len = 0; + gboolean success_read; + int ifindex; + const NMPlatformLink * pllink; + const NMConfigDeviceStateData *dev_state; + + if (priv->hw_addr_perm) { + /* the permanent hardware address is only read once and not + * re-read later. + * + * Except during unrealize/realize cycles, where we clear the permanent + * hardware address during unrealization. */ + return; + } + + ifindex = priv->ifindex; + if (ifindex <= 0) + return; + + /* the user is advised to configure stable MAC addresses for software devices via + * UDEV. Thus, check whether the link is fully initialized. */ + pllink = nm_platform_link_get(nm_device_get_platform(self), ifindex); + if (!pllink || !pllink->initialized) { + if (!force_freeze) { + /* we can afford to wait. Back off and leave the permanent MAC address + * undecided for now. */ + return; + } + /* try to refresh the link just to give UDEV a bit more time... */ + nm_platform_link_refresh(nm_device_get_platform(self), ifindex); + /* maybe the MAC address changed... */ + nm_device_update_hw_address(self); + } else if (!priv->hw_addr_len) + nm_device_update_hw_address(self); + + if (!priv->hw_addr_len) { + /* we need the current MAC address because we require the permanent MAC address + * to have the same length as the current address. + * + * Abort if there is no current MAC address. */ + return; + } + + success_read = + nm_platform_link_get_permanent_address(nm_device_get_platform(self), ifindex, buf, &len); + if (success_read && priv->hw_addr_len == len) { + priv->hw_addr_perm_fake = FALSE; + priv->hw_addr_perm = nm_utils_hwaddr_ntoa(buf, len); + _LOGD(LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", priv->hw_addr_perm); + goto notify_and_out; + } + + /* we failed to read a permanent MAC address, thus we use a fake address, + * that is the current MAC address of the device. + * + * Note that the permanet MAC address of a NMDevice instance does not change + * after being set once. Thus, we use now a fake address and stick to that + * (until we unrealize the device). */ + priv->hw_addr_perm_fake = TRUE; + + /* We also persist our choice of the fake address to the device state + * file to use the same address on restart of NetworkManager. + * First, try to reload the address from the state file. */ + dev_state = nm_config_device_state_get(nm_config_get(), ifindex); + if (dev_state && dev_state->perm_hw_addr_fake + && nm_utils_hwaddr_aton(dev_state->perm_hw_addr_fake, buf, priv->hw_addr_len) + && !nm_utils_hwaddr_matches(buf, priv->hw_addr_len, priv->hw_addr, -1)) { + _LOGD(LOGD_PLATFORM | LOGD_ETHER, + "hw-addr: %s (use from statefile: %s, current: %s)", + success_read ? "read HW addr length of permanent MAC address differs" + : "unable to read permanent MAC address", + dev_state->perm_hw_addr_fake, + priv->hw_addr); + priv->hw_addr_perm = nm_utils_hwaddr_ntoa(buf, priv->hw_addr_len); + goto notify_and_out; + } + + _LOGD(LOGD_PLATFORM | LOGD_ETHER, + "hw-addr: %s (use current: %s)", + success_read ? "read HW addr length of permanent MAC address differs" + : "unable to read permanent MAC address", + priv->hw_addr); + priv->hw_addr_perm = g_strdup(priv->hw_addr); notify_and_out: - _notify (self, PROP_PERM_HW_ADDRESS); -} - -static const char * -_get_cloned_mac_address_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_addr) -{ - NMSetting *setting; - const char *addr = NULL; - - nm_assert (out_addr && !*out_addr); - - setting = nm_connection_get_setting (connection, - is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); - if (setting) { - addr = is_wifi - ? nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) setting) - : nm_setting_wired_get_cloned_mac_address ((NMSettingWired *) setting); - } - - if (!addr) { - gs_free char *a = NULL; - - a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - is_wifi - ? NM_CON_DEFAULT ("wifi.cloned-mac-address") - : NM_CON_DEFAULT ("ethernet.cloned-mac-address"), - self); - - addr = NM_CLONED_MAC_PRESERVE; - - if (!a) { - if (is_wifi) { - NMSettingMacRandomization v; - - /* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */ - a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("wifi.mac-address-randomization"), - self); - v = _nm_utils_ascii_str_to_int64 (a, 10, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, - NM_SETTING_MAC_RANDOMIZATION_ALWAYS, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT); - if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) - addr = NM_CLONED_MAC_RANDOM; - } - } else if ( NM_CLONED_MAC_IS_SPECIAL (a) - || nm_utils_hwaddr_valid (a, ETH_ALEN)) - addr = *out_addr = g_steal_pointer (&a); - } - - return addr; -} - -static const char * -_get_generate_mac_address_mask_setting (NMDevice *self, NMConnection *connection, gboolean is_wifi, char **out_value) -{ - NMSetting *setting; - const char *value = NULL; - char *a; - - nm_assert (out_value && !*out_value); - - setting = nm_connection_get_setting (connection, - is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); - if (setting) { - value = is_wifi - ? nm_setting_wireless_get_generate_mac_address_mask ((NMSettingWireless *) setting) - : nm_setting_wired_get_generate_mac_address_mask ((NMSettingWired *) setting); - if (value) - return value; - } - - a = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - is_wifi - ? NM_CON_DEFAULT ("wifi.generate-mac-address-mask") - : NM_CON_DEFAULT ("ethernet.generate-mac-address-mask"), - self); - if (!a) - return NULL; - *out_value = a; - return a; + _notify(self, PROP_PERM_HW_ADDRESS); } gboolean -nm_device_hw_addr_is_explict (NMDevice *self) +nm_device_hw_addr_is_explict(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); - return !NM_IN_SET ((HwAddrType) priv->hw_addr_type, - HW_ADDR_TYPE_PERMANENT, - HW_ADDR_TYPE_UNSET); + priv = NM_DEVICE_GET_PRIVATE(self); + return !NM_IN_SET((HwAddrType) priv->hw_addr_type, HW_ADDR_TYPE_PERMANENT, HW_ADDR_TYPE_UNSET); } static gboolean -_hw_addr_matches (NMDevice *self, const guint8 *addr, gsize addr_len) +_hw_addr_matches(NMDevice *self, const guint8 *addr, gsize addr_len) { - const char *cur_addr; + const char *cur_addr; - cur_addr = nm_device_get_hw_address (self); - return cur_addr && nm_utils_hwaddr_matches (addr, addr_len, cur_addr, -1); + cur_addr = nm_device_get_hw_address(self); + return cur_addr && nm_utils_hwaddr_matches(addr, addr_len, cur_addr, -1); } static gboolean -_hw_addr_set (NMDevice *self, - const char *const addr, - const char *const operation, - const char *const detail) -{ - NMDevicePrivate *priv; - gboolean success = FALSE; - int r; - guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; - gsize addr_len; - gboolean was_taken_down = FALSE; - gboolean retry_down; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (addr); - nm_assert (operation); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (!_nm_utils_hwaddr_aton (addr, addr_bytes, sizeof (addr_bytes), &addr_len)) - g_return_val_if_reached (FALSE); - - /* Do nothing if current MAC is same */ - if (_hw_addr_matches (self, addr_bytes, addr_len)) { - _LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed (%s)", addr); - return TRUE; - } - - if ( priv->hw_addr_len - && priv->hw_addr_len != addr_len) { - _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s) failed because of wrong address length (should be %u bytes)", addr, operation, detail, priv->hw_addr_len); - return FALSE; - } - - _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail); - - if (nm_device_get_device_type (self) == NM_DEVICE_TYPE_WIFI) { - /* Always take the device down for Wi-Fi because - * wpa_supplicant needs it to properly detect the MAC - * change. */ - retry_down = FALSE; - was_taken_down = TRUE; - nm_device_take_down (self, FALSE); - } +_hw_addr_set(NMDevice * self, + const char *const addr, + const char *const operation, + const char *const detail) +{ + NMDevicePrivate *priv; + gboolean success = FALSE; + int r; + guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; + gsize addr_len; + gboolean was_taken_down = FALSE; + gboolean retry_down; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(addr); + nm_assert(operation); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (!_nm_utils_hwaddr_aton(addr, addr_bytes, sizeof(addr_bytes), &addr_len)) + g_return_val_if_reached(FALSE); + + /* Do nothing if current MAC is same */ + if (_hw_addr_matches(self, addr_bytes, addr_len)) { + _LOGT(LOGD_DEVICE, "set-hw-addr: no MAC address change needed (%s)", addr); + return TRUE; + } + + if (priv->hw_addr_len && priv->hw_addr_len != addr_len) { + _LOGT(LOGD_DEVICE, + "set-hw-addr: setting MAC address to '%s' (%s, %s) failed because of wrong address " + "length (should be %u bytes)", + addr, + operation, + detail, + priv->hw_addr_len); + return FALSE; + } + + _LOGT(LOGD_DEVICE, + "set-hw-addr: setting MAC address to '%s' (%s, %s)...", + addr, + operation, + detail); + + if (nm_device_get_device_type(self) == NM_DEVICE_TYPE_WIFI) { + /* Always take the device down for Wi-Fi because + * wpa_supplicant needs it to properly detect the MAC + * change. */ + retry_down = FALSE; + was_taken_down = TRUE; + nm_device_take_down(self, FALSE); + } again: - r = nm_platform_link_set_address (nm_device_get_platform (self), nm_device_get_ip_ifindex (self), addr_bytes, addr_len); - success = (r >= 0); - if (!success) { - retry_down = !was_taken_down - && r != -NME_PL_NOT_FOUND - && nm_platform_link_is_up (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self)); - _NMLOG ( ( retry_down - || r == -NME_PL_NOT_FOUND) - ? LOGL_DEBUG - : LOGL_WARN, - LOGD_DEVICE, - "set-hw-addr: failed to %s MAC address to %s (%s) (%s)%s", - operation, addr, detail, - nm_strerror (r), - retry_down ? " (retry with taking down)" : ""); - } else { - /* MAC address successfully changed; update the current MAC to match */ - nm_device_update_hw_address (self); - - if (!_hw_addr_matches (self, addr_bytes, addr_len)) { - gint64 poll_end, now; - - _LOGD (LOGD_DEVICE, - "set-hw-addr: new MAC address %s not successfully %s (%s) (refresh link)", - addr, operation, detail); - - /* The platform call indicated success, however the address is not - * as expected. That is either due to a driver issue (brcmfmac, bgo#770456, - * rh#1374023) or a race where externally the MAC address was reset. - * The race is rather unlikely. - * - * The alternative would be to postpone the activation in case the - * MAC address is not yet ready and poll without blocking. However, - * that is rather complicated and it is not expected that this case - * happens for regular drivers. - * Note that brcmfmac can block NetworkManager for 500 msec while - * taking down the device. Let's add another 100 msec to that. - * - * wait/poll up to 100 msec until it changes. */ - - poll_end = nm_utils_get_monotonic_timestamp_usec () + (100 * 1000); - for (;;) { - if (!nm_platform_link_refresh (nm_device_get_platform (self), nm_device_get_ip_ifindex (self))) - goto handle_fail; - if (!nm_device_update_hw_address (self)) - goto handle_wait; - if (!_hw_addr_matches (self, addr_bytes, addr_len)) - goto handle_fail; - - break; + r = nm_platform_link_set_address(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self), + addr_bytes, + addr_len); + success = (r >= 0); + if (!success) { + retry_down = + !was_taken_down && r != -NME_PL_NOT_FOUND + && nm_platform_link_is_up(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + _NMLOG((retry_down || r == -NME_PL_NOT_FOUND) ? LOGL_DEBUG : LOGL_WARN, + LOGD_DEVICE, + "set-hw-addr: failed to %s MAC address to %s (%s) (%s)%s", + operation, + addr, + detail, + nm_strerror(r), + retry_down ? " (retry with taking down)" : ""); + } else { + /* MAC address successfully changed; update the current MAC to match */ + nm_device_update_hw_address(self); + + if (!_hw_addr_matches(self, addr_bytes, addr_len)) { + gint64 poll_end, now; + + _LOGD(LOGD_DEVICE, + "set-hw-addr: new MAC address %s not successfully %s (%s) (refresh link)", + addr, + operation, + detail); + + /* The platform call indicated success, however the address is not + * as expected. That is either due to a driver issue (brcmfmac, bgo#770456, + * rh#1374023) or a race where externally the MAC address was reset. + * The race is rather unlikely. + * + * The alternative would be to postpone the activation in case the + * MAC address is not yet ready and poll without blocking. However, + * that is rather complicated and it is not expected that this case + * happens for regular drivers. + * Note that brcmfmac can block NetworkManager for 500 msec while + * taking down the device. Let's add another 100 msec to that. + * + * wait/poll up to 100 msec until it changes. */ + + poll_end = nm_utils_get_monotonic_timestamp_usec() + (100 * 1000); + for (;;) { + if (!nm_platform_link_refresh(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self))) + goto handle_fail; + if (!nm_device_update_hw_address(self)) + goto handle_wait; + if (!_hw_addr_matches(self, addr_bytes, addr_len)) + goto handle_fail; + + break; handle_wait: - now = nm_utils_get_monotonic_timestamp_usec (); - if (now < poll_end) { - g_usleep (NM_MIN (poll_end - now, 500)); - continue; - } + now = nm_utils_get_monotonic_timestamp_usec(); + if (now < poll_end) { + g_usleep(NM_MIN(poll_end - now, 500)); + continue; + } handle_fail: - success = FALSE; - break; - } - } - - if (success) { - retry_down = FALSE; - _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", - operation, addr, detail); - } else { - retry_down = !was_taken_down - && nm_platform_link_is_up (nm_device_get_platform (self), - nm_device_get_ip_ifindex (self)); - - _NMLOG ( retry_down - ? LOGL_DEBUG - : LOGL_WARN, - LOGD_DEVICE, - "set-hw-addr: new MAC address %s not successfully %s (%s)%s", - addr, - operation, - detail, - retry_down ? " (retry with taking down)" : ""); - } - } - - if (retry_down) { - /* changing the MAC address failed, but also the device was up (and we did not yet try to take - * it down). Optimally, we change the MAC address without taking the device down, but some - * devices don't like that. So, retry with taking the device down. */ - retry_down = FALSE; - was_taken_down = TRUE; - nm_device_take_down (self, FALSE); - goto again; - } - - if (was_taken_down) { - if (!nm_device_bring_up (self, TRUE, NULL)) - return FALSE; - } - - return success; + success = FALSE; + break; + } + } + + if (success) { + retry_down = FALSE; + _LOGI(LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", operation, addr, detail); + } else { + retry_down = !was_taken_down + && nm_platform_link_is_up(nm_device_get_platform(self), + nm_device_get_ip_ifindex(self)); + + _NMLOG(retry_down ? LOGL_DEBUG : LOGL_WARN, + LOGD_DEVICE, + "set-hw-addr: new MAC address %s not successfully %s (%s)%s", + addr, + operation, + detail, + retry_down ? " (retry with taking down)" : ""); + } + } + + if (retry_down) { + /* changing the MAC address failed, but also the device was up (and we did not yet try to take + * it down). Optimally, we change the MAC address without taking the device down, but some + * devices don't like that. So, retry with taking the device down. */ + retry_down = FALSE; + was_taken_down = TRUE; + nm_device_take_down(self, FALSE); + goto again; + } + + if (was_taken_down) { + if (!nm_device_bring_up(self, TRUE, NULL)) + return FALSE; + } + + return success; } gboolean -nm_device_hw_addr_set (NMDevice *self, - const char *addr, - const char *detail, - gboolean set_permanent) +nm_device_hw_addr_set(NMDevice *self, const char *addr, const char *detail, gboolean set_permanent) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (!addr) - g_return_val_if_reached (FALSE); + if (!addr) + g_return_val_if_reached(FALSE); - if (set_permanent) { - /* The type is set to PERMANENT by NMDeviceVlan when taking the MAC - * address from the parent and by NMDeviceWifi when setting a random MAC - * address during scanning. - */ - priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT; - } + if (set_permanent) { + /* The type is set to PERMANENT by NMDeviceVlan when taking the MAC + * address from the parent and by NMDeviceWifi when setting a random MAC + * address during scanning. + */ + priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT; + } - return _hw_addr_set (self, addr, "set", detail); + return _hw_addr_set(self, addr, "set", detail); } /* @@ -17041,222 +17185,250 @@ nm_device_hw_addr_set (NMDevice *self, * %TRUE otherwise */ static gboolean -_hw_addr_get_cloned (NMDevice *self, NMConnection *connection, gboolean is_wifi, - gboolean *preserve, char **hwaddr, HwAddrType *hwaddr_type, - char **hwaddr_detail, GError **error) -{ - NMDevicePrivate *priv; - gs_free char *addr_setting_free = NULL; - gs_free char *hw_addr_generated = NULL; - gs_free char *generate_mac_address_mask_tmp = NULL; - const char *addr, *addr_setting; - char *addr_out; - HwAddrType type_out; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - priv = NM_DEVICE_GET_PRIVATE (self); - - if (!connection) - g_return_val_if_reached (FALSE); - - addr = addr_setting = _get_cloned_mac_address_setting (self, connection, is_wifi, &addr_setting_free); - - if (nm_streq (addr, NM_CLONED_MAC_PRESERVE)) { - /* "preserve" means to reset the initial MAC address. */ - NM_SET_OUT (preserve, TRUE); - NM_SET_OUT (hwaddr, NULL); - NM_SET_OUT (hwaddr_type, HW_ADDR_TYPE_UNSET); - NM_SET_OUT (hwaddr_detail, g_steal_pointer (&addr_setting_free) ?: g_strdup (addr_setting)); - return TRUE; - } - - if (nm_streq (addr, NM_CLONED_MAC_PERMANENT)) { - gboolean is_fake; - - addr = nm_device_get_permanent_hw_address_full (self, TRUE, &is_fake); - if (is_fake) { - /* Preserve the current address if the permanent address if fake */ - NM_SET_OUT (preserve, TRUE); - NM_SET_OUT (hwaddr, NULL); - NM_SET_OUT (hwaddr_type, HW_ADDR_TYPE_UNSET); - NM_SET_OUT (hwaddr_detail, g_steal_pointer (&addr_setting_free) ?: g_strdup (addr_setting)); - return TRUE; - } else if (!addr) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "failed to retrieve permanent address"); - return FALSE; - } - addr_out = g_strdup (addr); - type_out = HW_ADDR_TYPE_PERMANENT; - } else if (NM_IN_STRSET (addr, NM_CLONED_MAC_RANDOM)) { - if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { - /* hm, we already use a generate MAC address. Most certainly, that is from the same - * activation request, so we should not create a new random address, instead keep - * the current. */ - goto out_no_action; - } - hw_addr_generated = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (self), - _get_generate_mac_address_mask_setting (self, connection, - is_wifi, - &generate_mac_address_mask_tmp)); - if (!hw_addr_generated) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "failed to generate %s MAC address", "random"); - return FALSE; - } - - addr_out = g_steal_pointer (&hw_addr_generated); - type_out = HW_ADDR_TYPE_GENERATED; - } else if (NM_IN_STRSET (addr, NM_CLONED_MAC_STABLE)) { - NMUtilsStableType stable_type; - const char *stable_id; - - if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { - /* hm, we already use a generate MAC address. Most certainly, that is from the same - * activation request, so let's skip creating the stable address anew. */ - goto out_no_action; - } - - stable_id = _get_stable_id (self, connection, &stable_type); - hw_addr_generated = nm_utils_hw_addr_gen_stable_eth (stable_type, stable_id, - nm_device_get_ip_iface (self), - nm_device_get_initial_hw_address (self), - _get_generate_mac_address_mask_setting (self, connection, is_wifi, &generate_mac_address_mask_tmp)); - if (!hw_addr_generated) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "failed to generate %s MAC address", "stable"); - return FALSE; - } - - addr_out = g_steal_pointer (&hw_addr_generated); - type_out = HW_ADDR_TYPE_GENERATED; - } else { - /* this must be a valid address. Otherwise, we shouldn't come here. */ - if (!nm_utils_hwaddr_valid (addr, -1)) - g_return_val_if_reached (FALSE); - - addr_out = g_strdup (addr); - type_out = HW_ADDR_TYPE_EXPLICIT; - } - - NM_SET_OUT (preserve, FALSE); - NM_SET_OUT (hwaddr, addr_out); - NM_SET_OUT (hwaddr_type, type_out); - NM_SET_OUT (hwaddr_detail, g_steal_pointer (&addr_setting_free) ?: g_strdup (addr_setting)); - return TRUE; +_hw_addr_get_cloned(NMDevice * self, + NMConnection *connection, + gboolean is_wifi, + gboolean * preserve, + char ** hwaddr, + HwAddrType * hwaddr_type, + char ** hwaddr_detail, + GError ** error) +{ + NMDevicePrivate *priv; + gs_free char * addr_setting_free = NULL; + gs_free char * hw_addr_generated = NULL; + gs_free char * generate_mac_address_mask_tmp = NULL; + const char * addr, *addr_setting; + char * addr_out; + HwAddrType type_out; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (!connection) + g_return_val_if_reached(FALSE); + + addr = addr_setting = + _prop_get_x_cloned_mac_address(self, connection, is_wifi, &addr_setting_free); + + if (nm_streq(addr, NM_CLONED_MAC_PRESERVE)) { + /* "preserve" means to reset the initial MAC address. */ + NM_SET_OUT(preserve, TRUE); + NM_SET_OUT(hwaddr, NULL); + NM_SET_OUT(hwaddr_type, HW_ADDR_TYPE_UNSET); + NM_SET_OUT(hwaddr_detail, g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + return TRUE; + } + + if (nm_streq(addr, NM_CLONED_MAC_PERMANENT)) { + gboolean is_fake; + + addr = nm_device_get_permanent_hw_address_full(self, TRUE, &is_fake); + if (is_fake) { + /* Preserve the current address if the permanent address if fake */ + NM_SET_OUT(preserve, TRUE); + NM_SET_OUT(hwaddr, NULL); + NM_SET_OUT(hwaddr_type, HW_ADDR_TYPE_UNSET); + NM_SET_OUT(hwaddr_detail, + g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + return TRUE; + } else if (!addr) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "failed to retrieve permanent address"); + return FALSE; + } + addr_out = g_strdup(addr); + type_out = HW_ADDR_TYPE_PERMANENT; + } else if (NM_IN_STRSET(addr, NM_CLONED_MAC_RANDOM)) { + if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { + /* hm, we already use a generate MAC address. Most certainly, that is from the same + * activation request, so we should not create a new random address, instead keep + * the current. */ + goto out_no_action; + } + hw_addr_generated = nm_utils_hw_addr_gen_random_eth( + nm_device_get_initial_hw_address(self), + _prop_get_x_generate_mac_address_mask(self, + connection, + is_wifi, + &generate_mac_address_mask_tmp)); + if (!hw_addr_generated) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "failed to generate %s MAC address", + "random"); + return FALSE; + } + + addr_out = g_steal_pointer(&hw_addr_generated); + type_out = HW_ADDR_TYPE_GENERATED; + } else if (NM_IN_STRSET(addr, NM_CLONED_MAC_STABLE)) { + NMUtilsStableType stable_type; + const char * stable_id; + + if (priv->hw_addr_type == HW_ADDR_TYPE_GENERATED) { + /* hm, we already use a generate MAC address. Most certainly, that is from the same + * activation request, so let's skip creating the stable address anew. */ + goto out_no_action; + } + + stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); + hw_addr_generated = nm_utils_hw_addr_gen_stable_eth( + stable_type, + stable_id, + nm_device_get_ip_iface(self), + nm_device_get_initial_hw_address(self), + _prop_get_x_generate_mac_address_mask(self, + connection, + is_wifi, + &generate_mac_address_mask_tmp)); + if (!hw_addr_generated) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "failed to generate %s MAC address", + "stable"); + return FALSE; + } + + addr_out = g_steal_pointer(&hw_addr_generated); + type_out = HW_ADDR_TYPE_GENERATED; + } else { + /* this must be a valid address. Otherwise, we shouldn't come here. */ + if (!nm_utils_hwaddr_valid(addr, -1)) + g_return_val_if_reached(FALSE); + + addr_out = g_strdup(addr); + type_out = HW_ADDR_TYPE_EXPLICIT; + } + + NM_SET_OUT(preserve, FALSE); + NM_SET_OUT(hwaddr, addr_out); + NM_SET_OUT(hwaddr_type, type_out); + NM_SET_OUT(hwaddr_detail, g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + return TRUE; out_no_action: - NM_SET_OUT (preserve, FALSE); - NM_SET_OUT (hwaddr, NULL); - NM_SET_OUT (hwaddr_type, HW_ADDR_TYPE_UNSET); - NM_SET_OUT (hwaddr_detail, NULL); - return TRUE; + NM_SET_OUT(preserve, FALSE); + NM_SET_OUT(hwaddr, NULL); + NM_SET_OUT(hwaddr_type, HW_ADDR_TYPE_UNSET); + NM_SET_OUT(hwaddr_detail, NULL); + return TRUE; } gboolean -nm_device_hw_addr_get_cloned (NMDevice *self, NMConnection *connection, gboolean is_wifi, - char **hwaddr, gboolean *preserve, GError **error) +nm_device_hw_addr_get_cloned(NMDevice * self, + NMConnection *connection, + gboolean is_wifi, + char ** hwaddr, + gboolean * preserve, + GError ** error) { - if (!_hw_addr_get_cloned (self, connection, is_wifi, preserve, hwaddr, NULL, NULL, error)) - return FALSE; + if (!_hw_addr_get_cloned(self, connection, is_wifi, preserve, hwaddr, NULL, NULL, error)) + return FALSE; - return TRUE; + return TRUE; } gboolean -nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean is_wifi) +nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean is_wifi) { - NMDevicePrivate *priv; - gboolean preserve = FALSE; - gs_free char *hwaddr = NULL; - gs_free char *detail = NULL; - HwAddrType type = HW_ADDR_TYPE_UNSET; - gs_free_error GError *error = NULL; + NMDevicePrivate *priv; + gboolean preserve = FALSE; + gs_free char * hwaddr = NULL; + gs_free char * detail = NULL; + HwAddrType type = HW_ADDR_TYPE_UNSET; + gs_free_error GError *error = NULL; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + priv = NM_DEVICE_GET_PRIVATE(self); - if (!_hw_addr_get_cloned (self, connection, is_wifi, &preserve, &hwaddr, &type, &detail, &error)) { - _LOGW (LOGD_DEVICE, "set-hw-addr: %s", error->message); - return FALSE; - } + if (!_hw_addr_get_cloned(self, + connection, + is_wifi, + &preserve, + &hwaddr, + &type, + &detail, + &error)) { + _LOGW(LOGD_DEVICE, "set-hw-addr: %s", error->message); + return FALSE; + } - if (preserve) - return nm_device_hw_addr_reset (self, detail); + if (preserve) + return nm_device_hw_addr_reset(self, detail); - if (hwaddr) { - priv->hw_addr_type = type; - return _hw_addr_set (self, hwaddr, "set-cloned", detail); - } + if (hwaddr) { + priv->hw_addr_type = type; + return _hw_addr_set(self, hwaddr, "set-cloned", detail); + } - return TRUE; + return TRUE; } gboolean -nm_device_hw_addr_reset (NMDevice *self, const char *detail) +nm_device_hw_addr_reset(NMDevice *self, const char *detail) { - NMDevicePrivate *priv; - const char *addr; + NMDevicePrivate *priv; + const char * addr; - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->hw_addr_type == HW_ADDR_TYPE_UNSET) - return TRUE; + if (priv->hw_addr_type == HW_ADDR_TYPE_UNSET) + return TRUE; - priv->hw_addr_type = HW_ADDR_TYPE_UNSET; - addr = nm_device_get_initial_hw_address (self); - if (!addr) { - /* as hw_addr_type is not UNSET, we expect that we can get an - * initial address to which to reset. */ - g_return_val_if_reached (FALSE); - } + priv->hw_addr_type = HW_ADDR_TYPE_UNSET; + addr = nm_device_get_initial_hw_address(self); + if (!addr) { + /* as hw_addr_type is not UNSET, we expect that we can get an + * initial address to which to reset. */ + g_return_val_if_reached(FALSE); + } - return _hw_addr_set (self, addr, "reset", detail); + return _hw_addr_set(self, addr, "reset", detail); } const char * -nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean force_freeze, gboolean *out_is_fake) +nm_device_get_permanent_hw_address_full(NMDevice *self, + gboolean force_freeze, + gboolean *out_is_fake) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - priv = NM_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_GET_PRIVATE(self); - if ( !priv->hw_addr_perm - && force_freeze) { - /* somebody requests a permanent MAC address, but we don't have it set - * yet. We cannot delay it any longer and try to get it without waiting - * for UDEV. */ - nm_device_update_permanent_hw_address (self, TRUE); - } + if (!priv->hw_addr_perm && force_freeze) { + /* somebody requests a permanent MAC address, but we don't have it set + * yet. We cannot delay it any longer and try to get it without waiting + * for UDEV. */ + nm_device_update_permanent_hw_address(self, TRUE); + } - NM_SET_OUT (out_is_fake, priv->hw_addr_perm && priv->hw_addr_perm_fake); - return priv->hw_addr_perm; + NM_SET_OUT(out_is_fake, priv->hw_addr_perm && priv->hw_addr_perm_fake); + return priv->hw_addr_perm; } const char * -nm_device_get_permanent_hw_address (NMDevice *self) +nm_device_get_permanent_hw_address(NMDevice *self) { - return nm_device_get_permanent_hw_address_full (self, TRUE, NULL); + return nm_device_get_permanent_hw_address_full(self, TRUE, NULL); } const char * -nm_device_get_initial_hw_address (NMDevice *self) +nm_device_get_initial_hw_address(NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE(self), NULL); - return NM_DEVICE_GET_PRIVATE (self)->hw_addr_initial; + return NM_DEVICE_GET_PRIVATE(self)->hw_addr_initial; } /** @@ -17281,1167 +17453,1310 @@ nm_device_get_initial_hw_address (NMDevice *self) * Returns: #TRUE if @self matches one of the specs in @specs */ gboolean -nm_device_spec_match_list (NMDevice *self, const GSList *specs) +nm_device_spec_match_list(NMDevice *self, const GSList *specs) { - return nm_device_spec_match_list_full (self, specs, FALSE); + return nm_device_spec_match_list_full(self, specs, FALSE); } int -nm_device_spec_match_list_full (NMDevice *self, const GSList *specs, int no_match_value) -{ - NMDeviceClass *klass; - NMMatchSpecMatchType m; - const char *hw_address = NULL; - gboolean is_fake; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - klass = NM_DEVICE_GET_CLASS (self); - hw_address = nm_device_get_permanent_hw_address_full (self, - !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT), - &is_fake); - - m = nm_match_spec_device (specs, - nm_device_get_iface (self), - nm_device_get_type_description (self), - nm_device_get_driver (self), - nm_device_get_driver_version (self), - is_fake ? NULL : hw_address, - klass->get_s390_subchannels ? klass->get_s390_subchannels (self) : NULL, - nm_dhcp_manager_get_config (nm_dhcp_manager_get ())); - - switch (m) { - case NM_MATCH_SPEC_MATCH: - return TRUE; - case NM_MATCH_SPEC_NEG_MATCH: - return FALSE; - case NM_MATCH_SPEC_NO_MATCH: - return no_match_value; - } - nm_assert_not_reached (); - return no_match_value; +nm_device_spec_match_list_full(NMDevice *self, const GSList *specs, int no_match_value) +{ + NMDeviceClass * klass; + NMMatchSpecMatchType m; + const char * hw_address = NULL; + gboolean is_fake; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + klass = NM_DEVICE_GET_CLASS(self); + hw_address = nm_device_get_permanent_hw_address_full( + self, + !nm_device_get_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT), + &is_fake); + + m = nm_match_spec_device(specs, + nm_device_get_iface(self), + nm_device_get_type_description(self), + nm_device_get_driver(self), + nm_device_get_driver_version(self), + is_fake ? NULL : hw_address, + klass->get_s390_subchannels ? klass->get_s390_subchannels(self) : NULL, + nm_dhcp_manager_get_config(nm_dhcp_manager_get())); + + switch (m) { + case NM_MATCH_SPEC_MATCH: + return TRUE; + case NM_MATCH_SPEC_NEG_MATCH: + return FALSE; + case NM_MATCH_SPEC_NO_MATCH: + return no_match_value; + } + nm_assert_not_reached(); + return no_match_value; } guint -nm_device_get_supplicant_timeout (NMDevice *self) +nm_device_get_supplicant_timeout(NMDevice *self) { - NMConnection *connection; - NMSetting8021x *s_8021x; - int timeout; + NMConnection * connection; + NMSetting8021x *s_8021x; + int timeout; #define SUPPLICANT_DEFAULT_TIMEOUT 25 - g_return_val_if_fail (NM_IS_DEVICE (self), SUPPLICANT_DEFAULT_TIMEOUT); + g_return_val_if_fail(NM_IS_DEVICE(self), SUPPLICANT_DEFAULT_TIMEOUT); - connection = nm_device_get_applied_connection (self); + connection = nm_device_get_applied_connection(self); - g_return_val_if_fail (connection, SUPPLICANT_DEFAULT_TIMEOUT); + g_return_val_if_fail(connection, SUPPLICANT_DEFAULT_TIMEOUT); - s_8021x = nm_connection_get_setting_802_1x (connection); - if (s_8021x) { - timeout = nm_setting_802_1x_get_auth_timeout (s_8021x); - if (timeout > 0) - return timeout; - } + s_8021x = nm_connection_get_setting_802_1x(connection); + if (s_8021x) { + timeout = nm_setting_802_1x_get_auth_timeout(s_8021x); + if (timeout > 0) + return timeout; + } - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("802-1x.auth-timeout"), - self, - 1, - G_MAXINT32, - SUPPLICANT_DEFAULT_TIMEOUT); + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("802-1x.auth-timeout"), + self, + 1, + G_MAXINT32, + SUPPLICANT_DEFAULT_TIMEOUT); } gboolean -nm_device_auth_retries_try_next (NMDevice *self) -{ - NMDevicePrivate *priv; - NMSettingConnection *s_con; - int auth_retries; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - priv = NM_DEVICE_GET_PRIVATE (self); - auth_retries = priv->auth_retries; - - if (G_UNLIKELY (auth_retries == NM_DEVICE_AUTH_RETRIES_UNSET)) { - auth_retries = -1; - - s_con = nm_device_get_applied_setting (self, NM_TYPE_SETTING_CONNECTION); - if (s_con) - auth_retries = nm_setting_connection_get_auth_retries (s_con); - - if (auth_retries == -1) { - auth_retries = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - NM_CON_DEFAULT ("connection.auth-retries"), - self, - -1, G_MAXINT32, -1); - } - - if (auth_retries == 0) - auth_retries = NM_DEVICE_AUTH_RETRIES_INFINITY; - else if (auth_retries == -1) - auth_retries = NM_DEVICE_AUTH_RETRIES_DEFAULT; - else - nm_assert (auth_retries > 0); - - priv->auth_retries = auth_retries; - } - - if (auth_retries == NM_DEVICE_AUTH_RETRIES_INFINITY) - return TRUE; - if (auth_retries <= 0) { - nm_assert (auth_retries == 0); - return FALSE; - } - priv->auth_retries--; - return TRUE; +nm_device_auth_retries_try_next(NMDevice *self) +{ + NMDevicePrivate * priv; + NMSettingConnection *s_con; + int auth_retries; + + g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); + + priv = NM_DEVICE_GET_PRIVATE(self); + auth_retries = priv->auth_retries; + + if (G_UNLIKELY(auth_retries == NM_DEVICE_AUTH_RETRIES_UNSET)) { + auth_retries = -1; + + s_con = nm_device_get_applied_setting(self, NM_TYPE_SETTING_CONNECTION); + if (s_con) + auth_retries = nm_setting_connection_get_auth_retries(s_con); + + if (auth_retries == -1) { + auth_retries = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.auth-retries"), + self, + -1, + G_MAXINT32, + -1); + } + + if (auth_retries == 0) + auth_retries = NM_DEVICE_AUTH_RETRIES_INFINITY; + else if (auth_retries == -1) + auth_retries = NM_DEVICE_AUTH_RETRIES_DEFAULT; + else + nm_assert(auth_retries > 0); + + priv->auth_retries = auth_retries; + } + + if (auth_retries == NM_DEVICE_AUTH_RETRIES_INFINITY) + return TRUE; + if (auth_retries <= 0) { + nm_assert(auth_retries == 0); + return FALSE; + } + priv->auth_retries--; + return TRUE; } /*****************************************************************************/ static const char * -_activation_func_to_string (ActivationHandleFunc func) +_activation_func_to_string(ActivationHandleFunc func) { #define FUNC_TO_STRING_CHECK_AND_RETURN(func, f) \ - G_STMT_START { \ - if ((func) == (f)) \ - return #f; \ - } G_STMT_END - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage1_device_prepare); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage2_device_config); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage3_ip_config_start); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip_config_timeout_4); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage4_ip_config_timeout_6); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip_config_result_4); - FUNC_TO_STRING_CHECK_AND_RETURN (func, activate_stage5_ip_config_result_6); - g_return_val_if_reached ("unknown"); + G_STMT_START \ + { \ + if ((func) == (f)) \ + return #f; \ + } \ + G_STMT_END + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage1_device_prepare); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage2_device_config); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage3_ip_config_start); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage4_ip_config_timeout_4); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage4_ip_config_timeout_6); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage5_ip_config_result_4); + FUNC_TO_STRING_CHECK_AND_RETURN(func, activate_stage5_ip_config_result_6); + g_return_val_if_reached("unknown"); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - GVariantBuilder array_builder; - - switch (prop_id) { - case PROP_UDI: - /* UDI is (depending on the device type) a path to sysfs and can contain - * non-UTF-8. - * ip link add name $'d\xccf\\c' type dummy */ - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->udi, - NM_UTILS_STR_UTF8_SAFE_FLAG_NONE)); - break; - case PROP_PATH: - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->path, - NM_UTILS_STR_UTF8_SAFE_FLAG_NONE)); - break; - case PROP_IFACE: - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->iface, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); - break; - case PROP_IP_IFACE: - if (ip_config_valid (priv->state)) { - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (nm_device_get_ip_iface (self), - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); - } else - g_value_set_string (value, NULL); - break; - case PROP_IFINDEX: - g_value_set_int (value, priv->ifindex); - break; - case PROP_DRIVER: - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->driver, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); - break; - case PROP_DRIVER_VERSION: - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->driver_version, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); - break; - case PROP_FIRMWARE_VERSION: - g_value_take_string (value, - nm_utils_str_utf8safe_escape_cp (priv->firmware_version, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); - break; - case PROP_CAPABILITIES: - g_value_set_uint (value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK)); - break; - case PROP_IP4_ADDRESS: - g_value_set_uint (value, priv->ip4_address); - break; - case PROP_CARRIER: - g_value_set_boolean (value, priv->carrier); - break; - case PROP_MTU: - g_value_set_uint (value, priv->mtu); - break; - case PROP_IP4_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip_config_4 : NULL); - break; - case PROP_DHCP4_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp_data_4.config : NULL); - break; - case PROP_IP6_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip_config_6 : NULL); - break; - case PROP_DHCP6_CONFIG: - nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp_data_6.config : NULL); - break; - case PROP_STATE: - g_value_set_uint (value, priv->state); - break; - case PROP_STATE_REASON: - g_value_take_variant (value, - g_variant_new ("(uu)", priv->state, priv->state_reason)); - break; - case PROP_ACTIVE_CONNECTION: - g_value_set_string (value, nm_dbus_track_obj_path_get (&priv->act_request)); - break; - case PROP_DEVICE_TYPE: - g_value_set_uint (value, priv->type); - break; - case PROP_LINK_TYPE: - g_value_set_uint (value, priv->link_type); - break; - case PROP_MANAGED: - /* The managed state exposed on D-Bus only depends on the current device state alone. */ - g_value_set_boolean (value, nm_device_get_state (self) > NM_DEVICE_STATE_UNMANAGED); - break; - case PROP_AUTOCONNECT: - g_value_set_boolean (value, - nm_device_autoconnect_blocked_get (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL) - ? FALSE - : TRUE); - break; - case PROP_FIRMWARE_MISSING: - g_value_set_boolean (value, priv->firmware_missing); - break; - case PROP_NM_PLUGIN_MISSING: - g_value_set_boolean (value, priv->nm_plugin_missing); - break; - case PROP_TYPE_DESC: - g_value_set_string (value, priv->type_desc); - break; - case PROP_RFKILL_TYPE: - g_value_set_uint (value, priv->rfkill_type); - break; - case PROP_AVAILABLE_CONNECTIONS: - nm_dbus_utils_g_value_set_object_path_from_hash (value, - priv->available_connections, - TRUE); - break; - case PROP_PHYSICAL_PORT_ID: - g_value_set_string (value, priv->physical_port_id); - break; - case PROP_MASTER: - g_value_set_object (value, nm_device_get_master (self)); - break; - case PROP_PARENT: - g_value_set_string (value, nm_dbus_track_obj_path_get (&priv->parent_device)); - break; - case PROP_HW_ADDRESS: - g_value_set_string (value, priv->hw_addr); - break; - case PROP_PERM_HW_ADDRESS: { - const char *perm_hw_addr; - gboolean perm_hw_addr_is_fake; - - perm_hw_addr = nm_device_get_permanent_hw_address_full (self, FALSE, &perm_hw_addr_is_fake); - /* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */ - g_value_set_string (value, perm_hw_addr && !perm_hw_addr_is_fake ? perm_hw_addr : NULL); - break; - } - case PROP_HAS_PENDING_ACTION: - g_value_set_boolean (value, nm_device_has_pending_action (self)); - break; - case PROP_METERED: - g_value_set_uint (value, priv->metered); - break; - case PROP_LLDP_NEIGHBORS: - if (priv->lldp_listener) - g_value_set_variant (value, nm_lldp_listener_get_neighbors (priv->lldp_listener)); - else { - g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); - g_value_take_variant (value, g_variant_builder_end (&array_builder)); - } - break; - case PROP_REAL: - g_value_set_boolean (value, nm_device_is_real (self)); - break; - case PROP_SLAVES: { - CList *slave_iter; - char **slave_list; - gsize i, n; - - n = c_list_length (&priv->slaves); - slave_list = g_new (char *, n + 1); - i = 0; - c_list_for_each (slave_iter, &priv->slaves) { - SlaveInfo *info = c_list_entry (slave_iter, SlaveInfo, lst_slave); - const char *path; - - if (!NM_DEVICE_GET_PRIVATE (info->slave)->is_enslaved) - continue; - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (info->slave)); - if (path) - slave_list[i++] = g_strdup (path); - } - nm_assert (i <= n); - slave_list[i] = NULL; - g_value_take_boxed (value, slave_list); - break; - } - case PROP_STATISTICS_REFRESH_RATE_MS: - g_value_set_uint (value, priv->stats.refresh_rate_ms); - break; - case PROP_STATISTICS_TX_BYTES: - g_value_set_uint64 (value, priv->stats.tx_bytes); - break; - case PROP_STATISTICS_RX_BYTES: - g_value_set_uint64 (value, priv->stats.rx_bytes); - break; - case PROP_IP4_CONNECTIVITY: - g_value_set_uint (value, priv->concheck_x[1].state); - break; - case PROP_IP6_CONNECTIVITY: - g_value_set_uint (value, priv->concheck_x[0].state); - break; - case PROP_INTERFACE_FLAGS: - g_value_set_uint (value, priv->interface_flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDevice * self = NM_DEVICE(object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + GVariantBuilder array_builder; + + switch (prop_id) { + case PROP_UDI: + /* UDI is (depending on the device type) a path to sysfs and can contain + * non-UTF-8. + * ip link add name $'d\xccf\\c' type dummy */ + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->udi, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE)); + break; + case PROP_PATH: + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->path, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE)); + break; + case PROP_IFACE: + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->iface, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); + break; + case PROP_IP_IFACE: + if (ip_config_valid(priv->state)) { + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(nm_device_get_ip_iface(self), + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); + } else + g_value_set_string(value, NULL); + break; + case PROP_IFINDEX: + g_value_set_int(value, priv->ifindex); + break; + case PROP_DRIVER: + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->driver, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); + break; + case PROP_DRIVER_VERSION: + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->driver_version, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); + break; + case PROP_FIRMWARE_VERSION: + g_value_take_string( + value, + nm_utils_str_utf8safe_escape_cp(priv->firmware_version, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL)); + break; + case PROP_CAPABILITIES: + g_value_set_uint(value, (priv->capabilities & ~NM_DEVICE_CAP_INTERNAL_MASK)); + break; + case PROP_IP4_ADDRESS: + g_value_set_variant(value, nm_g_variant_singleton_u_0()); + break; + case PROP_CARRIER: + g_value_set_boolean(value, priv->carrier); + break; + case PROP_MTU: + g_value_set_uint(value, priv->mtu); + break; + case PROP_IP4_CONFIG: + nm_dbus_utils_g_value_set_object_path(value, + ip_config_valid(priv->state) ? priv->ip_config_4 + : NULL); + break; + case PROP_DHCP4_CONFIG: + nm_dbus_utils_g_value_set_object_path( + value, + ip_config_valid(priv->state) ? priv->dhcp_data_4.config : NULL); + break; + case PROP_IP6_CONFIG: + nm_dbus_utils_g_value_set_object_path(value, + ip_config_valid(priv->state) ? priv->ip_config_6 + : NULL); + break; + case PROP_DHCP6_CONFIG: + nm_dbus_utils_g_value_set_object_path( + value, + ip_config_valid(priv->state) ? priv->dhcp_data_6.config : NULL); + break; + case PROP_STATE: + g_value_set_uint(value, priv->state); + break; + case PROP_STATE_REASON: + g_value_take_variant(value, g_variant_new("(uu)", priv->state, priv->state_reason)); + break; + case PROP_ACTIVE_CONNECTION: + g_value_set_string(value, nm_dbus_track_obj_path_get(&priv->act_request)); + break; + case PROP_DEVICE_TYPE: + g_value_set_uint(value, priv->type); + break; + case PROP_LINK_TYPE: + g_value_set_uint(value, priv->link_type); + break; + case PROP_MANAGED: + /* The managed state exposed on D-Bus only depends on the current device state alone. */ + g_value_set_boolean(value, nm_device_get_state(self) > NM_DEVICE_STATE_UNMANAGED); + break; + case PROP_AUTOCONNECT: + g_value_set_boolean( + value, + nm_device_autoconnect_blocked_get(self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL) ? FALSE + : TRUE); + break; + case PROP_FIRMWARE_MISSING: + g_value_set_boolean(value, priv->firmware_missing); + break; + case PROP_NM_PLUGIN_MISSING: + g_value_set_boolean(value, priv->nm_plugin_missing); + break; + case PROP_TYPE_DESC: + g_value_set_string(value, priv->type_desc); + break; + case PROP_RFKILL_TYPE: + g_value_set_uint(value, priv->rfkill_type); + break; + case PROP_AVAILABLE_CONNECTIONS: + nm_dbus_utils_g_value_set_object_path_from_hash(value, priv->available_connections, TRUE); + break; + case PROP_PHYSICAL_PORT_ID: + g_value_set_string(value, priv->physical_port_id); + break; + case PROP_MASTER: + g_value_set_object(value, nm_device_get_master(self)); + break; + case PROP_PARENT: + g_value_set_string(value, nm_dbus_track_obj_path_get(&priv->parent_device)); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, priv->hw_addr); + break; + case PROP_PERM_HW_ADDRESS: + { + const char *perm_hw_addr; + gboolean perm_hw_addr_is_fake; + + perm_hw_addr = nm_device_get_permanent_hw_address_full(self, FALSE, &perm_hw_addr_is_fake); + /* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */ + g_value_set_string(value, perm_hw_addr && !perm_hw_addr_is_fake ? perm_hw_addr : NULL); + break; + } + case PROP_HAS_PENDING_ACTION: + g_value_set_boolean(value, nm_device_has_pending_action(self)); + break; + case PROP_METERED: + g_value_set_uint(value, priv->metered); + break; + case PROP_LLDP_NEIGHBORS: + if (priv->lldp_listener) + g_value_set_variant(value, nm_lldp_listener_get_neighbors(priv->lldp_listener)); + else { + g_variant_builder_init(&array_builder, G_VARIANT_TYPE("aa{sv}")); + g_value_take_variant(value, g_variant_builder_end(&array_builder)); + } + break; + case PROP_REAL: + g_value_set_boolean(value, nm_device_is_real(self)); + break; + case PROP_SLAVES: + { + CList *slave_iter; + char **slave_list; + gsize i, n; + + n = c_list_length(&priv->slaves); + slave_list = g_new(char *, n + 1); + i = 0; + c_list_for_each (slave_iter, &priv->slaves) { + SlaveInfo * info = c_list_entry(slave_iter, SlaveInfo, lst_slave); + const char *path; + + if (!NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved) + continue; + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(info->slave)); + if (path) + slave_list[i++] = g_strdup(path); + } + nm_assert(i <= n); + slave_list[i] = NULL; + g_value_take_boxed(value, slave_list); + break; + } + case PROP_STATISTICS_REFRESH_RATE_MS: + g_value_set_uint(value, priv->stats.refresh_rate_ms); + break; + case PROP_STATISTICS_TX_BYTES: + g_value_set_uint64(value, priv->stats.tx_bytes); + break; + case PROP_STATISTICS_RX_BYTES: + g_value_set_uint64(value, priv->stats.rx_bytes); + break; + case PROP_IP4_CONNECTIVITY: + g_value_set_uint(value, priv->concheck_x[1].state); + break; + case PROP_IP6_CONNECTIVITY: + g_value_set_uint(value, priv->concheck_x[0].state); + break; + case PROP_INTERFACE_FLAGS: + g_value_set_uint(value, priv->interface_flags); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMDevice *self = (NMDevice *) object; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_UDI: - /* construct-only */ - priv->udi = g_value_dup_string (value); - break; - case PROP_IFACE: - /* construct-only */ - priv->iface = g_value_dup_string (value); - break; - case PROP_DRIVER: - /* construct-only */ - priv->driver = g_value_dup_string (value); - break; - case PROP_MANAGED: - /* via D-Bus */ - if (nm_device_is_real (self)) { - gboolean managed; - NMDeviceStateReason reason; - - managed = g_value_get_boolean (value); - if (managed) { - reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; - if (NM_IN_SET_TYPED (NMDeviceSysIfaceState, - priv->sys_iface_state, - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_REMOVED)) - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_ASSUME); - } else { - reason = NM_DEVICE_STATE_REASON_REMOVED; - nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_REMOVED); - } - nm_device_set_unmanaged_by_flags (self, - NM_UNMANAGED_USER_EXPLICIT, - !managed, - reason); - } - break; - case PROP_AUTOCONNECT: - /* via D-Bus */ - if (g_value_get_boolean (value)) - nm_device_autoconnect_blocked_unset (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL); - else - nm_device_autoconnect_blocked_set (self, NM_DEVICE_AUTOCONNECT_BLOCKED_USER); - break; - case PROP_NM_PLUGIN_MISSING: - /* construct-only */ - priv->nm_plugin_missing = g_value_get_boolean (value); - break; - case PROP_DEVICE_TYPE: - /* construct-only */ - nm_assert (priv->type == NM_DEVICE_TYPE_UNKNOWN); - priv->type = g_value_get_uint (value); - nm_assert (priv->type > NM_DEVICE_TYPE_UNKNOWN); - nm_assert (priv->type <= NM_DEVICE_TYPE_VRF); - break; - case PROP_LINK_TYPE: - /* construct-only */ - nm_assert (priv->link_type == NM_LINK_TYPE_NONE); - priv->link_type = g_value_get_uint (value); - break; - case PROP_TYPE_DESC: - /* construct-only */ - priv->type_desc = g_value_dup_string (value); - break; - case PROP_RFKILL_TYPE: - /* construct-only */ - priv->rfkill_type = g_value_get_uint (value); - break; - case PROP_PERM_HW_ADDRESS: - /* construct-only */ - priv->hw_addr_perm = g_value_dup_string (value); - break; - case PROP_STATISTICS_REFRESH_RATE_MS: - /* via D-Bus */ - _stats_set_refresh_rate (self, g_value_get_uint (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMDevice * self = (NMDevice *) object; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_UDI: + /* construct-only */ + priv->udi = g_value_dup_string(value); + break; + case PROP_IFACE: + /* construct-only */ + priv->iface_ = g_value_dup_string(value); + break; + case PROP_DRIVER: + /* construct-only */ + priv->driver = g_value_dup_string(value); + break; + case PROP_MANAGED: + /* via D-Bus */ + if (nm_device_is_real(self)) { + gboolean managed; + NMDeviceStateReason reason; + + managed = g_value_get_boolean(value); + if (managed) { + reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; + if (NM_IN_SET_TYPED(NMDeviceSysIfaceState, + priv->sys_iface_state, + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_REMOVED)) + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_ASSUME); + } else { + reason = NM_DEVICE_STATE_REASON_REMOVED; + nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_REMOVED); + } + nm_device_set_unmanaged_by_flags(self, NM_UNMANAGED_USER_EXPLICIT, !managed, reason); + } + break; + case PROP_AUTOCONNECT: + /* via D-Bus */ + if (g_value_get_boolean(value)) + nm_device_autoconnect_blocked_unset(self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL); + else + nm_device_autoconnect_blocked_set(self, NM_DEVICE_AUTOCONNECT_BLOCKED_USER); + break; + case PROP_NM_PLUGIN_MISSING: + /* construct-only */ + priv->nm_plugin_missing = g_value_get_boolean(value); + break; + case PROP_DEVICE_TYPE: + /* construct-only */ + nm_assert(priv->type == NM_DEVICE_TYPE_UNKNOWN); + priv->type = g_value_get_uint(value); + nm_assert(priv->type > NM_DEVICE_TYPE_UNKNOWN); + nm_assert(priv->type <= NM_DEVICE_TYPE_VRF); + break; + case PROP_LINK_TYPE: + /* construct-only */ + nm_assert(priv->link_type == NM_LINK_TYPE_NONE); + priv->link_type = g_value_get_uint(value); + break; + case PROP_TYPE_DESC: + /* construct-only */ + priv->type_desc = g_value_dup_string(value); + break; + case PROP_RFKILL_TYPE: + /* construct-only */ + priv->rfkill_type = g_value_get_uint(value); + break; + case PROP_PERM_HW_ADDRESS: + /* construct-only */ + priv->hw_addr_perm = g_value_dup_string(value); + break; + case PROP_STATISTICS_REFRESH_RATE_MS: + /* via D-Bus */ + _stats_set_refresh_rate(self, g_value_get_uint(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_init (NMDevice *self) +nm_device_init(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DEVICE, NMDevicePrivate); + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_DEVICE, NMDevicePrivate); - self->_priv = priv; + self->_priv = priv; - c_list_init (&priv->concheck_lst_head); - c_list_init (&self->devices_lst); - c_list_init (&priv->slaves); + c_list_init(&priv->concheck_lst_head); + c_list_init(&self->devices_lst); + c_list_init(&priv->slaves); - priv->concheck_x[0].state = NM_CONNECTIVITY_UNKNOWN; - priv->concheck_x[1].state = NM_CONNECTIVITY_UNKNOWN; + priv->concheck_x[0].state = NM_CONNECTIVITY_UNKNOWN; + priv->concheck_x[1].state = NM_CONNECTIVITY_UNKNOWN; - nm_dbus_track_obj_path_init (&priv->parent_device, G_OBJECT (self), obj_properties[PROP_PARENT]); - nm_dbus_track_obj_path_init (&priv->act_request, G_OBJECT (self), obj_properties[PROP_ACTIVE_CONNECTION]); + nm_dbus_track_obj_path_init(&priv->parent_device, G_OBJECT(self), obj_properties[PROP_PARENT]); + nm_dbus_track_obj_path_init(&priv->act_request, + G_OBJECT(self), + obj_properties[PROP_ACTIVE_CONNECTION]); - priv->netns = g_object_ref (NM_NETNS_GET); + priv->netns = g_object_ref(NM_NETNS_GET); - priv->autoconnect_blocked_flags = DEFAULT_AUTOCONNECT - ? NM_DEVICE_AUTOCONNECT_BLOCKED_NONE - : NM_DEVICE_AUTOCONNECT_BLOCKED_USER; + priv->autoconnect_blocked_flags = DEFAULT_AUTOCONNECT ? NM_DEVICE_AUTOCONNECT_BLOCKED_NONE + : NM_DEVICE_AUTOCONNECT_BLOCKED_USER; - priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET; - priv->type = NM_DEVICE_TYPE_UNKNOWN; - priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; - priv->state = NM_DEVICE_STATE_UNMANAGED; - priv->state_reason = NM_DEVICE_STATE_REASON_NONE; - priv->rfkill_type = RFKILL_TYPE_UNKNOWN; - priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT; - priv->unmanaged_mask = priv->unmanaged_flags; - priv->available_connections = g_hash_table_new_full (nm_direct_hash, NULL, g_object_unref, NULL); - priv->ip6_saved_properties = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free); - priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; + priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET; + priv->type = NM_DEVICE_TYPE_UNKNOWN; + priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; + priv->state = NM_DEVICE_STATE_UNMANAGED; + priv->state_reason = NM_DEVICE_STATE_REASON_NONE; + priv->rfkill_type = RFKILL_TYPE_UNKNOWN; + priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT; + priv->unmanaged_mask = priv->unmanaged_flags; + priv->available_connections = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL); + priv->ip6_saved_properties = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, g_free); + priv->sys_iface_state_ = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL; - priv->v4_commit_first_time = TRUE; - priv->v6_commit_first_time = TRUE; + priv->v4_commit_first_time = TRUE; + priv->v6_commit_first_time = TRUE; } -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) +static GObject * +constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params) { - GObject *object; - GObjectClass *klass; - NMDevice *self; - NMDevicePrivate *priv; - const NMPlatformLink *pllink; + GObject * object; + GObjectClass * klass; + NMDevice * self; + NMDevicePrivate * priv; + const NMPlatformLink *pllink; - klass = G_OBJECT_CLASS (nm_device_parent_class); - object = klass->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; + klass = G_OBJECT_CLASS(nm_device_parent_class); + object = klass->constructor(type, n_construct_params, construct_params); + if (!object) + return NULL; - self = NM_DEVICE (object); - priv = NM_DEVICE_GET_PRIVATE (self); + self = NM_DEVICE(object); + priv = NM_DEVICE_GET_PRIVATE(self); - if ( priv->iface - && G_LIKELY (!nm_utils_get_testing ())) { - pllink = nm_platform_link_get_by_ifname (nm_device_get_platform (self), priv->iface); + if (priv->iface && G_LIKELY(!nm_utils_get_testing())) { + pllink = nm_platform_link_get_by_ifname(nm_device_get_platform(self), priv->iface); - if (pllink && link_type_compatible (self, pllink->type, NULL, NULL)) { - priv->ifindex = pllink->ifindex; - priv->up = NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP); - } - } + if (pllink && link_type_compatible(self, pllink->type, NULL, NULL)) { + _set_ifindex(self, pllink->ifindex, FALSE); + priv->up = NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP); + } + } - if (priv->hw_addr_perm) { - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; - gsize l; + if (priv->hw_addr_perm) { + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; - if (!_nm_utils_hwaddr_aton (priv->hw_addr_perm, buf, sizeof (buf), &l)) { - nm_clear_g_free (&priv->hw_addr_perm); - g_return_val_if_reached (object); - } + if (!_nm_utils_hwaddr_aton(priv->hw_addr_perm, buf, sizeof(buf), &l)) { + nm_clear_g_free(&priv->hw_addr_perm); + g_return_val_if_reached(object); + } - priv->hw_addr_len_ = l; - priv->hw_addr = nm_utils_hwaddr_ntoa (buf, l); - _LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm); - } + priv->hw_addr_len_ = l; + priv->hw_addr = nm_utils_hwaddr_ntoa(buf, l); + _LOGT(LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm); + } - return object; + return object; } static void -constructed (GObject *object) -{ - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform; - - if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) - priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); - - /* Watch for external IP config changes */ - platform = nm_device_get_platform (self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ipx_changed), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ipx_changed), self); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self); - - priv->manager = g_object_ref (NM_MANAGER_GET); - priv->settings = g_object_ref (NM_SETTINGS_GET); - - g_signal_connect (priv->settings, - NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (cp_connection_added), - self); - g_signal_connect (priv->settings, - NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, - G_CALLBACK (cp_connection_updated), - self); - g_signal_connect (priv->settings, - NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, - G_CALLBACK (cp_connection_removed), - self); - - G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); - - _LOGD (LOGD_DEVICE, "constructed (%s)", G_OBJECT_TYPE_NAME (self)); +constructed(GObject *object) +{ + NMDevice * self = NM_DEVICE(object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform * platform; + + if (NM_DEVICE_GET_CLASS(self)->get_generic_capabilities) + priv->capabilities |= NM_DEVICE_GET_CLASS(self)->get_generic_capabilities(self); + + /* Watch for external IP config changes */ + platform = nm_device_get_platform(self); + g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + G_CALLBACK(device_ipx_changed), + self); + g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + G_CALLBACK(device_ipx_changed), + self); + g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, + G_CALLBACK(device_ipx_changed), + self); + g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, + G_CALLBACK(device_ipx_changed), + self); + g_signal_connect(platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK(link_changed_cb), self); + + priv->manager = g_object_ref(NM_MANAGER_GET); + priv->settings = g_object_ref(NM_SETTINGS_GET); + + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK(cp_connection_added), + self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + G_CALLBACK(cp_connection_updated), + self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_CALLBACK(cp_connection_removed), + self); + + G_OBJECT_CLASS(nm_device_parent_class)->constructed(object); + + _LOGD(LOGD_DEVICE, "constructed (%s)", G_OBJECT_TYPE_NAME(self)); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform; - NMDeviceConnectivityHandle *con_handle; - gs_free_error GError *cancelled_error = NULL; + NMDevice * self = NM_DEVICE(object); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMPlatform * platform; + NMDeviceConnectivityHandle *con_handle; + gs_free_error GError *cancelled_error = NULL; - _LOGD (LOGD_DEVICE, "disposing"); + _LOGD(LOGD_DEVICE, "disposing"); - nm_assert (c_list_is_empty (&self->devices_lst)); + nm_assert(c_list_is_empty(&self->devices_lst)); - while ((con_handle = c_list_first_entry (&priv->concheck_lst_head, NMDeviceConnectivityHandle, concheck_lst))) { - if (!cancelled_error) - nm_utils_error_set_cancelled (&cancelled_error, FALSE, "NMDevice"); - concheck_handle_complete (con_handle, cancelled_error); - } + while ((con_handle = c_list_first_entry(&priv->concheck_lst_head, + NMDeviceConnectivityHandle, + concheck_lst))) { + if (!cancelled_error) + nm_utils_error_set_cancelled(&cancelled_error, FALSE, "NMDevice"); + concheck_handle_complete(con_handle, cancelled_error); + } - nm_clear_g_cancellable (&priv->deactivating_cancellable); + nm_clear_g_cancellable(&priv->deactivating_cancellable); - nm_device_assume_state_reset (self); + nm_device_assume_state_reset(self); - _parent_set_ifindex (self, 0, FALSE); + _parent_set_ifindex(self, 0, FALSE); - platform = nm_device_get_platform (self); - g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ipx_changed), self); - g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self); + platform = nm_device_get_platform(self); + g_signal_handlers_disconnect_by_func(platform, G_CALLBACK(device_ipx_changed), self); + g_signal_handlers_disconnect_by_func(platform, G_CALLBACK(link_changed_cb), self); - arp_cleanup (self); + arp_cleanup(self); - nm_clear_g_signal_handler (nm_config_get (), &priv->config_changed_id); + nm_clear_g_signal_handler(nm_config_get(), &priv->config_changed_id); - dispatcher_cleanup (self); + dispatcher_cleanup(self); - nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id); + nm_pacrunner_manager_remove_clear(&priv->pacrunner_conf_id); - _cleanup_generic_pre (self, CLEANUP_TYPE_KEEP); + _cleanup_generic_pre(self, CLEANUP_TYPE_KEEP); - nm_assert (c_list_is_empty (&priv->slaves)); + nm_assert(c_list_is_empty(&priv->slaves)); - /* Let the kernel manage IPv6LL again */ - set_nm_ipv6ll (self, FALSE); + /* Let the kernel manage IPv6LL again */ + set_nm_ipv6ll(self, FALSE); - _cleanup_generic_post (self, CLEANUP_TYPE_KEEP); + _cleanup_generic_post(self, CLEANUP_TYPE_KEEP); - nm_assert (priv->master_ready_id == 0); + nm_assert(priv->master_ready_id == 0); - g_hash_table_remove_all (priv->ip6_saved_properties); + g_hash_table_remove_all(priv->ip6_saved_properties); - nm_clear_g_source (&priv->recheck_assume_id); - nm_clear_g_source (&priv->recheck_available.call_id); + nm_clear_g_source(&priv->recheck_assume_id); + nm_clear_g_source(&priv->recheck_available.call_id); - nm_clear_g_source (&priv->check_delete_unrealized_id); + nm_clear_g_source(&priv->check_delete_unrealized_id); - nm_clear_g_source (&priv->stats.timeout_id); + nm_clear_g_source(&priv->stats.timeout_id); - carrier_disconnected_action_cancel (self); + carrier_disconnected_action_cancel(self); - if (priv->ifindex > 0) { - priv->ifindex = 0; - _notify (self, PROP_IFINDEX); - } + _set_ifindex(self, 0, FALSE); + _set_ifindex(self, 0, TRUE); - if (priv->settings) { - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_added, self); - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_updated, self); - g_signal_handlers_disconnect_by_func (priv->settings, cp_connection_removed, self); - } + if (priv->settings) { + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_added, self); + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_updated, self); + g_signal_handlers_disconnect_by_func(priv->settings, cp_connection_removed, self); + } - available_connections_del_all (self); + available_connections_del_all(self); - if (nm_clear_g_source (&priv->carrier_wait_id)) - nm_device_remove_pending_action (self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); + if (nm_clear_g_source(&priv->carrier_wait_id)) + nm_device_remove_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); - _clear_queued_act_request (priv, - NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); + _clear_queued_act_request(priv, NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); - nm_clear_g_source (&priv->device_link_changed_id); - nm_clear_g_source (&priv->device_ip_link_changed_id); + nm_clear_g_source(&priv->device_link_changed_id); + nm_clear_g_source(&priv->device_ip_link_changed_id); - if (priv->lldp_listener) { - g_signal_handlers_disconnect_by_func (priv->lldp_listener, - G_CALLBACK (lldp_neighbors_changed), - self); - nm_lldp_listener_stop (priv->lldp_listener); - g_clear_object (&priv->lldp_listener); - } + if (priv->lldp_listener) { + g_signal_handlers_disconnect_by_func(priv->lldp_listener, + G_CALLBACK(lldp_neighbors_changed), + self); + nm_lldp_listener_stop(priv->lldp_listener); + g_clear_object(&priv->lldp_listener); + } - nm_clear_g_source (&priv->concheck_x[0].p_cur_id); - nm_clear_g_source (&priv->concheck_x[1].p_cur_id); + nm_clear_g_source(&priv->concheck_x[0].p_cur_id); + nm_clear_g_source(&priv->concheck_x[1].p_cur_id); - nm_assert (!priv->sriov.pending); - if (priv->sriov.next) { - nm_g_slice_free (priv->sriov.next); - priv->sriov.next = NULL; - } + nm_assert(!priv->sriov.pending); + if (priv->sriov.next) { + nm_g_slice_free(priv->sriov.next); + priv->sriov.next = NULL; + } - G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_parent_class)->dispose(object); - if (nm_clear_g_source (&priv->queued_state.id)) { - /* FIXME: we'd expect the queud_state to be already cleared and this statement - * not being necessary. Add this check here to hopefully investigate crash - * rh#1270247. */ - g_return_if_reached (); - } + if (nm_clear_g_source(&priv->queued_state.id)) { + /* FIXME: we'd expect the queud_state to be already cleared and this statement + * not being necessary. Add this check here to hopefully investigate crash + * rh#1270247. */ + g_return_if_reached(); + } } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice * self = NM_DEVICE(object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self)); + _LOGD(LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME(self)); - g_free (priv->hw_addr); - g_free (priv->hw_addr_perm); - g_free (priv->hw_addr_initial); - g_slist_free (priv->pending_actions); - g_slist_free_full (priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); - nm_clear_g_free (&priv->physical_port_id); - g_free (priv->udi); - g_free (priv->path); - g_free (priv->iface); - g_free (priv->ip_iface); - g_free (priv->driver); - g_free (priv->driver_version); - g_free (priv->firmware_version); - g_free (priv->type_desc); - g_free (priv->dhcp_anycast_address); - g_free (priv->current_stable_id); + g_free(priv->hw_addr); + g_free(priv->hw_addr_perm); + g_free(priv->hw_addr_initial); + g_slist_free(priv->pending_actions); + g_slist_free_full(priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); + nm_clear_g_free(&priv->physical_port_id); + g_free(priv->udi); + g_free(priv->path); + g_free(priv->iface_); + g_free(priv->ip_iface_); + g_free(priv->driver); + g_free(priv->driver_version); + g_free(priv->firmware_version); + g_free(priv->type_desc); + g_free(priv->dhcp_anycast_address); + g_free(priv->current_stable_id); - g_hash_table_unref (priv->ip6_saved_properties); - g_hash_table_unref (priv->available_connections); + g_hash_table_unref(priv->ip6_saved_properties); + g_hash_table_unref(priv->available_connections); - nm_dbus_track_obj_path_deinit (&priv->parent_device); - nm_dbus_track_obj_path_deinit (&priv->act_request); + nm_dbus_track_obj_path_deinit(&priv->parent_device); + nm_dbus_track_obj_path_deinit(&priv->act_request); - G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_device_parent_class)->finalize(object); - /* for testing, NMDeviceTest does not invoke NMDevice::constructed, - * and thus @settings might be unset. */ - nm_g_object_unref (priv->settings); - nm_g_object_unref (priv->manager); + /* for testing, NMDeviceTest does not invoke NMDevice::constructed, + * and thus @settings might be unset. */ + nm_g_object_unref(priv->settings); + nm_g_object_unref(priv->manager); - nm_g_object_unref (priv->concheck_mgr); + nm_g_object_unref(priv->concheck_mgr); - g_object_unref (priv->netns); + g_object_unref(priv->netns); } /*****************************************************************************/ -static const GDBusSignalInfo signal_info_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "StateChanged", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("new_state", "u"), - NM_DEFINE_GDBUS_ARG_INFO ("old_state", "u"), - NM_DEFINE_GDBUS_ARG_INFO ("reason", "u"), - ), -); +static const GDBusSignalInfo signal_info_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "StateChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("new_state", "u"), + NM_DEFINE_GDBUS_ARG_INFO("old_state", "u"), + NM_DEFINE_GDBUS_ARG_INFO("reason", "u"), ), ); static const NMDBusInterfaceInfoExtended interface_info_device = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Reapply", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), - NM_DEFINE_GDBUS_ARG_INFO ("version_id", "t"), - NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), - ), - ), - .handle = impl_device_reapply, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetAppliedConnection", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), - NM_DEFINE_GDBUS_ARG_INFO ("version_id", "t"), - ), - ), - .handle = impl_device_get_applied_connection, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Disconnect", - ), - .handle = impl_device_disconnect, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "Delete", - ), - .handle = impl_device_delete, - ), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &signal_info_state_changed, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Udi", "s", NM_DEVICE_UDI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Path", "s", NM_DEVICE_PATH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Interface", "s", NM_DEVICE_IFACE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IpInterface", "s", NM_DEVICE_IP_IFACE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Driver", "s", NM_DEVICE_DRIVER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DriverVersion", "s", NM_DEVICE_DRIVER_VERSION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FirmwareVersion", "s", NM_DEVICE_FIRMWARE_VERSION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Capabilities", "u", NM_DEVICE_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip4Address", "u", NM_DEVICE_IP4_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("State", "u", NM_DEVICE_STATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("StateReason", "(uu)", NM_DEVICE_STATE_REASON), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveConnection", "o", NM_DEVICE_ACTIVE_CONNECTION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip4Config", "o", NM_DEVICE_IP4_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp4Config", "o", NM_DEVICE_DHCP4_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip6Config", "o", NM_DEVICE_IP6_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp6Config", "o", NM_DEVICE_DHCP6_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("Managed", "b", NM_DEVICE_MANAGED, NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_AUDIT_OP_DEVICE_MANAGED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("Autoconnect", "b", NM_DEVICE_AUTOCONNECT, NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_AUDIT_OP_DEVICE_AUTOCONNECT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FirmwareMissing", "b", NM_DEVICE_FIRMWARE_MISSING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NmPluginMissing", "b", NM_DEVICE_NM_PLUGIN_MISSING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DeviceType", "u", NM_DEVICE_DEVICE_TYPE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AvailableConnections", "ao", NM_DEVICE_AVAILABLE_CONNECTIONS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PhysicalPortId", "s", NM_DEVICE_PHYSICAL_PORT_ID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mtu", "u", NM_DEVICE_MTU), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Metered", "u", NM_DEVICE_METERED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("LldpNeighbors", "aa{sv}", NM_DEVICE_LLDP_NEIGHBORS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Real", "b", NM_DEVICE_REAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Ip4Connectivity", "u", NM_DEVICE_IP4_CONNECTIVITY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Ip6Connectivity", "u", NM_DEVICE_IP6_CONNECTIVITY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("InterfaceFlags", "u", NM_DEVICE_INTERFACE_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "Reapply", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("version_id", "t"), + NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), ), ), + .handle = impl_device_reapply, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetAppliedConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("flags", "u"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO("version_id", "t"), ), ), + .handle = impl_device_get_applied_connection, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Disconnect", ), + .handle = impl_device_disconnect, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("Delete", ), + .handle = impl_device_delete, ), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&signal_info_state_changed, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Udi", "s", NM_DEVICE_UDI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Path", "s", NM_DEVICE_PATH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Interface", "s", NM_DEVICE_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IpInterface", + "s", + NM_DEVICE_IP_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Driver", "s", NM_DEVICE_DRIVER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DriverVersion", + "s", + NM_DEVICE_DRIVER_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FirmwareVersion", + "s", + NM_DEVICE_FIRMWARE_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Capabilities", + "u", + NM_DEVICE_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip4Address", + "u", + NM_DEVICE_IP4_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("State", "u", NM_DEVICE_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("StateReason", + "(uu)", + NM_DEVICE_STATE_REASON), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ActiveConnection", + "o", + NM_DEVICE_ACTIVE_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip4Config", + "o", + NM_DEVICE_IP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Dhcp4Config", + "o", + NM_DEVICE_DHCP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip6Config", + "o", + NM_DEVICE_IP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Dhcp6Config", + "o", + NM_DEVICE_DHCP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L("Managed", + "b", + NM_DEVICE_MANAGED, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_MANAGED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L("Autoconnect", + "b", + NM_DEVICE_AUTOCONNECT, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_AUTOCONNECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FirmwareMissing", + "b", + NM_DEVICE_FIRMWARE_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NmPluginMissing", + "b", + NM_DEVICE_NM_PLUGIN_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DeviceType", + "u", + NM_DEVICE_DEVICE_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("AvailableConnections", + "ao", + NM_DEVICE_AVAILABLE_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PhysicalPortId", + "s", + NM_DEVICE_PHYSICAL_PORT_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mtu", "u", NM_DEVICE_MTU), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Metered", "u", NM_DEVICE_METERED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("LldpNeighbors", + "aa{sv}", + NM_DEVICE_LLDP_NEIGHBORS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Real", "b", NM_DEVICE_REAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Connectivity", + "u", + NM_DEVICE_IP4_CONNECTIVITY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip6Connectivity", + "u", + NM_DEVICE_IP6_CONNECTIVITY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InterfaceFlags", + "u", + NM_DEVICE_INTERFACE_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; const NMDBusInterfaceInfoExtended nm_interface_info_device_statistics = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_STATISTICS, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE ("RefreshRateMs", "u", NM_DEVICE_STATISTICS_REFRESH_RATE_MS, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, NM_AUDIT_OP_STATISTICS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("TxBytes", "t", NM_DEVICE_STATISTICS_TX_BYTES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("RxBytes", "t", NM_DEVICE_STATISTICS_RX_BYTES), - ), - ), + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_STATISTICS, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE( + "RefreshRateMs", + "u", + NM_DEVICE_STATISTICS_REFRESH_RATE_MS, + NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, + NM_AUDIT_OP_STATISTICS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("TxBytes", + "t", + NM_DEVICE_STATISTICS_TX_BYTES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RxBytes", + "t", + NM_DEVICE_STATISTICS_RX_BYTES), ), ), }; static void -nm_device_class_init (NMDeviceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/Devices"); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device, - &nm_interface_info_device_statistics); - - object_class->dispose = dispose; - object_class->finalize = finalize; - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->constructor = constructor; - object_class->constructed = constructed; - - klass->link_changed = link_changed; - - klass->is_available = is_available; - klass->act_stage2_config = act_stage2_config; - klass->act_stage3_ip_config_start = act_stage3_ip_config_start; - klass->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout; - - klass->get_type_description = get_type_description; - klass->can_auto_connect = can_auto_connect; - klass->can_update_from_platform_link = can_update_from_platform_link; - klass->check_connection_compatible = check_connection_compatible; - klass->check_connection_available = check_connection_available; - klass->can_unmanaged_external_down = can_unmanaged_external_down; - klass->realize_start_notify = realize_start_notify; - klass->unrealize_notify = unrealize_notify; - klass->carrier_changed_notify = carrier_changed_notify; - klass->get_ip_iface_identifier = get_ip_iface_identifier; - klass->unmanaged_on_quit = unmanaged_on_quit; - klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr; - klass->parent_changed_notify = parent_changed_notify; - klass->can_reapply_change = can_reapply_change; - klass->reapply_connection = reapply_connection; - klass->set_platform_mtu = set_platform_mtu; - - obj_properties[PROP_UDI] = - g_param_spec_string (NM_DEVICE_UDI, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PATH] = - g_param_spec_string (NM_DEVICE_PATH, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IFACE] = - g_param_spec_string (NM_DEVICE_IFACE, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IP_IFACE] = - g_param_spec_string (NM_DEVICE_IP_IFACE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DRIVER] = - g_param_spec_string (NM_DEVICE_DRIVER, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DRIVER_VERSION] = - g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FIRMWARE_VERSION] = - g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_CARRIER] = - g_param_spec_boolean (NM_DEVICE_CARRIER, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_MTU] = - g_param_spec_uint (NM_DEVICE_MTU, "", "", - 0, G_MAXUINT32, 1500, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IP4_ADDRESS] = - g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "", - 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IP4_CONFIG] = - g_param_spec_string (NM_DEVICE_IP4_CONFIG, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DHCP4_CONFIG] = - g_param_spec_string (NM_DEVICE_DHCP4_CONFIG, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IP6_CONFIG] = - g_param_spec_string (NM_DEVICE_IP6_CONFIG, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DHCP6_CONFIG] = - g_param_spec_string (NM_DEVICE_DHCP6_CONFIG, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATE] = - g_param_spec_uint (NM_DEVICE_STATE, "", "", - 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATE_REASON] = - g_param_spec_variant (NM_DEVICE_STATE_REASON, "", "", - G_VARIANT_TYPE ("(uu)"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ACTIVE_CONNECTION] = - g_param_spec_string (NM_DEVICE_ACTIVE_CONNECTION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DEVICE_TYPE] = - g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "", - 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_LINK_TYPE] = - g_param_spec_uint (NM_DEVICE_LINK_TYPE, "", "", - 0, G_MAXUINT32, NM_LINK_TYPE_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_MANAGED] = - g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", - FALSE, - G_PARAM_READWRITE | /* via D-Bus */ - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_AUTOCONNECT] = - g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", - DEFAULT_AUTOCONNECT, - G_PARAM_READWRITE | /* via D-Bus */ - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_FIRMWARE_MISSING] = - g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_NM_PLUGIN_MISSING] = - g_param_spec_boolean (NM_DEVICE_NM_PLUGIN_MISSING, "", "", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_TYPE_DESC] = - g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_RFKILL_TYPE] = - g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "", - RFKILL_TYPE_WLAN, - RFKILL_TYPE_MAX, - RFKILL_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IFINDEX] = - g_param_spec_int (NM_DEVICE_IFINDEX, "", "", - 0, G_MAXINT, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_AVAILABLE_CONNECTIONS] = - g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PHYSICAL_PORT_ID] = - g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_MASTER] = - g_param_spec_object (NM_DEVICE_MASTER, "", "", - NM_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PARENT] = - g_param_spec_string (NM_DEVICE_PARENT, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_PERM_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_PERM_HW_ADDRESS, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_HAS_PENDING_ACTION] = - g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_METERED] = - g_param_spec_uint (NM_DEVICE_METERED, "", "", - 0, G_MAXUINT32, NM_METERED_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_LLDP_NEIGHBORS] = - g_param_spec_variant (NM_DEVICE_LLDP_NEIGHBORS, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_REAL] = - g_param_spec_boolean (NM_DEVICE_REAL, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_SLAVES] = - g_param_spec_boxed (NM_DEVICE_SLAVES, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_STATISTICS_REFRESH_RATE_MS] = - g_param_spec_uint (NM_DEVICE_STATISTICS_REFRESH_RATE_MS, "", "", - 0, UINT32_MAX, 0, - G_PARAM_READWRITE | /* via D-Bus */ - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATISTICS_TX_BYTES] = - g_param_spec_uint64 (NM_DEVICE_STATISTICS_TX_BYTES, "", "", - 0, UINT64_MAX, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_STATISTICS_RX_BYTES] = - g_param_spec_uint64 (NM_DEVICE_STATISTICS_RX_BYTES, "", "", - 0, UINT64_MAX, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_IP4_CONNECTIVITY] = - g_param_spec_uint (NM_DEVICE_IP4_CONNECTIVITY, "", "", - NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_IP6_CONNECTIVITY] = - g_param_spec_uint (NM_DEVICE_IP6_CONNECTIVITY, "", "", - NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_INTERFACE_FLAGS] = - g_param_spec_uint (NM_DEVICE_INTERFACE_FLAGS, "", "", - 0, - G_MAXUINT32, - 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[STATE_CHANGED] = - g_signal_new (NM_DEVICE_STATE_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMDeviceClass, state_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 3, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); - - signals[AUTOCONNECT_ALLOWED] = - g_signal_new (NM_DEVICE_AUTOCONNECT_ALLOWED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, - autoconnect_allowed_accumulator, NULL, NULL, - G_TYPE_BOOLEAN, 0); - - signals[IP4_CONFIG_CHANGED] = - g_signal_new (NM_DEVICE_IP4_CONFIG_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT); - - signals[IP6_CONFIG_CHANGED] = - g_signal_new (NM_DEVICE_IP6_CONFIG_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT); - - signals[IP6_PREFIX_DELEGATED] = - g_signal_new (NM_DEVICE_IP6_PREFIX_DELEGATED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - signals[IP6_SUBNET_NEEDED] = - g_signal_new (NM_DEVICE_IP6_SUBNET_NEEDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - signals[REMOVED] = - g_signal_new (NM_DEVICE_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - signals[RECHECK_AUTO_ACTIVATE] = - g_signal_new (NM_DEVICE_RECHECK_AUTO_ACTIVATE, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - signals[RECHECK_ASSUME] = - g_signal_new (NM_DEVICE_RECHECK_ASSUME, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); +nm_device_class_init(NMDeviceClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + + g_type_class_add_private(object_class, sizeof(NMDevicePrivate)); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/Devices"); + dbus_object_class->interface_infos = + NM_DBUS_INTERFACE_INFOS(&interface_info_device, &nm_interface_info_device_statistics); + + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->constructor = constructor; + object_class->constructed = constructed; + + klass->link_changed = link_changed; + + klass->is_available = is_available; + klass->act_stage2_config = act_stage2_config; + klass->act_stage3_ip_config_start = act_stage3_ip_config_start; + klass->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout; + + klass->get_type_description = get_type_description; + klass->can_auto_connect = can_auto_connect; + klass->can_update_from_platform_link = can_update_from_platform_link; + klass->check_connection_compatible = check_connection_compatible; + klass->check_connection_available = check_connection_available; + klass->can_unmanaged_external_down = can_unmanaged_external_down; + klass->realize_start_notify = realize_start_notify; + klass->unrealize_notify = unrealize_notify; + klass->carrier_changed_notify = carrier_changed_notify; + klass->get_ip_iface_identifier = get_ip_iface_identifier; + klass->unmanaged_on_quit = unmanaged_on_quit; + klass->deactivate_reset_hw_addr = deactivate_reset_hw_addr; + klass->parent_changed_notify = parent_changed_notify; + klass->can_reapply_change = can_reapply_change; + klass->reapply_connection = reapply_connection; + klass->set_platform_mtu = set_platform_mtu; + + obj_properties[PROP_UDI] = + g_param_spec_string(NM_DEVICE_UDI, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PATH] = g_param_spec_string(NM_DEVICE_PATH, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IFACE] = + g_param_spec_string(NM_DEVICE_IFACE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IP_IFACE] = g_param_spec_string(NM_DEVICE_IP_IFACE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DRIVER] = + g_param_spec_string(NM_DEVICE_DRIVER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DRIVER_VERSION] = + g_param_spec_string(NM_DEVICE_DRIVER_VERSION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_FIRMWARE_VERSION] = + g_param_spec_string(NM_DEVICE_FIRMWARE_VERSION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_CAPABILITIES, + "", + "", + 0, + G_MAXUINT32, + NM_DEVICE_CAP_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CARRIER] = g_param_spec_boolean(NM_DEVICE_CARRIER, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_MTU] = g_param_spec_uint(NM_DEVICE_MTU, + "", + "", + 0, + G_MAXUINT32, + 1500, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IP4_ADDRESS] = + g_param_spec_variant(NM_DEVICE_IP4_ADDRESS, + "", + "", + G_VARIANT_TYPE_UINT32, + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IP4_CONFIG] = + g_param_spec_string(NM_DEVICE_IP4_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DHCP4_CONFIG] = + g_param_spec_string(NM_DEVICE_DHCP4_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IP6_CONFIG] = + g_param_spec_string(NM_DEVICE_IP6_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DHCP6_CONFIG] = + g_param_spec_string(NM_DEVICE_DHCP6_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_STATE] = g_param_spec_uint(NM_DEVICE_STATE, + "", + "", + 0, + G_MAXUINT32, + NM_DEVICE_STATE_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_STATE_REASON] = + g_param_spec_variant(NM_DEVICE_STATE_REASON, + "", + "", + G_VARIANT_TYPE("(uu)"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ACTIVE_CONNECTION] = + g_param_spec_string(NM_DEVICE_ACTIVE_CONNECTION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DEVICE_TYPE] = + g_param_spec_uint(NM_DEVICE_DEVICE_TYPE, + "", + "", + 0, + G_MAXUINT32, + NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_LINK_TYPE] = + g_param_spec_uint(NM_DEVICE_LINK_TYPE, + "", + "", + 0, + G_MAXUINT32, + NM_LINK_TYPE_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_MANAGED] = g_param_spec_boolean(NM_DEVICE_MANAGED, + "", + "", + FALSE, + G_PARAM_READWRITE | /* via D-Bus */ + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_AUTOCONNECT] = g_param_spec_boolean(NM_DEVICE_AUTOCONNECT, + "", + "", + DEFAULT_AUTOCONNECT, + G_PARAM_READWRITE | /* via D-Bus */ + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_FIRMWARE_MISSING] = + g_param_spec_boolean(NM_DEVICE_FIRMWARE_MISSING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_NM_PLUGIN_MISSING] = + g_param_spec_boolean(NM_DEVICE_NM_PLUGIN_MISSING, + "", + "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_TYPE_DESC] = + g_param_spec_string(NM_DEVICE_TYPE_DESC, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_RFKILL_TYPE] = + g_param_spec_uint(NM_DEVICE_RFKILL_TYPE, + "", + "", + RFKILL_TYPE_WLAN, + RFKILL_TYPE_MAX, + RFKILL_TYPE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IFINDEX] = g_param_spec_int(NM_DEVICE_IFINDEX, + "", + "", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_AVAILABLE_CONNECTIONS] = + g_param_spec_boxed(NM_DEVICE_AVAILABLE_CONNECTIONS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PHYSICAL_PORT_ID] = + g_param_spec_string(NM_DEVICE_PHYSICAL_PORT_ID, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_MASTER] = g_param_spec_object(NM_DEVICE_MASTER, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PARENT] = g_param_spec_string(NM_DEVICE_PARENT, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PERM_HW_ADDRESS] = + g_param_spec_string(NM_DEVICE_PERM_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_HAS_PENDING_ACTION] = + g_param_spec_boolean(NM_DEVICE_HAS_PENDING_ACTION, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_METERED] = g_param_spec_uint(NM_DEVICE_METERED, + "", + "", + 0, + G_MAXUINT32, + NM_METERED_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_LLDP_NEIGHBORS] = + g_param_spec_variant(NM_DEVICE_LLDP_NEIGHBORS, + "", + "", + G_VARIANT_TYPE("aa{sv}"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_REAL] = g_param_spec_boolean(NM_DEVICE_REAL, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_SLAVES, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STATISTICS_REFRESH_RATE_MS] = + g_param_spec_uint(NM_DEVICE_STATISTICS_REFRESH_RATE_MS, + "", + "", + 0, + UINT32_MAX, + 0, + G_PARAM_READWRITE | /* via D-Bus */ + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_STATISTICS_TX_BYTES] = + g_param_spec_uint64(NM_DEVICE_STATISTICS_TX_BYTES, + "", + "", + 0, + UINT64_MAX, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_STATISTICS_RX_BYTES] = + g_param_spec_uint64(NM_DEVICE_STATISTICS_RX_BYTES, + "", + "", + 0, + UINT64_MAX, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_IP4_CONNECTIVITY] = + g_param_spec_uint(NM_DEVICE_IP4_CONNECTIVITY, + "", + "", + NM_CONNECTIVITY_UNKNOWN, + NM_CONNECTIVITY_FULL, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_IP6_CONNECTIVITY] = + g_param_spec_uint(NM_DEVICE_IP6_CONNECTIVITY, + "", + "", + NM_CONNECTIVITY_UNKNOWN, + NM_CONNECTIVITY_FULL, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_INTERFACE_FLAGS] = + g_param_spec_uint(NM_DEVICE_INTERFACE_FLAGS, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[STATE_CHANGED] = g_signal_new(NM_DEVICE_STATE_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(NMDeviceClass, state_changed), + NULL, + NULL, + NULL, + G_TYPE_NONE, + 3, + G_TYPE_UINT, + G_TYPE_UINT, + G_TYPE_UINT); + + signals[AUTOCONNECT_ALLOWED] = g_signal_new(NM_DEVICE_AUTOCONNECT_ALLOWED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + autoconnect_allowed_accumulator, + NULL, + NULL, + G_TYPE_BOOLEAN, + 0); + + signals[IP4_CONFIG_CHANGED] = g_signal_new(NM_DEVICE_IP4_CONFIG_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_OBJECT, + G_TYPE_OBJECT); + + signals[IP6_CONFIG_CHANGED] = g_signal_new(NM_DEVICE_IP6_CONFIG_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_OBJECT, + G_TYPE_OBJECT); + + signals[IP6_PREFIX_DELEGATED] = g_signal_new(NM_DEVICE_IP6_PREFIX_DELEGATED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + + signals[IP6_SUBNET_NEEDED] = g_signal_new(NM_DEVICE_IP6_SUBNET_NEEDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[REMOVED] = g_signal_new(NM_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[RECHECK_AUTO_ACTIVATE] = g_signal_new(NM_DEVICE_RECHECK_AUTO_ACTIVATE, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[RECHECK_ASSUME] = g_signal_new(NM_DEVICE_RECHECK_ASSUME, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); } /* Connection defaults from plugins */ -NM_CON_DEFAULT_NOP ("cdma.mtu"); -NM_CON_DEFAULT_NOP ("gsm.mtu"); -NM_CON_DEFAULT_NOP ("wifi.powersave"); -NM_CON_DEFAULT_NOP ("wifi.wake-on-wlan"); -NM_CON_DEFAULT_NOP ("wifi-sec.pmf"); -NM_CON_DEFAULT_NOP ("wifi-sec.fils"); +NM_CON_DEFAULT_NOP("cdma.mtu"); +NM_CON_DEFAULT_NOP("gsm.mtu"); +NM_CON_DEFAULT_NOP("wifi.ap-isolation"); +NM_CON_DEFAULT_NOP("wifi.powersave"); +NM_CON_DEFAULT_NOP("wifi.wake-on-wlan"); +NM_CON_DEFAULT_NOP("wifi-sec.pmf"); +NM_CON_DEFAULT_NOP("wifi-sec.fils"); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 36cae7a3..13782417 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2017 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -16,103 +16,103 @@ #include "nm-rfkill-manager.h" #include "NetworkManagerUtils.h" -typedef enum { - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME, - NM_DEVICE_SYS_IFACE_STATE_MANAGED, - - /* the REMOVED state applies when the device is manually set to unmanaged - * or the link was externally removed. In both cases, we move the device - * to UNMANAGED state, without touching the link -- be it, because the link - * is already gone or because we want to release it (give it up). - */ - NM_DEVICE_SYS_IFACE_STATE_REMOVED, +typedef enum _nm_packed { + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME, + NM_DEVICE_SYS_IFACE_STATE_MANAGED, + + /* the REMOVED state applies when the device is manually set to unmanaged + * or the link was externally removed. In both cases, we move the device + * to UNMANAGED state, without touching the link -- be it, because the link + * is already gone or because we want to release it (give it up). + */ + NM_DEVICE_SYS_IFACE_STATE_REMOVED, } NMDeviceSysIfaceState; typedef enum { - NM_DEVICE_MTU_SOURCE_NONE, - NM_DEVICE_MTU_SOURCE_PARENT, - NM_DEVICE_MTU_SOURCE_IP_CONFIG, - NM_DEVICE_MTU_SOURCE_CONNECTION, + NM_DEVICE_MTU_SOURCE_NONE, + NM_DEVICE_MTU_SOURCE_PARENT, + NM_DEVICE_MTU_SOURCE_IP_CONFIG, + NM_DEVICE_MTU_SOURCE_CONNECTION, } NMDeviceMtuSource; static inline NMDeviceStateReason -nm_device_state_reason_check (NMDeviceStateReason reason) +nm_device_state_reason_check(NMDeviceStateReason reason) { - /* the device-state-reason serves mostly informational purpose during a state - * change. In some cases however, decisions are made based on the reason. - * I tend to think that interpreting the state reason to derive some behaviors - * is confusing, because the cause and effect are so far apart. - * - * This function is here to mark source that inspects the reason to make - * a decision -- contrary to places that set the reason. Thus, by grepping - * for nm_device_state_reason_check() you can find the "effect" to a certain - * reason. - */ - return reason; + /* the device-state-reason serves mostly informational purpose during a state + * change. In some cases however, decisions are made based on the reason. + * I tend to think that interpreting the state reason to derive some behaviors + * is confusing, because the cause and effect are so far apart. + * + * This function is here to mark source that inspects the reason to make + * a decision -- contrary to places that set the reason. Thus, by grepping + * for nm_device_state_reason_check() you can find the "effect" to a certain + * reason. + */ + return reason; } -#define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate" -#define NM_PENDING_ACTION_IN_STATE_CHANGE "in-state-change" -#define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available" -#define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait" -#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant" -#define NM_PENDING_ACTION_WIFI_SCAN "wifi-scan" -#define NM_PENDING_ACTION_WAITING_FOR_COMPANION "waiting-for-companion" -#define NM_PENDING_ACTION_LINK_INIT "link-init" +#define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate" +#define NM_PENDING_ACTION_IN_STATE_CHANGE "in-state-change" +#define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available" +#define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait" +#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant" +#define NM_PENDING_ACTION_WIFI_SCAN "wifi-scan" +#define NM_PENDING_ACTION_WAITING_FOR_COMPANION "waiting-for-companion" +#define NM_PENDING_ACTION_LINK_INIT "link-init" #define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-" #define NM_PENDING_ACTIONPREFIX_ACTIVATION "activation-" /* Properties */ -#define NM_DEVICE_UDI "udi" -#define NM_DEVICE_PATH "path" -#define NM_DEVICE_IFACE "interface" -#define NM_DEVICE_IP_IFACE "ip-interface" -#define NM_DEVICE_DRIVER "driver" -#define NM_DEVICE_DRIVER_VERSION "driver-version" -#define NM_DEVICE_FIRMWARE_VERSION "firmware-version" -#define NM_DEVICE_CAPABILITIES "capabilities" -#define NM_DEVICE_CARRIER "carrier" -#define NM_DEVICE_IP4_ADDRESS "ip4-address" -#define NM_DEVICE_IP4_CONFIG "ip4-config" -#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" -#define NM_DEVICE_IP6_CONFIG "ip6-config" -#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config" -#define NM_DEVICE_STATE "state" -#define NM_DEVICE_STATE_REASON "state-reason" -#define NM_DEVICE_ACTIVE_CONNECTION "active-connection" -#define NM_DEVICE_DEVICE_TYPE "device-type" /* ugh */ -#define NM_DEVICE_LINK_TYPE "link-type" -#define NM_DEVICE_MANAGED "managed" -#define NM_DEVICE_AUTOCONNECT "autoconnect" -#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" -#define NM_DEVICE_NM_PLUGIN_MISSING "nm-plugin-missing" +#define NM_DEVICE_UDI "udi" +#define NM_DEVICE_PATH "path" +#define NM_DEVICE_IFACE "interface" +#define NM_DEVICE_IP_IFACE "ip-interface" +#define NM_DEVICE_DRIVER "driver" +#define NM_DEVICE_DRIVER_VERSION "driver-version" +#define NM_DEVICE_FIRMWARE_VERSION "firmware-version" +#define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_CARRIER "carrier" +#define NM_DEVICE_IP4_ADDRESS "ip4-address" +#define NM_DEVICE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" +#define NM_DEVICE_IP6_CONFIG "ip6-config" +#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config" +#define NM_DEVICE_STATE "state" +#define NM_DEVICE_STATE_REASON "state-reason" +#define NM_DEVICE_ACTIVE_CONNECTION "active-connection" +#define NM_DEVICE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_LINK_TYPE "link-type" +#define NM_DEVICE_MANAGED "managed" +#define NM_DEVICE_AUTOCONNECT "autoconnect" +#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_NM_PLUGIN_MISSING "nm-plugin-missing" #define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" -#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" -#define NM_DEVICE_MTU "mtu" -#define NM_DEVICE_HW_ADDRESS "hw-address" +#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" +#define NM_DEVICE_MTU "mtu" +#define NM_DEVICE_HW_ADDRESS "hw-address" /* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet * and NMDeviceWifi. */ -#define NM_DEVICE_PERM_HW_ADDRESS "perm-hw-address" +#define NM_DEVICE_PERM_HW_ADDRESS "perm-hw-address" -#define NM_DEVICE_METERED "metered" -#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors" -#define NM_DEVICE_REAL "real" +#define NM_DEVICE_METERED "metered" +#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors" +#define NM_DEVICE_REAL "real" /* "parent" is exposed on D-Bus by subclasses like NMDeviceIPTunnel */ -#define NM_DEVICE_PARENT "parent" +#define NM_DEVICE_PARENT "parent" /* the "slaves" property is internal in the parent class, but exposed * by the derived classes NMDeviceBond, NMDeviceBridge, NMDeviceTeam, * NMDeviceOvsBridge and NMDeviceOvsPort. */ -#define NM_DEVICE_SLAVES "slaves" /* partially internal */ +#define NM_DEVICE_SLAVES "slaves" /* partially internal */ -#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ -#define NM_DEVICE_MASTER "master" /* Internal only */ +#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ +#define NM_DEVICE_MASTER "master" /* Internal only */ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ @@ -131,16 +131,16 @@ nm_device_state_reason_check (NMDeviceStateReason reason) #define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes" #define NM_DEVICE_STATISTICS_RX_BYTES "rx-bytes" -#define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity" -#define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity" -#define NM_DEVICE_INTERFACE_FLAGS "interface-flags" +#define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity" +#define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity" +#define NM_DEVICE_INTERFACE_FLAGS "interface-flags" -#define NM_TYPE_DEVICE (nm_device_get_type ()) -#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE, NMDevice)) -#define NM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE, NMDeviceClass)) -#define NM_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE)) -#define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE)) -#define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass)) +#define NM_TYPE_DEVICE (nm_device_get_type()) +#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE, NMDevice)) +#define NM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE, NMDeviceClass)) +#define NM_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE)) +#define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE)) +#define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE, NMDeviceClass)) typedef enum NMActStageReturn NMActStageReturn; @@ -150,456 +150,439 @@ typedef enum NMActStageReturn NMActStageReturn; * not be available otherwise. Adding a flag should never make a connection * not available if it would be available otherwise. */ typedef enum { /*< skip >*/ - NM_DEVICE_CHECK_CON_AVAILABLE_NONE = 0, - - /* since NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST is a collection of flags with more fine grained - * parts, this flag in general indicates that this is a user-request. */ - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = (1L << 0), - - /* we also consider devices which have no carrier but are still waiting for the driver - * to detect carrier. Usually, such devices are not yet available, however for a user-request - * they are. They might fail later if carrier doesn't come. */ - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER = (1L << 1), - - /* usually, a profile is only available if the Wi-Fi AP is in range. For an - * explicit user request, we also consider profiles for APs that are not (yet) - * visible. */ - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP = (1L << 2), - - /* a device can be marked as unmanaged for various reasons. Some of these reasons - * are authoritative, others not. Non-authoritative reasons can be overruled by - * `nmcli device set $DEVICE managed yes`. Also, for an explicit user activation - * request we may want to consider the device as managed. This flag makes devices - * that are unmanaged appear available. */ - _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED = (1L << 3), - - /* a collection of flags, that are commonly set for an explicit user-request. */ - NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST - | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER - | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP - | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED, - - NM_DEVICE_CHECK_CON_AVAILABLE_ALL = (1L << 4) - 1, + NM_DEVICE_CHECK_CON_AVAILABLE_NONE = 0, + + /* since NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST is a collection of flags with more fine grained + * parts, this flag in general indicates that this is a user-request. */ + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = (1L << 0), + + /* we also consider devices which have no carrier but are still waiting for the driver + * to detect carrier. Usually, such devices are not yet available, however for a user-request + * they are. They might fail later if carrier doesn't come. */ + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER = (1L << 1), + + /* usually, a profile is only available if the Wi-Fi AP is in range. For an + * explicit user request, we also consider profiles for APs that are not (yet) + * visible. */ + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP = (1L << 2), + + /* a device can be marked as unmanaged for various reasons. Some of these reasons + * are authoritative, others not. Non-authoritative reasons can be overruled by + * `nmcli device set $DEVICE managed yes`. Also, for an explicit user activation + * request we may want to consider the device as managed. This flag makes devices + * that are unmanaged appear available. */ + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED = (1L << 3), + + /* a collection of flags, that are commonly set for an explicit user-request. */ + NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST = + _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST + | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER + | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP + | _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_OVERRULE_UNMANAGED, + + NM_DEVICE_CHECK_CON_AVAILABLE_ALL = (1L << 4) - 1, } NMDeviceCheckConAvailableFlags; struct _NMDevicePrivate; struct _NMDevice { - NMDBusObject parent; - struct _NMDevicePrivate *_priv; - CList devices_lst; + NMDBusObject parent; + struct _NMDevicePrivate *_priv; + CList devices_lst; }; /* The flags have an relaxing meaning, that means, specifying more flags, can make * a device appear more available. It can never make a device less available. */ typedef enum { /*< skip >*/ - NM_DEVICE_CHECK_DEV_AVAILABLE_NONE = 0, + NM_DEVICE_CHECK_DEV_AVAILABLE_NONE = 0, - /* the device is considered available, even if it has no carrier. - * - * For various device types (software devices) we ignore carrier based - * on the type. So, for them, this flag has no effect anyway. */ - _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER = (1L << 0), + /* the device is considered available, even if it has no carrier. + * + * For various device types (software devices) we ignore carrier based + * on the type. So, for them, this flag has no effect anyway. */ + _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER = (1L << 0), - NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST = _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER, + NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST = + _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER, - NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (1L << 1) - 1, + NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (1L << 1) - 1, } NMDeviceCheckDevAvailableFlags; -typedef void (*NMDeviceDeactivateCallback) (NMDevice *self, - GError *error, - gpointer user_data); +typedef void (*NMDeviceDeactivateCallback)(NMDevice *self, GError *error, gpointer user_data); typedef struct _NMDeviceClass { - NMDBusObjectClass parent; - - struct _NMDeviceClass *default_type_description_klass; - const char *default_type_description; - - const char *connection_type_supported; - - /* most device types, can only handle profiles of a particular type. This - * is the connection.type setting, as checked by nm_device_check_connection_compatible() */ - const char *connection_type_check_compatible; - - const NMLinkType *link_types; - - /* if the device MTU is set based on parent's one, this specifies - * a delta in the MTU allowed value due the encapsulation overhead */ - guint16 mtu_parent_delta; - - /* Whether the device type is a master-type. This depends purely on the - * type (NMDeviceClass), not the actual device instance. */ - bool is_master:1; - - void (*state_changed) (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason); - - void (* link_changed) (NMDevice *self, - const NMPlatformLink *pllink); - - /** - * create_and_realize(): - * @self: the #NMDevice - * @connection: the #NMConnection being activated - * @parent: the parent #NMDevice, if any - * @out_plink: on success, a backing kernel network device if one exists. - * The returned pointer is owned by platform and only valid until the - * next platform operation. - * @error: location to store error, or %NULL - * - * Create any backing resources (kernel devices, etc) required for this - * device to activate @connection. If the device is backed by a kernel - * network device, that device should be returned in @out_plink after - * being created. - * - * Returns: %TRUE on success, %FALSE on error - */ - gboolean (*create_and_realize) (NMDevice *self, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error); - - /** - * realize_start_notify(): - * @self: the #NMDevice - * @pllink: the #NMPlatformLink if backed by a kernel netdevice - * - * Hook for derived classes to be notfied during realize_start_setup() - * and perform additional setup. - * - * The default implementation of NMDevice calls link_changed(). - */ - void (*realize_start_notify) (NMDevice *self, - const NMPlatformLink *pllink); - - /** - * unrealize(): - * @self: the #NMDevice - * - * Remove the device backing resources. - */ - gboolean (*unrealize) (NMDevice *self, GError **error); - - /** - * unrealize_notify(): - * @self: the #NMDevice - * - * Hook for derived classes to clear any properties that depend on backing resources - * (kernel devices, etc). This is called by nm_device_unrealize() during unrealization. - */ - void (*unrealize_notify) (NMDevice *self); - - /* Hardware state (IFF_UP) */ - gboolean (*can_unmanaged_external_down) (NMDevice *self); - - /* Carrier state (IFF_LOWER_UP) */ - void (*carrier_changed_notify) (NMDevice *, gboolean carrier); - - gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid); - - NMDeviceCapabilities (* get_generic_capabilities) (NMDevice *self); - - gboolean (* is_available) (NMDevice *self, NMDeviceCheckDevAvailableFlags flags); - - gboolean (* get_enabled) (NMDevice *self); - - void (* set_enabled) (NMDevice *self, gboolean enabled); - - /* let the subclass return additional NMPlatformRoutingRule (in form of NMPObject - * pointers) that shall be added to the rules provided by this device. - * The returned GPtrArray will be g_ptr_array_unref()'ed. The subclass may or - * may not keep an additional reference and return this array again and again. */ - GPtrArray *(*get_extra_rules) (NMDevice *self); - - /* allow derived classes to override the result of nm_device_autoconnect_allowed(). - * If the value changes, the class should call nm_device_emit_recheck_auto_activate(), - * which emits NM_DEVICE_RECHECK_AUTO_ACTIVATE signal. */ - gboolean (* get_autoconnect_allowed) (NMDevice *self); - - gboolean (* can_auto_connect) (NMDevice *self, - NMSettingsConnection *sett_conn, - char **specific_object); - - guint32 (*get_configured_mtu) (NMDevice *self, - NMDeviceMtuSource *out_source, - gboolean *out_force); - - /* allow the subclass to overwrite the routing table. This is mainly useful - * to change from partial mode (route-table=0) to full-sync mode (route-table=254). */ - guint32 (*coerce_route_table) (NMDevice *self, - int addr_family, - guint32 route_table, - gboolean is_user_config); - - const char *(*get_auto_ip_config_method) (NMDevice *self, int addr_family); - - /* Checks whether the connection is compatible with the device using - * only the devices type and characteristics. Does not use any live - * network information like Wi-Fi scan lists etc. - */ - gboolean (* check_connection_compatible) (NMDevice *self, - NMConnection *connection, - GError **error); - - /* Checks whether the connection is likely available to be activated, - * including any live network information like scan lists. The connection - * is checked against the object defined by @specific_object, if given. - * Returns TRUE if the connection is available; FALSE if not. - * - * The passed @flags affect whether a connection is considered - * available or not. Adding more flags, means the connection is - * *more* available. - * - * Specifying @specific_object can only reduce the availability of a connection. - */ - gboolean (* check_connection_available) (NMDevice *self, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error); - - gboolean (* complete_connection) (NMDevice *self, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error); - - NMActStageReturn (* act_stage1_prepare) (NMDevice *self, - NMDeviceStateReason *out_failure_reason); - NMActStageReturn (* act_stage2_config) (NMDevice *self, - NMDeviceStateReason *out_failure_reason); - NMActStageReturn (* act_stage3_ip_config_start) (NMDevice *self, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason); - NMActStageReturn (* act_stage4_ip_config_timeout) (NMDevice *self, - int addr_family, - NMDeviceStateReason *out_failure_reason); - - void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config); - - /* Async deactivating (in the DEACTIVATING phase) */ - void (* deactivate_async) (NMDevice *self, - GCancellable *cancellable, - NMDeviceDeactivateCallback callback, - gpointer user_data); - - void (* deactivate_reset_hw_addr) (NMDevice *self); - - /* Sync deactivating (in the DISCONNECTED phase) */ - void (* deactivate) (NMDevice *self); + NMDBusObjectClass parent; + + struct _NMDeviceClass *default_type_description_klass; + const char * default_type_description; + + const char *connection_type_supported; + + /* most device types, can only handle profiles of a particular type. This + * is the connection.type setting, as checked by nm_device_check_connection_compatible() */ + const char *connection_type_check_compatible; + + const NMLinkType *link_types; + + /* if the device MTU is set based on parent's one, this specifies + * a delta in the MTU allowed value due the encapsulation overhead */ + guint16 mtu_parent_delta; + + /* Whether the device type is a master-type. This depends purely on the + * type (NMDeviceClass), not the actual device instance. */ + bool is_master : 1; + + void (*state_changed)(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason); + + void (*link_changed)(NMDevice *self, const NMPlatformLink *pllink); + + /** + * create_and_realize(): + * @self: the #NMDevice + * @connection: the #NMConnection being activated + * @parent: the parent #NMDevice, if any + * @out_plink: on success, a backing kernel network device if one exists. + * The returned pointer is owned by platform and only valid until the + * next platform operation. + * @error: location to store error, or %NULL + * + * Create any backing resources (kernel devices, etc) required for this + * device to activate @connection. If the device is backed by a kernel + * network device, that device should be returned in @out_plink after + * being created. + * + * Returns: %TRUE on success, %FALSE on error + */ + gboolean (*create_and_realize)(NMDevice * self, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error); + + /** + * realize_start_notify(): + * @self: the #NMDevice + * @pllink: the #NMPlatformLink if backed by a kernel netdevice + * + * Hook for derived classes to be notfied during realize_start_setup() + * and perform additional setup. + * + * The default implementation of NMDevice calls link_changed(). + */ + void (*realize_start_notify)(NMDevice *self, const NMPlatformLink *pllink); + + /** + * unrealize(): + * @self: the #NMDevice + * + * Remove the device backing resources. + */ + gboolean (*unrealize)(NMDevice *self, GError **error); + + /** + * unrealize_notify(): + * @self: the #NMDevice + * + * Hook for derived classes to clear any properties that depend on backing resources + * (kernel devices, etc). This is called by nm_device_unrealize() during unrealization. + */ + void (*unrealize_notify)(NMDevice *self); + + /* Hardware state (IFF_UP) */ + gboolean (*can_unmanaged_external_down)(NMDevice *self); + + /* Carrier state (IFF_LOWER_UP) */ + void (*carrier_changed_notify)(NMDevice *, gboolean carrier); + + gboolean (*get_ip_iface_identifier)(NMDevice *self, NMUtilsIPv6IfaceId *out_iid); + + NMDeviceCapabilities (*get_generic_capabilities)(NMDevice *self); + + gboolean (*is_available)(NMDevice *self, NMDeviceCheckDevAvailableFlags flags); + + gboolean (*get_enabled)(NMDevice *self); + + void (*set_enabled)(NMDevice *self, gboolean enabled); + + /* let the subclass return additional NMPlatformRoutingRule (in form of NMPObject + * pointers) that shall be added to the rules provided by this device. + * The returned GPtrArray will be g_ptr_array_unref()'ed. The subclass may or + * may not keep an additional reference and return this array again and again. */ + GPtrArray *(*get_extra_rules)(NMDevice *self); + + /* allow derived classes to override the result of nm_device_autoconnect_allowed(). + * If the value changes, the class should call nm_device_emit_recheck_auto_activate(), + * which emits NM_DEVICE_RECHECK_AUTO_ACTIVATE signal. */ + gboolean (*get_autoconnect_allowed)(NMDevice *self); + + gboolean (*can_auto_connect)(NMDevice * self, + NMSettingsConnection *sett_conn, + char ** specific_object); + + guint32 (*get_configured_mtu)(NMDevice * self, + NMDeviceMtuSource *out_source, + gboolean * out_force); + + /* allow the subclass to overwrite the routing table. This is mainly useful + * to change from partial mode (route-table=0) to full-sync mode (route-table=254). */ + guint32 (*coerce_route_table)(NMDevice *self, + int addr_family, + guint32 route_table, + gboolean is_user_config); + + const char *(*get_auto_ip_config_method)(NMDevice *self, int addr_family); + + /* Checks whether the connection is compatible with the device using + * only the devices type and characteristics. Does not use any live + * network information like Wi-Fi scan lists etc. + */ + gboolean (*check_connection_compatible)(NMDevice * self, + NMConnection *connection, + GError ** error); + + /* Checks whether the connection is likely available to be activated, + * including any live network information like scan lists. The connection + * is checked against the object defined by @specific_object, if given. + * Returns TRUE if the connection is available; FALSE if not. + * + * The passed @flags affect whether a connection is considered + * available or not. Adding more flags, means the connection is + * *more* available. + * + * Specifying @specific_object can only reduce the availability of a connection. + */ + gboolean (*check_connection_available)(NMDevice * self, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error); + + gboolean (*complete_connection)(NMDevice * self, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error); + + NMActStageReturn (*act_stage1_prepare)(NMDevice *self, NMDeviceStateReason *out_failure_reason); + NMActStageReturn (*act_stage2_config)(NMDevice *self, NMDeviceStateReason *out_failure_reason); + NMActStageReturn (*act_stage3_ip_config_start)(NMDevice * self, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason); + NMActStageReturn (*act_stage4_ip_config_timeout)(NMDevice * self, + int addr_family, + NMDeviceStateReason *out_failure_reason); + + void (*ip4_config_pre_commit)(NMDevice *self, NMIP4Config *config); + + /* Async deactivating (in the DEACTIVATING phase) */ + void (*deactivate_async)(NMDevice * self, + GCancellable * cancellable, + NMDeviceDeactivateCallback callback, + gpointer user_data); + + void (*deactivate_reset_hw_addr)(NMDevice *self); + + /* Sync deactivating (in the DISCONNECTED phase) */ + void (*deactivate)(NMDevice *self); + + const char *(*get_type_description)(NMDevice *self); + + const char *(*get_s390_subchannels)(NMDevice *self); + + /* Update the connection with currently configured L2 settings */ + void (*update_connection)(NMDevice *device, NMConnection *connection); + + gboolean (*master_update_slave_connection)(NMDevice * self, + NMDevice * slave, + NMConnection *connection, + GError ** error); - const char *(*get_type_description) (NMDevice *self); - - const char *(*get_s390_subchannels) (NMDevice *self); - - /* Update the connection with currently configured L2 settings */ - void (* update_connection) (NMDevice *device, NMConnection *connection); - - gboolean (*master_update_slave_connection) (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - GError **error); - - gboolean (* enslave_slave) (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - gboolean configure); - - void (* release_slave) (NMDevice *self, - NMDevice *slave, - gboolean configure); - - void (* parent_changed_notify) (NMDevice *self, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent); - - gboolean (* owns_iface) (NMDevice *self, const char *iface); - - NMConnection * (* new_default_connection) (NMDevice *self); - - gboolean (* unmanaged_on_quit) (NMDevice *self); - - gboolean (* can_reapply_change) (NMDevice *self, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error); - - void (* reapply_connection) (NMDevice *self, - NMConnection *con_old, - NMConnection *con_new); - - guint32 (* get_dhcp_timeout_for_device) (NMDevice *self, - int addr_family); - - gboolean (* get_guessed_metered) (NMDevice *self); - - gboolean (* can_update_from_platform_link) (NMDevice *self, const NMPlatformLink *plink); - - gboolean (* set_platform_mtu) (NMDevice *self, guint32 mtu); - - /* Control whether to call stage1 and stage2 callbacks also for assuming - * a device or for external activations. In this case, the callback must - * take care not to touch the device's configuration. */ - bool act_stage1_prepare_also_for_external_or_assume:1; - bool act_stage2_config_also_for_external_or_assume:1; + gboolean (*enslave_slave)(NMDevice * self, + NMDevice * slave, + NMConnection *connection, + gboolean configure); + + void (*release_slave)(NMDevice *self, NMDevice *slave, gboolean configure); + + void (*parent_changed_notify)(NMDevice *self, + int old_ifindex, + NMDevice *old_parent, + int new_ifindex, + NMDevice *new_parent); + + gboolean (*owns_iface)(NMDevice *self, const char *iface); + + NMConnection *(*new_default_connection)(NMDevice *self); + + gboolean (*unmanaged_on_quit)(NMDevice *self); + + gboolean (*can_reapply_change)(NMDevice * self, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error); + + void (*reapply_connection)(NMDevice *self, NMConnection *con_old, NMConnection *con_new); + + guint32 (*get_dhcp_timeout_for_device)(NMDevice *self, int addr_family); - bool act_stage1_prepare_set_hwaddr_ethernet:1; + gboolean (*get_guessed_metered)(NMDevice *self); + + gboolean (*can_update_from_platform_link)(NMDevice *self, const NMPlatformLink *plink); + + gboolean (*set_platform_mtu)(NMDevice *self, guint32 mtu); + + /* Control whether to call stage1 and stage2 callbacks also for assuming + * a device or for external activations. In this case, the callback must + * take care not to touch the device's configuration. */ + bool act_stage1_prepare_also_for_external_or_assume : 1; + bool act_stage2_config_also_for_external_or_assume : 1; + + bool act_stage1_prepare_set_hwaddr_ethernet : 1; } NMDeviceClass; -GType nm_device_get_type (void); +GType nm_device_get_type(void); -struct _NMDedupMultiIndex *nm_device_get_multi_index (NMDevice *self); -NMNetns *nm_device_get_netns (NMDevice *self); -NMPlatform *nm_device_get_platform (NMDevice *self); +struct _NMDedupMultiIndex *nm_device_get_multi_index(NMDevice *self); +NMNetns * nm_device_get_netns(NMDevice *self); +NMPlatform * nm_device_get_platform(NMDevice *self); -const char * nm_device_get_udi (NMDevice *dev); -const char * nm_device_get_iface (NMDevice *dev); +const char *nm_device_get_udi(NMDevice *dev); +const char *nm_device_get_iface(NMDevice *dev); static inline const char * -_nm_device_get_iface (NMDevice *device) +_nm_device_get_iface(NMDevice *device) { - /* like nm_device_get_iface(), but gracefully accept NULL without - * asserting. */ - return device ? nm_device_get_iface (device) : NULL; + /* like nm_device_get_iface(), but gracefully accept NULL without + * asserting. */ + return device ? nm_device_get_iface(device) : NULL; } -int nm_device_get_ifindex (NMDevice *dev); -gboolean nm_device_is_software (NMDevice *dev); -gboolean nm_device_is_real (NMDevice *dev); -const char * nm_device_get_ip_iface (NMDevice *dev); -const char * nm_device_get_ip_iface_from_platform (NMDevice *dev); -int nm_device_get_ip_ifindex (const NMDevice *dev); -const char * nm_device_get_driver (NMDevice *dev); -const char * nm_device_get_driver_version (NMDevice *dev); -const char * nm_device_get_type_desc (NMDevice *dev); -const char * nm_device_get_type_description (NMDevice *dev); -NMDeviceType nm_device_get_device_type (NMDevice *dev); -NMLinkType nm_device_get_link_type (NMDevice *dev); -NMMetered nm_device_get_metered (NMDevice *dev); - -guint32 nm_device_get_route_table (NMDevice *self, int addr_family); -guint32 nm_device_get_route_metric (NMDevice *dev, int addr_family); - -guint32 nm_device_get_route_metric_default (NMDeviceType device_type); - -const char * nm_device_get_hw_address (NMDevice *dev); -const char * nm_device_get_permanent_hw_address (NMDevice *self); -const char * nm_device_get_permanent_hw_address_full (NMDevice *self, - gboolean force_freeze, - gboolean *out_is_fake); -const char * nm_device_get_initial_hw_address (NMDevice *dev); - -NMProxyConfig * nm_device_get_proxy_config (NMDevice *dev); - -NMDhcpConfig * nm_device_get_dhcp_config (NMDevice *dev, int addr_family); -NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); -void nm_device_replace_vpn4_config (NMDevice *dev, - NMIP4Config *old, - NMIP4Config *config); - -NMIP6Config * nm_device_get_ip6_config (NMDevice *dev); -void nm_device_replace_vpn6_config (NMDevice *dev, - NMIP6Config *old, - NMIP6Config *config); - -void nm_device_capture_initial_config (NMDevice *dev); - -int nm_device_parent_get_ifindex (NMDevice *dev); -NMDevice *nm_device_parent_get_device (NMDevice *dev); -void nm_device_parent_set_ifindex (NMDevice *self, - int parent_ifindex); -gboolean nm_device_parent_notify_changed (NMDevice *self, - NMDevice *change_candidate, - gboolean device_removed); - -const char *nm_device_parent_find_for_connection (NMDevice *self, - const char *current_setting_parent); +int nm_device_get_ifindex(NMDevice *dev); +gboolean nm_device_is_software(NMDevice *dev); +gboolean nm_device_is_real(NMDevice *dev); +const char * nm_device_get_ip_iface(NMDevice *dev); +const char * nm_device_get_ip_iface_from_platform(NMDevice *dev); +int nm_device_get_ip_ifindex(const NMDevice *dev); +const char * nm_device_get_driver(NMDevice *dev); +const char * nm_device_get_driver_version(NMDevice *dev); +const char * nm_device_get_type_desc(NMDevice *dev); +const char * nm_device_get_type_description(NMDevice *dev); +NMDeviceType nm_device_get_device_type(NMDevice *dev); +NMLinkType nm_device_get_link_type(NMDevice *dev); +NMMetered nm_device_get_metered(NMDevice *dev); + +guint32 nm_device_get_route_table(NMDevice *self, int addr_family); +guint32 nm_device_get_route_metric(NMDevice *dev, int addr_family); + +guint32 nm_device_get_route_metric_default(NMDeviceType device_type); + +const char *nm_device_get_hw_address(NMDevice *dev); +const char *nm_device_get_permanent_hw_address(NMDevice *self); +const char *nm_device_get_permanent_hw_address_full(NMDevice *self, + gboolean force_freeze, + gboolean *out_is_fake); +const char *nm_device_get_initial_hw_address(NMDevice *dev); + +NMProxyConfig *nm_device_get_proxy_config(NMDevice *dev); + +NMDhcpConfig *nm_device_get_dhcp_config(NMDevice *dev, int addr_family); +NMIP4Config * nm_device_get_ip4_config(NMDevice *dev); +void nm_device_replace_vpn4_config(NMDevice *dev, NMIP4Config *old, NMIP4Config *config); + +NMIP6Config *nm_device_get_ip6_config(NMDevice *dev); +void nm_device_replace_vpn6_config(NMDevice *dev, NMIP6Config *old, NMIP6Config *config); + +void nm_device_capture_initial_config(NMDevice *dev); + +int nm_device_parent_get_ifindex(NMDevice *dev); +NMDevice *nm_device_parent_get_device(NMDevice *dev); +void nm_device_parent_set_ifindex(NMDevice *self, int parent_ifindex); +gboolean nm_device_parent_notify_changed(NMDevice *self, + NMDevice *change_candidate, + gboolean device_removed); + +const char *nm_device_parent_find_for_connection(NMDevice * self, + const char *current_setting_parent); /* Master */ -gboolean nm_device_is_master (NMDevice *dev); +gboolean nm_device_is_master(NMDevice *dev); /* Slave */ -NMDevice * nm_device_get_master (NMDevice *dev); +NMDevice *nm_device_get_master(NMDevice *dev); -NMActRequest * nm_device_get_act_request (NMDevice *dev); -NMSettingsConnection *nm_device_get_settings_connection (NMDevice *dev); -NMConnection * nm_device_get_settings_connection_get_connection (NMDevice *self); -NMConnection * nm_device_get_applied_connection (NMDevice *dev); -gboolean nm_device_has_unmodified_applied_connection (NMDevice *self, - NMSettingCompareFlags compare_flags); -NMActivationStateFlags nm_device_get_activation_state_flags (NMDevice *self); +NMActRequest * nm_device_get_act_request(NMDevice *dev); +NMSettingsConnection * nm_device_get_settings_connection(NMDevice *dev); +NMConnection * nm_device_get_settings_connection_get_connection(NMDevice *self); +NMConnection * nm_device_get_applied_connection(NMDevice *dev); +gboolean nm_device_has_unmodified_applied_connection(NMDevice * self, + NMSettingCompareFlags compare_flags); +NMActivationStateFlags nm_device_get_activation_state_flags(NMDevice *self); -gpointer /* (NMSetting *) */ nm_device_get_applied_setting (NMDevice *dev, - GType setting_type); +gpointer /* (NMSetting *) */ nm_device_get_applied_setting(NMDevice *dev, GType setting_type); -void nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config); +void nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config); -gboolean nm_device_ignore_carrier_by_default (NMDevice *self); +gboolean nm_device_ignore_carrier_by_default(NMDevice *self); -gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags); -gboolean nm_device_has_carrier (NMDevice *dev); +gboolean nm_device_is_available(NMDevice *dev, NMDeviceCheckDevAvailableFlags flags); +gboolean nm_device_has_carrier(NMDevice *dev); -NMConnection * nm_device_generate_connection (NMDevice *self, - NMDevice *master, - gboolean *out_maybe_later, - GError **error); +NMConnection *nm_device_generate_connection(NMDevice *self, + NMDevice *master, + gboolean *out_maybe_later, + GError ** error); -gboolean nm_device_master_update_slave_connection (NMDevice *master, - NMDevice *slave, - NMConnection *connection, - GError **error); +gboolean nm_device_master_update_slave_connection(NMDevice * master, + NMDevice * slave, + NMConnection *connection, + GError ** error); -gboolean nm_device_can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, - char **specific_object); +gboolean +nm_device_can_auto_connect(NMDevice *self, NMSettingsConnection *sett_conn, char **specific_object); -gboolean nm_device_complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error); +gboolean nm_device_complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error); -gboolean nm_device_check_connection_compatible (NMDevice *device, - NMConnection *connection, - GError **error); +gboolean +nm_device_check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error); -gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnection *connection); +gboolean nm_device_check_slave_connection_compatible(NMDevice *device, NMConnection *connection); -gboolean nm_device_unmanage_on_quit (NMDevice *self); +gboolean nm_device_unmanage_on_quit(NMDevice *self); -gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); -int nm_device_spec_match_list_full (NMDevice *self, const GSList *specs, int no_match_value); +gboolean nm_device_spec_match_list(NMDevice *device, const GSList *specs); +int nm_device_spec_match_list_full(NMDevice *self, const GSList *specs, int no_match_value); -gboolean nm_device_is_activating (NMDevice *dev); -gboolean nm_device_autoconnect_allowed (NMDevice *self); +gboolean nm_device_is_activating(NMDevice *dev); +gboolean nm_device_autoconnect_allowed(NMDevice *self); -NMDeviceState nm_device_get_state (NMDevice *device); +NMDeviceState nm_device_get_state(NMDevice *device); -gboolean nm_device_get_enabled (NMDevice *device); +gboolean nm_device_get_enabled(NMDevice *device); -void nm_device_set_enabled (NMDevice *device, gboolean enabled); +void nm_device_set_enabled(NMDevice *device, gboolean enabled); -RfKillType nm_device_get_rfkill_type (NMDevice *device); +RfKillType nm_device_get_rfkill_type(NMDevice *device); /* IPv6 prefix delegation */ -void nm_device_request_ip6_prefixes (NMDevice *self, int needed_prefixes); +void nm_device_request_ip6_prefixes(NMDevice *self, int needed_prefixes); -gboolean nm_device_needs_ip6_subnet (NMDevice *self); +gboolean nm_device_needs_ip6_subnet(NMDevice *self); -void nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet); +void nm_device_use_ip6_subnet(NMDevice *self, const NMPlatformIP6Address *subnet); -void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device); +void nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device); /** * NMUnmanagedFlags: @@ -631,254 +614,244 @@ void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device); * meaning to set a slave device as managed if the parent is managed too. */ typedef enum { /*< skip >*/ - NM_UNMANAGED_NONE = 0, - - /* these flags are authoritative. If one of them is set, - * the device cannot be managed. */ - NM_UNMANAGED_SLEEPING = (1LL << 0), - NM_UNMANAGED_QUITTING = (1LL << 1), - NM_UNMANAGED_PARENT = (1LL << 2), - NM_UNMANAGED_BY_TYPE = (1LL << 3), - NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), - NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), - NM_UNMANAGED_USER_SETTINGS = (1LL << 6), - - /* These flags can be non-effective and be overwritten - * by other flags. */ - NM_UNMANAGED_BY_DEFAULT = (1LL << 8), - NM_UNMANAGED_USER_CONF = (1LL << 9), - NM_UNMANAGED_USER_UDEV = (1LL << 10), - NM_UNMANAGED_EXTERNAL_DOWN = (1LL << 11), - NM_UNMANAGED_IS_SLAVE = (1LL << 12), + NM_UNMANAGED_NONE = 0, + + /* these flags are authoritative. If one of them is set, + * the device cannot be managed. */ + NM_UNMANAGED_SLEEPING = (1LL << 0), + NM_UNMANAGED_QUITTING = (1LL << 1), + NM_UNMANAGED_PARENT = (1LL << 2), + NM_UNMANAGED_BY_TYPE = (1LL << 3), + NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), + NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), + NM_UNMANAGED_USER_SETTINGS = (1LL << 6), + + /* These flags can be non-effective and be overwritten + * by other flags. */ + NM_UNMANAGED_BY_DEFAULT = (1LL << 8), + NM_UNMANAGED_USER_CONF = (1LL << 9), + NM_UNMANAGED_USER_UDEV = (1LL << 10), + NM_UNMANAGED_EXTERNAL_DOWN = (1LL << 11), + NM_UNMANAGED_IS_SLAVE = (1LL << 12), } NMUnmanagedFlags; typedef enum { - NM_UNMAN_FLAG_OP_SET_MANAGED = FALSE, - NM_UNMAN_FLAG_OP_SET_UNMANAGED = TRUE, - NM_UNMAN_FLAG_OP_FORGET = 2, + NM_UNMAN_FLAG_OP_SET_MANAGED = FALSE, + NM_UNMAN_FLAG_OP_SET_UNMANAGED = TRUE, + NM_UNMAN_FLAG_OP_FORGET = 2, } NMUnmanFlagOp; -const char *nm_unmanaged_flags2str (NMUnmanagedFlags flags, char *buf, gsize len); - -gboolean nm_device_get_managed (NMDevice *device, gboolean for_user_request); -NMUnmanagedFlags nm_device_get_unmanaged_mask (NMDevice *device, NMUnmanagedFlags flag); -NMUnmanagedFlags nm_device_get_unmanaged_flags (NMDevice *device, NMUnmanagedFlags flag); -void nm_device_set_unmanaged_flags (NMDevice *device, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op); -void nm_device_set_unmanaged_by_flags (NMDevice *device, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op, - NMDeviceStateReason reason); -void nm_device_set_unmanaged_by_flags_queue (NMDevice *self, - NMUnmanagedFlags flags, - NMUnmanFlagOp set_op, - NMDeviceStateReason reason); -void nm_device_set_unmanaged_by_user_settings (NMDevice *self); -void nm_device_set_unmanaged_by_user_udev (NMDevice *self); -void nm_device_set_unmanaged_by_user_conf (NMDevice *self); -void nm_device_set_unmanaged_by_quitting (NMDevice *device); - -gboolean nm_device_check_unrealized_device_managed (NMDevice *self); - -gboolean nm_device_is_nm_owned (NMDevice *device); - -gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps); +const char *nm_unmanaged_flags2str(NMUnmanagedFlags flags, char *buf, gsize len); + +gboolean nm_device_get_managed(NMDevice *device, gboolean for_user_request); +NMUnmanagedFlags nm_device_get_unmanaged_mask(NMDevice *device, NMUnmanagedFlags flag); +NMUnmanagedFlags nm_device_get_unmanaged_flags(NMDevice *device, NMUnmanagedFlags flag); +void nm_device_set_unmanaged_flags(NMDevice *device, NMUnmanagedFlags flags, NMUnmanFlagOp set_op); +void nm_device_set_unmanaged_by_flags(NMDevice * device, + NMUnmanagedFlags flags, + NMUnmanFlagOp set_op, + NMDeviceStateReason reason); +void nm_device_set_unmanaged_by_flags_queue(NMDevice * self, + NMUnmanagedFlags flags, + NMUnmanFlagOp set_op, + NMDeviceStateReason reason); +void nm_device_set_unmanaged_by_user_settings(NMDevice *self); +void nm_device_set_unmanaged_by_user_udev(NMDevice *self); +void nm_device_set_unmanaged_by_user_conf(NMDevice *self); +void nm_device_set_unmanaged_by_quitting(NMDevice *device); + +gboolean nm_device_check_unrealized_device_managed(NMDevice *self); + +gboolean nm_device_is_nm_owned(NMDevice *device); + +gboolean nm_device_has_capability(NMDevice *self, NMDeviceCapabilities caps); /*****************************************************************************/ -void nm_device_assume_state_get (NMDevice *self, - gboolean *out_assume_state_guess_assume, - const char **out_assume_state_connection_uuid); -void nm_device_assume_state_reset (NMDevice *self); +void nm_device_assume_state_get(NMDevice * self, + gboolean * out_assume_state_guess_assume, + const char **out_assume_state_connection_uuid); +void nm_device_assume_state_reset(NMDevice *self); /*****************************************************************************/ -gboolean nm_device_realize_start (NMDevice *device, - const NMPlatformLink *plink, - gboolean assume_state_guess_assume, - const char *assume_state_connection_uuid, - gboolean set_nm_owned, - NMUnmanFlagOp unmanaged_user_explicit, - gboolean *out_compatible, - GError **error); -void nm_device_realize_finish (NMDevice *self, - const NMPlatformLink *plink); -gboolean nm_device_create_and_realize (NMDevice *self, - NMConnection *connection, - NMDevice *parent, - GError **error); -gboolean nm_device_unrealize (NMDevice *device, - gboolean remove_resources, - GError **error); - -void nm_device_update_from_platform_link (NMDevice *self, - const NMPlatformLink *plink); +gboolean nm_device_realize_start(NMDevice * device, + const NMPlatformLink *plink, + gboolean assume_state_guess_assume, + const char * assume_state_connection_uuid, + gboolean set_nm_owned, + NMUnmanFlagOp unmanaged_user_explicit, + gboolean * out_compatible, + GError ** error); +void nm_device_realize_finish(NMDevice *self, const NMPlatformLink *plink); +gboolean nm_device_create_and_realize(NMDevice * self, + NMConnection *connection, + NMDevice * parent, + GError ** error); +gboolean nm_device_unrealize(NMDevice *device, gboolean remove_resources, GError **error); + +void nm_device_update_from_platform_link(NMDevice *self, const NMPlatformLink *plink); typedef enum { - NM_DEVICE_AUTOCONNECT_BLOCKED_NONE = 0, + NM_DEVICE_AUTOCONNECT_BLOCKED_NONE = 0, - NM_DEVICE_AUTOCONNECT_BLOCKED_USER = (1LL << 0), + NM_DEVICE_AUTOCONNECT_BLOCKED_USER = (1LL << 0), - NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN = (1LL << 1), - NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT = (1LL << 2), - NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING = (1LL << 3), - NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED = (1LL << 4), + NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN = (1LL << 1), + NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT = (1LL << 2), + NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING = (1LL << 3), + NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED = (1LL << 4), - _NM_DEVICE_AUTOCONNECT_BLOCKED_LAST, + _NM_DEVICE_AUTOCONNECT_BLOCKED_LAST, - NM_DEVICE_AUTOCONNECT_BLOCKED_ALL = (((_NM_DEVICE_AUTOCONNECT_BLOCKED_LAST - 1) << 1) - 1), + NM_DEVICE_AUTOCONNECT_BLOCKED_ALL = (((_NM_DEVICE_AUTOCONNECT_BLOCKED_LAST - 1) << 1) - 1), - NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL & ~NM_DEVICE_AUTOCONNECT_BLOCKED_USER, + NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL = + NM_DEVICE_AUTOCONNECT_BLOCKED_ALL & ~NM_DEVICE_AUTOCONNECT_BLOCKED_USER, } NMDeviceAutoconnectBlockedFlags; -NMDeviceAutoconnectBlockedFlags nm_device_autoconnect_blocked_get (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask); +NMDeviceAutoconnectBlockedFlags +nm_device_autoconnect_blocked_get(NMDevice *device, NMDeviceAutoconnectBlockedFlags mask); -void nm_device_autoconnect_blocked_set_full (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask, NMDeviceAutoconnectBlockedFlags values); +void nm_device_autoconnect_blocked_set_full(NMDevice * device, + NMDeviceAutoconnectBlockedFlags mask, + NMDeviceAutoconnectBlockedFlags values); static inline void -nm_device_autoconnect_blocked_set (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask) +nm_device_autoconnect_blocked_set(NMDevice *device, NMDeviceAutoconnectBlockedFlags mask) { - nm_device_autoconnect_blocked_set_full (device, mask, mask); + nm_device_autoconnect_blocked_set_full(device, mask, mask); } static inline void -nm_device_autoconnect_blocked_unset (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask) +nm_device_autoconnect_blocked_unset(NMDevice *device, NMDeviceAutoconnectBlockedFlags mask) { - nm_device_autoconnect_blocked_set_full (device, mask, NM_DEVICE_AUTOCONNECT_BLOCKED_NONE); + nm_device_autoconnect_blocked_set_full(device, mask, NM_DEVICE_AUTOCONNECT_BLOCKED_NONE); } -void nm_device_emit_recheck_auto_activate (NMDevice *device); +void nm_device_emit_recheck_auto_activate(NMDevice *device); -NMDeviceSysIfaceState nm_device_sys_iface_state_get (NMDevice *device); +NMDeviceSysIfaceState nm_device_sys_iface_state_get(NMDevice *device); -gboolean nm_device_sys_iface_state_is_external (NMDevice *self); -gboolean nm_device_sys_iface_state_is_external_or_assume (NMDevice *self); +gboolean nm_device_sys_iface_state_is_external(NMDevice *self); +gboolean nm_device_sys_iface_state_is_external_or_assume(NMDevice *self); -void nm_device_sys_iface_state_set (NMDevice *device, NMDeviceSysIfaceState sys_iface_state); +void nm_device_sys_iface_state_set(NMDevice *device, NMDeviceSysIfaceState sys_iface_state); -void nm_device_state_changed (NMDevice *device, - NMDeviceState state, - NMDeviceStateReason reason); +void nm_device_state_changed(NMDevice *device, NMDeviceState state, NMDeviceStateReason reason); -void nm_device_queue_state (NMDevice *self, - NMDeviceState state, - NMDeviceStateReason reason); +void nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason); -gboolean nm_device_get_firmware_missing (NMDevice *self); +gboolean nm_device_get_firmware_missing(NMDevice *self); -void nm_device_disconnect_active_connection (NMActiveConnection *active, - NMDeviceStateReason device_reason, - NMActiveConnectionStateReason active_reason); +void nm_device_disconnect_active_connection(NMActiveConnection * active, + NMDeviceStateReason device_reason, + NMActiveConnectionStateReason active_reason); -void nm_device_queue_activation (NMDevice *device, NMActRequest *req); +void nm_device_queue_activation(NMDevice *device, NMActRequest *req); -gboolean nm_device_supports_vlans (NMDevice *device); +gboolean nm_device_supports_vlans(NMDevice *device); -gboolean nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending); -gboolean nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending); -const char *nm_device_has_pending_action_reason (NMDevice *device); +gboolean +nm_device_add_pending_action(NMDevice *device, const char *action, gboolean assert_not_yet_pending); +gboolean +nm_device_remove_pending_action(NMDevice *device, const char *action, gboolean assert_is_pending); +const char *nm_device_has_pending_action_reason(NMDevice *device); static inline gboolean -nm_device_has_pending_action (NMDevice *device) +nm_device_has_pending_action(NMDevice *device) { - return !!nm_device_has_pending_action_reason (device); + return !!nm_device_has_pending_action_reason(device); } -NMSettingsConnection *nm_device_get_best_connection (NMDevice *device, - const char *specific_object, - GError **error); +NMSettingsConnection * +nm_device_get_best_connection(NMDevice *device, const char *specific_object, GError **error); -gboolean nm_device_check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error); +gboolean nm_device_check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error); -void nm_device_notify_availability_maybe_changed (NMDevice *self); +void nm_device_notify_availability_maybe_changed(NMDevice *self); -gboolean nm_device_owns_iface (NMDevice *device, const char *iface); +gboolean nm_device_owns_iface(NMDevice *device, const char *iface); -NMConnection *nm_device_new_default_connection (NMDevice *self); +NMConnection *nm_device_new_default_connection(NMDevice *self); -const NMPObject *nm_device_get_best_default_route (NMDevice *self, - int addr_family); +const NMPObject *nm_device_get_best_default_route(NMDevice *self, int addr_family); -void nm_device_spawn_iface_helper (NMDevice *self); +void nm_device_spawn_iface_helper(NMDevice *self); -gboolean nm_device_reapply (NMDevice *self, - NMConnection *connection, - GError **error); -void nm_device_reapply_settings_immediately (NMDevice *self); +gboolean nm_device_reapply(NMDevice *self, NMConnection *connection, GError **error); +void nm_device_reapply_settings_immediately(NMDevice *self); -void nm_device_update_firewall_zone (NMDevice *self); -void nm_device_update_metered (NMDevice *self); -void nm_device_reactivate_ip4_config (NMDevice *device, - NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new); -void nm_device_reactivate_ip6_config (NMDevice *device, - NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new); +void nm_device_update_firewall_zone(NMDevice *self); +void nm_device_update_metered(NMDevice *self); +void nm_device_reactivate_ip4_config(NMDevice * device, + NMSettingIPConfig *s_ip4_old, + NMSettingIPConfig *s_ip4_new); +void nm_device_reactivate_ip6_config(NMDevice * device, + NMSettingIPConfig *s_ip6_old, + NMSettingIPConfig *s_ip6_new); -gboolean nm_device_update_hw_address (NMDevice *self); -void nm_device_update_initial_hw_address (NMDevice *self); -void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze); -void nm_device_update_dynamic_ip_setup (NMDevice *self); -guint nm_device_get_supplicant_timeout (NMDevice *self); +gboolean nm_device_update_hw_address(NMDevice *self); +void nm_device_update_initial_hw_address(NMDevice *self); +void nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_freeze); +void nm_device_update_dynamic_ip_setup(NMDevice *self); +guint nm_device_get_supplicant_timeout(NMDevice *self); -gboolean nm_device_auth_retries_try_next (NMDevice *self); +gboolean nm_device_auth_retries_try_next(NMDevice *self); -gboolean nm_device_hw_addr_get_cloned (NMDevice *self, - NMConnection *connection, - gboolean is_wifi, - char **hwaddr, - gboolean *preserve, - GError **error); +gboolean nm_device_hw_addr_get_cloned(NMDevice * self, + NMConnection *connection, + gboolean is_wifi, + char ** hwaddr, + gboolean * preserve, + GError ** error); typedef struct _NMDeviceConnectivityHandle NMDeviceConnectivityHandle; -typedef void (*NMDeviceConnectivityCallback) (NMDevice *self, - NMDeviceConnectivityHandle *handle, - NMConnectivityState state, - GError *error, - gpointer user_data); +typedef void (*NMDeviceConnectivityCallback)(NMDevice * self, + NMDeviceConnectivityHandle *handle, + NMConnectivityState state, + GError * error, + gpointer user_data); -void nm_device_check_connectivity_update_interval (NMDevice *self); +void nm_device_check_connectivity_update_interval(NMDevice *self); -NMDeviceConnectivityHandle *nm_device_check_connectivity (NMDevice *self, - int addr_family, - NMDeviceConnectivityCallback callback, - gpointer user_data); +NMDeviceConnectivityHandle *nm_device_check_connectivity(NMDevice * self, + int addr_family, + NMDeviceConnectivityCallback callback, + gpointer user_data); -void nm_device_check_connectivity_cancel (NMDeviceConnectivityHandle *handle); +void nm_device_check_connectivity_cancel(NMDeviceConnectivityHandle *handle); -NMConnectivityState nm_device_get_connectivity_state (NMDevice *self, int addr_family); +NMConnectivityState nm_device_get_connectivity_state(NMDevice *self, int addr_family); typedef struct _NMBtVTableNetworkServer NMBtVTableNetworkServer; -typedef void (*NMBtVTableRegisterCallback) (GError *error, - gpointer user_data); +typedef void (*NMBtVTableRegisterCallback)(GError *error, gpointer user_data); struct _NMBtVTableNetworkServer { - gboolean (*is_available) (const NMBtVTableNetworkServer *vtable, - const char *addr, - NMDevice *device_accept_busy); - - gboolean (*register_bridge) (const NMBtVTableNetworkServer *vtable, - const char *addr, - NMDevice *device, - GCancellable *cancellable, - NMBtVTableRegisterCallback callback, - gpointer callback_user_data, - GError **error); - gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable, - NMDevice *device); + gboolean (*is_available)(const NMBtVTableNetworkServer *vtable, + const char * addr, + NMDevice * device_accept_busy); + + gboolean (*register_bridge)(const NMBtVTableNetworkServer *vtable, + const char * addr, + NMDevice * device, + GCancellable * cancellable, + NMBtVTableRegisterCallback callback, + gpointer callback_user_data, + GError ** error); + gboolean (*unregister_bridge)(const NMBtVTableNetworkServer *vtable, NMDevice *device); }; -const char *nm_device_state_to_str (NMDeviceState state); -const char *nm_device_state_reason_to_str (NMDeviceStateReason reason); +const char *nm_device_state_to_str(NMDeviceState state); +const char *nm_device_state_reason_to_str(NMDeviceStateReason reason); -gboolean nm_device_is_vpn (NMDevice *self); +gboolean nm_device_is_vpn(NMDevice *self); #endif /* __NETWORKMANAGER_DEVICE_H__ */ diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index 9d37758d..25d863c8 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -19,1065 +19,1104 @@ #define MAX_NEIGHBORS 128 #define MIN_UPDATE_INTERVAL_NSEC (2 * NM_UTILS_NSEC_PER_SEC) -#define LLDP_MAC_NEAREST_BRIDGE (&((struct ether_addr) { .ether_addr_octet = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e } })) -#define LLDP_MAC_NEAREST_NON_TPMR_BRIDGE (&((struct ether_addr) { .ether_addr_octet = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 } })) -#define LLDP_MAC_NEAREST_CUSTOMER_BRIDGE (&((struct ether_addr) { .ether_addr_octet = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 } })) +#define LLDP_MAC_NEAREST_BRIDGE \ + (&((struct ether_addr){.ether_addr_octet = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e}})) +#define LLDP_MAC_NEAREST_NON_TPMR_BRIDGE \ + (&((struct ether_addr){.ether_addr_octet = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03}})) +#define LLDP_MAC_NEAREST_CUSTOMER_BRIDGE \ + (&((struct ether_addr){.ether_addr_octet = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}})) /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMLldpListener, - PROP_NEIGHBORS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMLldpListener, PROP_NEIGHBORS, ); typedef struct { - sd_lldp *lldp_handle; - GHashTable *lldp_neighbors; - GVariant *variant; + sd_lldp * lldp_handle; + GHashTable *lldp_neighbors; + GVariant * variant; - /* the timestamp in nsec until which we delay updates. */ - gint64 ratelimit_next_nsec; - guint ratelimit_id; + /* the timestamp in nsec until which we delay updates. */ + gint64 ratelimit_next_nsec; + guint ratelimit_id; - int ifindex; + int ifindex; } NMLldpListenerPrivate; struct _NMLldpListener { - GObject parent; - NMLldpListenerPrivate _priv; + GObject parent; + NMLldpListenerPrivate _priv; }; struct _NMLldpListenerClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMLldpListener, nm_lldp_listener, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMLldpListener, nm_lldp_listener, G_TYPE_OBJECT) -#define NM_LLDP_LISTENER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMLldpListener, NM_IS_LLDP_LISTENER) +#define NM_LLDP_LISTENER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMLldpListener, NM_IS_LLDP_LISTENER) /*****************************************************************************/ typedef struct { - GVariant *variant; - sd_lldp_neighbor *neighbor_sd; - char *chassis_id; - char *port_id; - guint8 chassis_id_type; - guint8 port_id_type; + GVariant * variant; + sd_lldp_neighbor *neighbor_sd; + char * chassis_id; + char * port_id; + guint8 chassis_id_type; + guint8 port_id_type; } LldpNeighbor; /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "lldp" -#define _NMLOG_DOMAIN LOGD_DEVICE -#define _NMLOG(level, ...) \ - G_STMT_START { \ - const NMLogLevel _level = (level); \ - \ - if (nm_logging_enabled (_level, _NMLOG_DOMAIN)) { \ - char _sbuf[64]; \ - int _ifindex = (self) ? NM_LLDP_LISTENER_GET_PRIVATE (self)->ifindex : 0; \ - \ - _nm_log (_level, _NMLOG_DOMAIN, 0, \ - _ifindex > 0 ? nm_platform_link_get_name (NM_PLATFORM_GET, _ifindex) : NULL, \ - NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - ((_ifindex > 0) \ - ? nm_sprintf_buf (_sbuf, "[%p,%d]", (self), _ifindex) \ - : ((self) \ - ? nm_sprintf_buf (_sbuf, "[%p]", (self)) \ - : "")) \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } \ - } G_STMT_END \ - -#define LOG_NEIGH_FMT "CHASSIS=%u/%s PORT=%u/%s" -#define LOG_NEIGH_ARG(neigh) (neigh)->chassis_id_type, (neigh)->chassis_id, (neigh)->port_id_type, (neigh)->port_id +#define _NMLOG_PREFIX_NAME "lldp" +#define _NMLOG_DOMAIN LOGD_DEVICE +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) { \ + char _sbuf[64]; \ + int _ifindex = (self) ? NM_LLDP_LISTENER_GET_PRIVATE(self)->ifindex : 0; \ + \ + _nm_log(_level, \ + _NMLOG_DOMAIN, \ + 0, \ + _ifindex > 0 ? nm_platform_link_get_name(NM_PLATFORM_GET, _ifindex) : NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + ((_ifindex > 0) ? nm_sprintf_buf(_sbuf, "[%p,%d]", (self), _ifindex) \ + : ((self) ? nm_sprintf_buf(_sbuf, "[%p]", (self)) : "")) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +#define LOG_NEIGH_FMT "CHASSIS=%u/%s PORT=%u/%s" +#define LOG_NEIGH_ARG(neigh) \ + (neigh)->chassis_id_type, (neigh)->chassis_id, (neigh)->port_id_type, (neigh)->port_id /*****************************************************************************/ static void -lldp_neighbor_get_raw (LldpNeighbor *neigh, - const guint8 **out_raw_data, - gsize *out_raw_len) +lldp_neighbor_get_raw(LldpNeighbor *neigh, const guint8 **out_raw_data, gsize *out_raw_len) { - gconstpointer raw_data; - gsize raw_len; - int r; + gconstpointer raw_data; + gsize raw_len; + int r; - nm_assert (neigh); + nm_assert(neigh); - r = sd_lldp_neighbor_get_raw (neigh->neighbor_sd, &raw_data, &raw_len); + r = sd_lldp_neighbor_get_raw(neigh->neighbor_sd, &raw_data, &raw_len); - nm_assert (r >= 0); - nm_assert (raw_data); - nm_assert (raw_len > 0); + nm_assert(r >= 0); + nm_assert(raw_data); + nm_assert(raw_len > 0); - *out_raw_data = raw_data; - *out_raw_len = raw_len; + *out_raw_data = raw_data; + *out_raw_len = raw_len; } static gboolean -lldp_neighbor_id_get (struct sd_lldp_neighbor *neighbor_sd, - guint8 *out_chassis_id_type, - const guint8 **out_chassis_id, - gsize *out_chassis_id_len, - guint8 *out_port_id_type, - const guint8 **out_port_id, - gsize *out_port_id_len) +lldp_neighbor_id_get(struct sd_lldp_neighbor *neighbor_sd, + guint8 * out_chassis_id_type, + const guint8 ** out_chassis_id, + gsize * out_chassis_id_len, + guint8 * out_port_id_type, + const guint8 ** out_port_id, + gsize * out_port_id_len) { - int r; - - r = sd_lldp_neighbor_get_chassis_id (neighbor_sd, - out_chassis_id_type, - (gconstpointer *) out_chassis_id, - out_chassis_id_len); - if (r < 0) - return FALSE; - - r = sd_lldp_neighbor_get_port_id (neighbor_sd, - out_port_id_type, - (gconstpointer *) out_port_id, - out_port_id_len); - if (r < 0) - return FALSE; - - return TRUE; + int r; + + r = sd_lldp_neighbor_get_chassis_id(neighbor_sd, + out_chassis_id_type, + (gconstpointer *) out_chassis_id, + out_chassis_id_len); + if (r < 0) + return FALSE; + + r = sd_lldp_neighbor_get_port_id(neighbor_sd, + out_port_id_type, + (gconstpointer *) out_port_id, + out_port_id_len); + if (r < 0) + return FALSE; + + return TRUE; } static guint -lldp_neighbor_id_hash (gconstpointer ptr) +lldp_neighbor_id_hash(gconstpointer ptr) { - const LldpNeighbor *neigh = ptr; - guint8 chassis_id_type; - guint8 port_id_type; - const guint8 *chassis_id; - const guint8 *port_id; - gsize chassis_id_len; - gsize port_id_len; - NMHashState h; - - if (!lldp_neighbor_id_get (neigh->neighbor_sd, &chassis_id_type, &chassis_id, &chassis_id_len, &port_id_type, &port_id, &port_id_len)) { - nm_assert_not_reached (); - return 0; - } - - nm_hash_init (&h, 23423423u); - nm_hash_update_vals (&h, - chassis_id_len, - port_id_len, - chassis_id_type, - port_id_type); - nm_hash_update (&h, chassis_id, chassis_id_len); - nm_hash_update (&h, port_id, port_id_len); - return nm_hash_complete (&h); + const LldpNeighbor *neigh = ptr; + guint8 chassis_id_type; + guint8 port_id_type; + const guint8 * chassis_id; + const guint8 * port_id; + gsize chassis_id_len; + gsize port_id_len; + NMHashState h; + + if (!lldp_neighbor_id_get(neigh->neighbor_sd, + &chassis_id_type, + &chassis_id, + &chassis_id_len, + &port_id_type, + &port_id, + &port_id_len)) { + nm_assert_not_reached(); + return 0; + } + + nm_hash_init(&h, 23423423u); + nm_hash_update_vals(&h, chassis_id_len, port_id_len, chassis_id_type, port_id_type); + nm_hash_update(&h, chassis_id, chassis_id_len); + nm_hash_update(&h, port_id, port_id_len); + return nm_hash_complete(&h); } static int -lldp_neighbor_id_cmp (const LldpNeighbor *a, const LldpNeighbor *b) +lldp_neighbor_id_cmp(const LldpNeighbor *a, const LldpNeighbor *b) { - guint8 a_chassis_id_type; - guint8 b_chassis_id_type; - guint8 a_port_id_type; - guint8 b_port_id_type; - const guint8 *a_chassis_id; - const guint8 *b_chassis_id; - const guint8 *a_port_id; - const guint8 *b_port_id; - gsize a_chassis_id_len; - gsize b_chassis_id_len; - gsize a_port_id_len; - gsize b_port_id_len; - - NM_CMP_SELF (a, b); - - if (!lldp_neighbor_id_get (a->neighbor_sd, &a_chassis_id_type, &a_chassis_id, &a_chassis_id_len, &a_port_id_type, &a_port_id, &a_port_id_len)) { - nm_assert_not_reached (); - return FALSE; - } - - if (!lldp_neighbor_id_get (b->neighbor_sd, &b_chassis_id_type, &b_chassis_id, &b_chassis_id_len, &b_port_id_type, &b_port_id, &b_port_id_len)) { - nm_assert_not_reached (); - return FALSE; - } - - NM_CMP_DIRECT (a_chassis_id_type, b_chassis_id_type); - NM_CMP_DIRECT (a_port_id_type, b_port_id_type); - NM_CMP_DIRECT (a_chassis_id_len, b_chassis_id_len); - NM_CMP_DIRECT (a_port_id_len, b_port_id_len); - NM_CMP_DIRECT_MEMCMP (a_chassis_id, b_chassis_id, a_chassis_id_len); - NM_CMP_DIRECT_MEMCMP (a_port_id, b_port_id, a_port_id_len); - return 0; + guint8 a_chassis_id_type; + guint8 b_chassis_id_type; + guint8 a_port_id_type; + guint8 b_port_id_type; + const guint8 *a_chassis_id; + const guint8 *b_chassis_id; + const guint8 *a_port_id; + const guint8 *b_port_id; + gsize a_chassis_id_len; + gsize b_chassis_id_len; + gsize a_port_id_len; + gsize b_port_id_len; + + NM_CMP_SELF(a, b); + + if (!lldp_neighbor_id_get(a->neighbor_sd, + &a_chassis_id_type, + &a_chassis_id, + &a_chassis_id_len, + &a_port_id_type, + &a_port_id, + &a_port_id_len)) { + nm_assert_not_reached(); + return FALSE; + } + + if (!lldp_neighbor_id_get(b->neighbor_sd, + &b_chassis_id_type, + &b_chassis_id, + &b_chassis_id_len, + &b_port_id_type, + &b_port_id, + &b_port_id_len)) { + nm_assert_not_reached(); + return FALSE; + } + + NM_CMP_DIRECT(a_chassis_id_type, b_chassis_id_type); + NM_CMP_DIRECT(a_port_id_type, b_port_id_type); + NM_CMP_DIRECT(a_chassis_id_len, b_chassis_id_len); + NM_CMP_DIRECT(a_port_id_len, b_port_id_len); + NM_CMP_DIRECT_MEMCMP(a_chassis_id, b_chassis_id, a_chassis_id_len); + NM_CMP_DIRECT_MEMCMP(a_port_id, b_port_id, a_port_id_len); + return 0; } static int -lldp_neighbor_id_cmp_p (gconstpointer a, gconstpointer b, gpointer user_data) +lldp_neighbor_id_cmp_p(gconstpointer a, gconstpointer b, gpointer user_data) { - return lldp_neighbor_id_cmp (*((const LldpNeighbor *const*) a), - *((const LldpNeighbor *const*) b)); + return lldp_neighbor_id_cmp(*((const LldpNeighbor *const *) a), + *((const LldpNeighbor *const *) b)); } static gboolean -lldp_neighbor_id_equal (gconstpointer a, gconstpointer b) +lldp_neighbor_id_equal(gconstpointer a, gconstpointer b) { - return lldp_neighbor_id_cmp (a, b) == 0; + return lldp_neighbor_id_cmp(a, b) == 0; } static void -lldp_neighbor_free (LldpNeighbor *neighbor) +lldp_neighbor_free(LldpNeighbor *neighbor) { - if (!neighbor) - return; - - g_free (neighbor->chassis_id); - g_free (neighbor->port_id); - nm_g_variant_unref (neighbor->variant); - sd_lldp_neighbor_unref (neighbor->neighbor_sd); - nm_g_slice_free (neighbor); + if (!neighbor) + return; + + g_free(neighbor->chassis_id); + g_free(neighbor->port_id); + nm_g_variant_unref(neighbor->variant); + sd_lldp_neighbor_unref(neighbor->neighbor_sd); + nm_g_slice_free(neighbor); } static void -lldp_neighbor_freep (LldpNeighbor **ptr) +lldp_neighbor_freep(LldpNeighbor **ptr) { - lldp_neighbor_free (*ptr); + lldp_neighbor_free(*ptr); } static gboolean -lldp_neighbor_equal (LldpNeighbor *a, LldpNeighbor *b) +lldp_neighbor_equal(LldpNeighbor *a, LldpNeighbor *b) { - const guint8 *raw_data_a; - const guint8 *raw_data_b; - gsize raw_len_a; - gsize raw_len_b; - - if (a->neighbor_sd == b->neighbor_sd) - return TRUE; - - lldp_neighbor_get_raw (a, &raw_data_a, &raw_len_a); - lldp_neighbor_get_raw (b, &raw_data_b, &raw_len_b); - return raw_len_a == raw_len_b - && (memcmp (raw_data_a, raw_data_b, raw_len_a) == 0); + const guint8 *raw_data_a; + const guint8 *raw_data_b; + gsize raw_len_a; + gsize raw_len_b; + + if (a->neighbor_sd == b->neighbor_sd) + return TRUE; + + lldp_neighbor_get_raw(a, &raw_data_a, &raw_len_a); + lldp_neighbor_get_raw(b, &raw_data_b, &raw_len_b); + return raw_len_a == raw_len_b && (memcmp(raw_data_a, raw_data_b, raw_len_a) == 0); } static GVariant * -parse_management_address_tlv (const uint8_t *data, gsize len) +parse_management_address_tlv(const uint8_t *data, gsize len) { - GVariantBuilder builder; - gsize addr_len; - const guint8 *v_object_id_arr; - gsize v_object_id_len; - const guint8 *v_address_arr; - gsize v_address_len; - guint32 v_interface_number; - guint32 v_interface_number_subtype; - guint32 v_address_subtype; - - /* 802.1AB-2009 - Figure 8-11 - * - * - TLV type / length (2 bytes) - * - address string length (1 byte) - * - address subtype (1 byte) - * - address (1 to 31 bytes) - * - interface number subtype (1 byte) - * - interface number (4 bytes) - * - OID string length (1 byte) - * - OID (0 to 128 bytes) - */ - - if (len < 11) - return NULL; - - nm_assert ((data[0] >> 1) == SD_LLDP_TYPE_MGMT_ADDRESS); - nm_assert ((((data[0] & 1) << 8) + data[1]) + 2 == len); - - data += 2; - len -= 2; - addr_len = *data; /* length of (address subtype + address) */ - - if (addr_len < 2 || addr_len > 32) - return NULL; - if (len < ( 1 /* address stringth length */ - + addr_len /* address subtype + address */ - + 5 /* interface */ - + 1)) /* oid */ - return NULL; - - data++; - len--; - v_address_subtype = *data; - v_address_arr = &data[1]; - v_address_len = addr_len - 1; - - data += addr_len; - len -= addr_len; - v_interface_number_subtype = *data; - - data++; - len--; - v_interface_number = unaligned_read_be32 (data); - - data += 4; - len -= 4; - v_object_id_len = *data; - if (len < (1 + v_object_id_len)) - return NULL; - data++; - v_object_id_arr = data; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - nm_g_variant_builder_add_sv_uint32 (&builder, "address-subtype", v_address_subtype); - nm_g_variant_builder_add_sv_bytearray (&builder, "address", v_address_arr, v_address_len); - nm_g_variant_builder_add_sv_uint32 (&builder, "interface-number-subtype", v_interface_number_subtype); - nm_g_variant_builder_add_sv_uint32 (&builder, "interface-number", v_interface_number); - if (v_object_id_len > 0) - nm_g_variant_builder_add_sv_bytearray (&builder, "object-id", v_object_id_arr, v_object_id_len); - return g_variant_builder_end (&builder); + GVariantBuilder builder; + gsize addr_len; + const guint8 * v_object_id_arr; + gsize v_object_id_len; + const guint8 * v_address_arr; + gsize v_address_len; + guint32 v_interface_number; + guint32 v_interface_number_subtype; + guint32 v_address_subtype; + + /* 802.1AB-2009 - Figure 8-11 + * + * - TLV type / length (2 bytes) + * - address string length (1 byte) + * - address subtype (1 byte) + * - address (1 to 31 bytes) + * - interface number subtype (1 byte) + * - interface number (4 bytes) + * - OID string length (1 byte) + * - OID (0 to 128 bytes) + */ + + if (len < 11) + return NULL; + + nm_assert((data[0] >> 1) == SD_LLDP_TYPE_MGMT_ADDRESS); + nm_assert((((data[0] & 1) << 8) + data[1]) + 2 == len); + + data += 2; + len -= 2; + addr_len = *data; /* length of (address subtype + address) */ + + if (addr_len < 2 || addr_len > 32) + return NULL; + if (len < (1 /* address stringth length */ + + addr_len /* address subtype + address */ + + 5 /* interface */ + + 1)) /* oid */ + return NULL; + + data++; + len--; + v_address_subtype = *data; + v_address_arr = &data[1]; + v_address_len = addr_len - 1; + + data += addr_len; + len -= addr_len; + v_interface_number_subtype = *data; + + data++; + len--; + v_interface_number = unaligned_read_be32(data); + + data += 4; + len -= 4; + v_object_id_len = *data; + if (len < (1 + v_object_id_len)) + return NULL; + data++; + v_object_id_arr = data; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + nm_g_variant_builder_add_sv_uint32(&builder, "address-subtype", v_address_subtype); + nm_g_variant_builder_add_sv_bytearray(&builder, "address", v_address_arr, v_address_len); + nm_g_variant_builder_add_sv_uint32(&builder, + "interface-number-subtype", + v_interface_number_subtype); + nm_g_variant_builder_add_sv_uint32(&builder, "interface-number", v_interface_number); + if (v_object_id_len > 0) + nm_g_variant_builder_add_sv_bytearray(&builder, + "object-id", + v_object_id_arr, + v_object_id_len); + return g_variant_builder_end(&builder); } static char * -format_network_address (const guint8 *data, gsize sz) +format_network_address(const guint8 *data, gsize sz) { - NMIPAddr a; - int family; - - if ( sz == 5 - && data[0] == 1 /* LLDP_MGMT_ADDR_IP4 */) { - memcpy (&a, &data[1], sizeof (a.addr4)); - family = AF_INET; - } else if ( sz == 17 - && data[0] == 2 /* LLDP_MGMT_ADDR_IP6 */) { - memcpy (&a, &data[1], sizeof (a.addr6)); - family = AF_INET6; - } else - return NULL; - - return nm_utils_inet_ntop_dup (family, &a); + NMIPAddr a; + int family; + + if (sz == 5 && data[0] == 1 /* LLDP_MGMT_ADDR_IP4 */) { + memcpy(&a, &data[1], sizeof(a.addr4)); + family = AF_INET; + } else if (sz == 17 && data[0] == 2 /* LLDP_MGMT_ADDR_IP6 */) { + memcpy(&a, &data[1], sizeof(a.addr6)); + family = AF_INET6; + } else + return NULL; + + return nm_utils_inet_ntop_dup(family, &a); } static const char * -format_string (const guint8 *data, gsize len, gboolean allow_trim, char **out_to_free) +format_string(const guint8 *data, gsize len, gboolean allow_trim, char **out_to_free) { - gboolean is_null_terminated = FALSE; + gboolean is_null_terminated = FALSE; - nm_assert (out_to_free && !*out_to_free); + nm_assert(out_to_free && !*out_to_free); - if (allow_trim) { - while ( len > 0 - && data[len - 1] == '\0') { - is_null_terminated = TRUE; - len--; - } - } + if (allow_trim) { + while (len > 0 && data[len - 1] == '\0') { + is_null_terminated = TRUE; + len--; + } + } - if (len == 0) - return NULL; + if (len == 0) + return NULL; - if (memchr (data, len, '\0')) - return NULL; + if (memchr(data, len, '\0')) + return NULL; - return nm_utils_buf_utf8safe_escape (data, - is_null_terminated ? -1 : (gssize) len, - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL - | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, - out_to_free); + return nm_utils_buf_utf8safe_escape(data, + is_null_terminated ? -1 : (gssize) len, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL + | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, + out_to_free); } static char * -format_string_cp (const guint8 *data, gsize len, gboolean allow_trim) +format_string_cp(const guint8 *data, gsize len, gboolean allow_trim) { - char *s_free = NULL; - const char *s; + char * s_free = NULL; + const char *s; - s = format_string (data, len, allow_trim, &s_free); - nm_assert (!s_free || s == s_free); - return s ? (s_free ?: g_strdup (s)) : NULL; + s = format_string(data, len, allow_trim, &s_free); + nm_assert(!s_free || s == s_free); + return s ? (s_free ?: g_strdup(s)) : NULL; } static LldpNeighbor * -lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd) +lldp_neighbor_new(sd_lldp_neighbor *neighbor_sd) { - LldpNeighbor *neigh; - guint8 chassis_id_type; - guint8 port_id_type; - const guint8 *chassis_id; - const guint8 *port_id; - gsize chassis_id_len; - gsize port_id_len; - gs_free char *s_chassis_id = NULL; - gs_free char *s_port_id = NULL; - - if (!lldp_neighbor_id_get (neighbor_sd, - &chassis_id_type, - &chassis_id, - &chassis_id_len, - &port_id_type, - &port_id, - &port_id_len)) - return NULL; - - switch (chassis_id_type) { - case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT: - case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS: - case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT: - case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME: - case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED: - s_chassis_id = format_string_cp (chassis_id, chassis_id_len, FALSE); - break; - case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: - s_chassis_id = nm_utils_hwaddr_ntoa (chassis_id, chassis_id_len); - break; - case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS: - s_chassis_id = format_network_address (chassis_id, chassis_id_len); - break; - } - if (!s_chassis_id) { - /* Invalid/unsupported chassis_id? Expose as hex string. This format is not stable, and - * in the future we may add a better string representation for these case (thus - * changing the API). */ - s_chassis_id = nm_utils_bin2hexstr_full (chassis_id, chassis_id_len, '\0', FALSE, NULL); - } - - switch (port_id_type) { - case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: - case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT: - case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME: - case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: - s_port_id = format_string_cp (port_id, port_id_len, FALSE); - break; - case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS: - s_port_id = nm_utils_hwaddr_ntoa (port_id, port_id_len); - break; - case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS: - s_port_id = format_network_address (port_id, port_id_len); - break; - } - if (!s_port_id) { - /* Invalid/unsupported port_id? Expose as hex string. This format is not stable, and - * in the future we may add a better string representation for these case (thus - * changing the API). */ - s_port_id = nm_utils_bin2hexstr_full (port_id, port_id_len, '\0', FALSE, NULL); - } - - neigh = g_slice_new (LldpNeighbor); - *neigh = (LldpNeighbor) { - .neighbor_sd = sd_lldp_neighbor_ref (neighbor_sd), - .chassis_id_type = chassis_id_type, - .chassis_id = g_steal_pointer (&s_chassis_id), - .port_id_type = port_id_type, - .port_id = g_steal_pointer (&s_port_id), - }; - return neigh; + LldpNeighbor *neigh; + guint8 chassis_id_type; + guint8 port_id_type; + const guint8 *chassis_id; + const guint8 *port_id; + gsize chassis_id_len; + gsize port_id_len; + gs_free char *s_chassis_id = NULL; + gs_free char *s_port_id = NULL; + + if (!lldp_neighbor_id_get(neighbor_sd, + &chassis_id_type, + &chassis_id, + &chassis_id_len, + &port_id_type, + &port_id, + &port_id_len)) + return NULL; + + switch (chassis_id_type) { + case SD_LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT: + case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS: + case SD_LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT: + case SD_LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME: + case SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED: + s_chassis_id = format_string_cp(chassis_id, chassis_id_len, FALSE); + break; + case SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: + s_chassis_id = nm_utils_hwaddr_ntoa(chassis_id, chassis_id_len); + break; + case SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS: + s_chassis_id = format_network_address(chassis_id, chassis_id_len); + break; + } + if (!s_chassis_id) { + /* Invalid/unsupported chassis_id? Expose as hex string. This format is not stable, and + * in the future we may add a better string representation for these case (thus + * changing the API). */ + s_chassis_id = nm_utils_bin2hexstr_full(chassis_id, chassis_id_len, '\0', FALSE, NULL); + } + + switch (port_id_type) { + case SD_LLDP_PORT_SUBTYPE_INTERFACE_ALIAS: + case SD_LLDP_PORT_SUBTYPE_PORT_COMPONENT: + case SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME: + case SD_LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED: + s_port_id = format_string_cp(port_id, port_id_len, FALSE); + break; + case SD_LLDP_PORT_SUBTYPE_MAC_ADDRESS: + s_port_id = nm_utils_hwaddr_ntoa(port_id, port_id_len); + break; + case SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS: + s_port_id = format_network_address(port_id, port_id_len); + break; + } + if (!s_port_id) { + /* Invalid/unsupported port_id? Expose as hex string. This format is not stable, and + * in the future we may add a better string representation for these case (thus + * changing the API). */ + s_port_id = nm_utils_bin2hexstr_full(port_id, port_id_len, '\0', FALSE, NULL); + } + + neigh = g_slice_new(LldpNeighbor); + *neigh = (LldpNeighbor){ + .neighbor_sd = sd_lldp_neighbor_ref(neighbor_sd), + .chassis_id_type = chassis_id_type, + .chassis_id = g_steal_pointer(&s_chassis_id), + .port_id_type = port_id_type, + .port_id = g_steal_pointer(&s_port_id), + }; + return neigh; } static GVariant * -lldp_neighbor_to_variant (LldpNeighbor *neigh) +lldp_neighbor_to_variant(LldpNeighbor *neigh) { - struct ether_addr destination_address; - GVariantBuilder builder; - const char *str; - const guint8 *raw_data; - gsize raw_len; - uint16_t u16; - uint8_t *data8; - gsize len; - int r; - - if (neigh->variant) - return neigh->variant; - - lldp_neighbor_get_raw (neigh, &raw_data, &raw_len); - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - - nm_g_variant_builder_add_sv_bytearray (&builder, - NM_LLDP_ATTR_RAW, - raw_data, - raw_len); - nm_g_variant_builder_add_sv_uint32 (&builder, NM_LLDP_ATTR_CHASSIS_ID_TYPE, neigh->chassis_id_type); - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_CHASSIS_ID, neigh->chassis_id); - nm_g_variant_builder_add_sv_uint32 (&builder, NM_LLDP_ATTR_PORT_ID_TYPE, neigh->port_id_type); - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_PORT_ID, neigh->port_id); - - r = sd_lldp_neighbor_get_destination_address (neigh->neighbor_sd, &destination_address); - if (r < 0) - str = NULL; - else if (nm_utils_ether_addr_equal (&destination_address, LLDP_MAC_NEAREST_BRIDGE)) - str = NM_LLDP_DEST_NEAREST_BRIDGE; - else if (nm_utils_ether_addr_equal (&destination_address, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE)) - str = NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE; - else if (nm_utils_ether_addr_equal (&destination_address, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE)) - str = NM_LLDP_DEST_NEAREST_CUSTOMER_BRIDGE; - else - str = NULL; - if (str) - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_DESTINATION, str); - - if (sd_lldp_neighbor_get_port_description (neigh->neighbor_sd, &str) == 0) - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_PORT_DESCRIPTION, str); - - if (sd_lldp_neighbor_get_system_name (neigh->neighbor_sd, &str) == 0) - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_SYSTEM_NAME, str); - - if (sd_lldp_neighbor_get_system_description (neigh->neighbor_sd, &str) == 0) - nm_g_variant_builder_add_sv_str (&builder, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, str); - - if (sd_lldp_neighbor_get_system_capabilities (neigh->neighbor_sd, &u16) == 0) - nm_g_variant_builder_add_sv_uint32 (&builder, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, u16); - - r = sd_lldp_neighbor_tlv_rewind (neigh->neighbor_sd); - if (r < 0) - nm_assert_not_reached (); - else { - gboolean v_management_addresses_has = FALSE; - GVariantBuilder v_management_addresses; - GVariant *v_ieee_802_1_pvid = NULL; - GVariant *v_ieee_802_1_ppvid = NULL; - GVariant *v_ieee_802_1_ppvid_flags = NULL; - GVariantBuilder v_ieee_802_1_ppvids; - GVariant *v_ieee_802_1_vid = NULL; - GVariant *v_ieee_802_1_vlan_name = NULL; - GVariantBuilder v_ieee_802_1_vlans; - GVariant *v_ieee_802_3_mac_phy_conf = NULL; - GVariant *v_ieee_802_3_power_via_mdi = NULL; - GVariant *v_ieee_802_3_max_frame_size = NULL; - GVariant *v_mud_url = NULL; - GVariantBuilder tmp_builder; - GVariant *tmp_variant; - - do { - guint8 oui[3]; - guint8 type; - guint8 subtype; - - if (sd_lldp_neighbor_tlv_get_type (neigh->neighbor_sd, &type) < 0) - continue; - - if (sd_lldp_neighbor_tlv_get_raw (neigh->neighbor_sd, (void *) &data8, &len) < 0) - continue; - - switch (type) { - case SD_LLDP_TYPE_MGMT_ADDRESS: - tmp_variant = parse_management_address_tlv (data8, len); - if (tmp_variant) { - if (!v_management_addresses_has) { - v_management_addresses_has = TRUE; - g_variant_builder_init (&v_management_addresses, G_VARIANT_TYPE ("aa{sv}")); - } - g_variant_builder_add_value (&v_management_addresses, tmp_variant); - } - continue; - case SD_LLDP_TYPE_PRIVATE: - break; - default: - continue; - } - - r = sd_lldp_neighbor_tlv_get_oui (neigh->neighbor_sd, oui, &subtype); - if (r < 0) { - if (r == -ENXIO) - continue; - - /* in other cases, something is seriously wrong. Abort, but - * keep what we parsed so far. */ - break; - } - - if (len <= 6) - continue; - - /* skip over leading TLV, OUI and subtype */ + struct ether_addr destination_address; + GVariantBuilder builder; + const char * str; + const guint8 * raw_data; + gsize raw_len; + uint16_t u16; + uint8_t * data8; + gsize len; + int r; + + if (neigh->variant) + return neigh->variant; + + lldp_neighbor_get_raw(neigh, &raw_data, &raw_len); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + + nm_g_variant_builder_add_sv_bytearray(&builder, NM_LLDP_ATTR_RAW, raw_data, raw_len); + nm_g_variant_builder_add_sv_uint32(&builder, + NM_LLDP_ATTR_CHASSIS_ID_TYPE, + neigh->chassis_id_type); + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_CHASSIS_ID, neigh->chassis_id); + nm_g_variant_builder_add_sv_uint32(&builder, NM_LLDP_ATTR_PORT_ID_TYPE, neigh->port_id_type); + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_PORT_ID, neigh->port_id); + + r = sd_lldp_neighbor_get_destination_address(neigh->neighbor_sd, &destination_address); + if (r < 0) + str = NULL; + else if (nm_utils_ether_addr_equal(&destination_address, LLDP_MAC_NEAREST_BRIDGE)) + str = NM_LLDP_DEST_NEAREST_BRIDGE; + else if (nm_utils_ether_addr_equal(&destination_address, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE)) + str = NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE; + else if (nm_utils_ether_addr_equal(&destination_address, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE)) + str = NM_LLDP_DEST_NEAREST_CUSTOMER_BRIDGE; + else + str = NULL; + if (str) + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_DESTINATION, str); + + if (sd_lldp_neighbor_get_port_description(neigh->neighbor_sd, &str) == 0) + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_PORT_DESCRIPTION, str); + + if (sd_lldp_neighbor_get_system_name(neigh->neighbor_sd, &str) == 0) + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_SYSTEM_NAME, str); + + if (sd_lldp_neighbor_get_system_description(neigh->neighbor_sd, &str) == 0) + nm_g_variant_builder_add_sv_str(&builder, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, str); + + if (sd_lldp_neighbor_get_system_capabilities(neigh->neighbor_sd, &u16) == 0) + nm_g_variant_builder_add_sv_uint32(&builder, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, u16); + + r = sd_lldp_neighbor_tlv_rewind(neigh->neighbor_sd); + if (r < 0) + nm_assert_not_reached(); + else { + gboolean v_management_addresses_has = FALSE; + GVariantBuilder v_management_addresses; + GVariant * v_ieee_802_1_pvid = NULL; + GVariant * v_ieee_802_1_ppvid = NULL; + GVariant * v_ieee_802_1_ppvid_flags = NULL; + GVariantBuilder v_ieee_802_1_ppvids; + GVariant * v_ieee_802_1_vid = NULL; + GVariant * v_ieee_802_1_vlan_name = NULL; + GVariantBuilder v_ieee_802_1_vlans; + GVariant * v_ieee_802_3_mac_phy_conf = NULL; + GVariant * v_ieee_802_3_power_via_mdi = NULL; + GVariant * v_ieee_802_3_max_frame_size = NULL; + GVariant * v_mud_url = NULL; + GVariantBuilder tmp_builder; + GVariant * tmp_variant; + + do { + guint8 oui[3]; + guint8 type; + guint8 subtype; + + if (sd_lldp_neighbor_tlv_get_type(neigh->neighbor_sd, &type) < 0) + continue; + + if (sd_lldp_neighbor_tlv_get_raw(neigh->neighbor_sd, (void *) &data8, &len) < 0) + continue; + + switch (type) { + case SD_LLDP_TYPE_MGMT_ADDRESS: + tmp_variant = parse_management_address_tlv(data8, len); + if (tmp_variant) { + if (!v_management_addresses_has) { + v_management_addresses_has = TRUE; + g_variant_builder_init(&v_management_addresses, G_VARIANT_TYPE("aa{sv}")); + } + g_variant_builder_add_value(&v_management_addresses, tmp_variant); + } + continue; + case SD_LLDP_TYPE_PRIVATE: + break; + default: + continue; + } + + r = sd_lldp_neighbor_tlv_get_oui(neigh->neighbor_sd, oui, &subtype); + if (r < 0) { + if (r == -ENXIO) + continue; + + /* in other cases, something is seriously wrong. Abort, but + * keep what we parsed so far. */ + break; + } + + if (len <= 6) + continue; + + /* skip over leading TLV, OUI and subtype */ #if NM_MORE_ASSERTS > 5 - { - guint8 check_hdr[] = { - 0xfe | (((len - 2) >> 8) & 0x01), ((len - 2) & 0xFF), - oui[0], oui[1], oui[2], - subtype - }; - - nm_assert (len > 2 + 3 +1); - nm_assert (memcmp (data8, check_hdr, sizeof check_hdr) == 0); - } + { + guint8 check_hdr[] = {0xfe | (((len - 2) >> 8) & 0x01), + ((len - 2) & 0xFF), + oui[0], + oui[1], + oui[2], + subtype}; + + nm_assert(len > 2 + 3 + 1); + nm_assert(memcmp(data8, check_hdr, sizeof check_hdr) == 0); + } #endif - data8 += 6; - len -= 6; - - if (memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0) { - switch (subtype) { - case SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID: - if (len != 2) - continue; - if (!v_ieee_802_1_pvid) - v_ieee_802_1_pvid = g_variant_new_uint32 (unaligned_read_be16 (data8)); - break; - case SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID: - if (len != 3) - continue; - if (!v_ieee_802_1_ppvid) { - v_ieee_802_1_ppvid_flags = g_variant_new_uint32 (data8[0]); - v_ieee_802_1_ppvid = g_variant_new_uint32 (unaligned_read_be16 (&data8[1])); - g_variant_builder_init (&v_ieee_802_1_ppvids, G_VARIANT_TYPE ("aa{sv}")); - } - g_variant_builder_init (&tmp_builder, G_VARIANT_TYPE ("a{sv}")); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "ppvid", unaligned_read_be16 (&data8[1])); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "flags", data8[0]); - g_variant_builder_add_value (&v_ieee_802_1_ppvids, g_variant_builder_end (&tmp_builder)); - break; - case SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: { - gs_free char *name_to_free = NULL; - const char *name; - guint32 vid; - gsize l; - - if (len <= 3) - continue; - - l = data8[2]; - if (len != 3 + l) - continue; - if (l > 32) - continue; - - name = format_string (&data8[3], l, TRUE, &name_to_free); - if (!name) - continue; - - vid = unaligned_read_be16 (&data8[0]); - if (!v_ieee_802_1_vid) { - v_ieee_802_1_vid = g_variant_new_uint32 (vid); - v_ieee_802_1_vlan_name = g_variant_new_string (name); - g_variant_builder_init (&v_ieee_802_1_vlans, G_VARIANT_TYPE ("aa{sv}")); - } - g_variant_builder_init (&tmp_builder, G_VARIANT_TYPE ("a{sv}")); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "vid", vid); - nm_g_variant_builder_add_sv_str (&tmp_builder, "name", name); - g_variant_builder_add_value (&v_ieee_802_1_vlans, g_variant_builder_end (&tmp_builder)); - break; - } - default: - continue; - } - } else if (memcmp (oui, SD_LLDP_OUI_802_3, sizeof (oui)) == 0) { - switch (subtype) { - case SD_LLDP_OUI_802_3_SUBTYPE_MAC_PHY_CONFIG_STATUS: - if (len != 5) - continue; - - if (!v_ieee_802_3_mac_phy_conf) { - g_variant_builder_init (&tmp_builder, G_VARIANT_TYPE ("a{sv}")); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "autoneg", data8[0]); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "pmd-autoneg-cap", unaligned_read_be16 (&data8[1])); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "operational-mau-type", unaligned_read_be16 (&data8[3])); - v_ieee_802_3_mac_phy_conf = g_variant_builder_end (&tmp_builder); - } - break; - case SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI: - if (len != 3) - continue; - - if (!v_ieee_802_3_power_via_mdi) { - g_variant_builder_init (&tmp_builder, G_VARIANT_TYPE ("a{sv}")); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "mdi-power-support", data8[0]); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "pse-power-pair", data8[1]); - nm_g_variant_builder_add_sv_uint32 (&tmp_builder, "power-class", data8[2]); - v_ieee_802_3_power_via_mdi = g_variant_builder_end (&tmp_builder); - } - break; - case SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE: - if (len != 2) - continue; - if (!v_ieee_802_3_max_frame_size) - v_ieee_802_3_max_frame_size = g_variant_new_uint32 (unaligned_read_be16 (data8)); - break; - } - } else if (memcmp (oui, SD_LLDP_OUI_MUD, sizeof (oui)) == 0) { - switch (subtype) { - case SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION: - if (!v_mud_url) { - gs_free char *s_free = NULL; - const char *s; - - s = format_string (data8, len, TRUE, &s_free); - if (s) - v_mud_url = g_variant_new_string (s); - } - break; - } - } - } while (sd_lldp_neighbor_tlv_next (neigh->neighbor_sd) > 0); - - if (v_management_addresses_has) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, g_variant_builder_end (&v_management_addresses)); - if (v_ieee_802_1_pvid) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_PVID, v_ieee_802_1_pvid); - if (v_ieee_802_1_ppvid) { - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_PPVID, v_ieee_802_1_ppvid); - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, v_ieee_802_1_ppvid_flags); - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_PPVIDS, g_variant_builder_end (&v_ieee_802_1_ppvids)); - } - if (v_ieee_802_1_vid) { - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_VID, v_ieee_802_1_vid); - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, v_ieee_802_1_vlan_name); - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_1_VLANS, g_variant_builder_end (&v_ieee_802_1_vlans)); - } - if (v_ieee_802_3_mac_phy_conf) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, v_ieee_802_3_mac_phy_conf); - if (v_ieee_802_3_power_via_mdi) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, v_ieee_802_3_power_via_mdi); - if (v_ieee_802_3_max_frame_size) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, v_ieee_802_3_max_frame_size); - if (v_mud_url) - nm_g_variant_builder_add_sv (&builder, NM_LLDP_ATTR_MUD_URL, v_mud_url); - } - - return (neigh->variant = g_variant_ref_sink (g_variant_builder_end (&builder))); + data8 += 6; + len -= 6; + + if (memcmp(oui, SD_LLDP_OUI_802_1, sizeof(oui)) == 0) { + switch (subtype) { + case SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID: + if (len != 2) + continue; + if (!v_ieee_802_1_pvid) + v_ieee_802_1_pvid = g_variant_new_uint32(unaligned_read_be16(data8)); + break; + case SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID: + if (len != 3) + continue; + if (!v_ieee_802_1_ppvid) { + v_ieee_802_1_ppvid_flags = g_variant_new_uint32(data8[0]); + v_ieee_802_1_ppvid = g_variant_new_uint32(unaligned_read_be16(&data8[1])); + g_variant_builder_init(&v_ieee_802_1_ppvids, G_VARIANT_TYPE("aa{sv}")); + } + g_variant_builder_init(&tmp_builder, G_VARIANT_TYPE("a{sv}")); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, + "ppvid", + unaligned_read_be16(&data8[1])); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, "flags", data8[0]); + g_variant_builder_add_value(&v_ieee_802_1_ppvids, + g_variant_builder_end(&tmp_builder)); + break; + case SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: + { + gs_free char *name_to_free = NULL; + const char * name; + guint32 vid; + gsize l; + + if (len <= 3) + continue; + + l = data8[2]; + if (len != 3 + l) + continue; + if (l > 32) + continue; + + name = format_string(&data8[3], l, TRUE, &name_to_free); + if (!name) + continue; + + vid = unaligned_read_be16(&data8[0]); + if (!v_ieee_802_1_vid) { + v_ieee_802_1_vid = g_variant_new_uint32(vid); + v_ieee_802_1_vlan_name = g_variant_new_string(name); + g_variant_builder_init(&v_ieee_802_1_vlans, G_VARIANT_TYPE("aa{sv}")); + } + g_variant_builder_init(&tmp_builder, G_VARIANT_TYPE("a{sv}")); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, "vid", vid); + nm_g_variant_builder_add_sv_str(&tmp_builder, "name", name); + g_variant_builder_add_value(&v_ieee_802_1_vlans, + g_variant_builder_end(&tmp_builder)); + break; + } + default: + continue; + } + } else if (memcmp(oui, SD_LLDP_OUI_802_3, sizeof(oui)) == 0) { + switch (subtype) { + case SD_LLDP_OUI_802_3_SUBTYPE_MAC_PHY_CONFIG_STATUS: + if (len != 5) + continue; + + if (!v_ieee_802_3_mac_phy_conf) { + g_variant_builder_init(&tmp_builder, G_VARIANT_TYPE("a{sv}")); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, "autoneg", data8[0]); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, + "pmd-autoneg-cap", + unaligned_read_be16(&data8[1])); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, + "operational-mau-type", + unaligned_read_be16(&data8[3])); + v_ieee_802_3_mac_phy_conf = g_variant_builder_end(&tmp_builder); + } + break; + case SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI: + if (len != 3) + continue; + + if (!v_ieee_802_3_power_via_mdi) { + g_variant_builder_init(&tmp_builder, G_VARIANT_TYPE("a{sv}")); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, + "mdi-power-support", + data8[0]); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, + "pse-power-pair", + data8[1]); + nm_g_variant_builder_add_sv_uint32(&tmp_builder, "power-class", data8[2]); + v_ieee_802_3_power_via_mdi = g_variant_builder_end(&tmp_builder); + } + break; + case SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE: + if (len != 2) + continue; + if (!v_ieee_802_3_max_frame_size) + v_ieee_802_3_max_frame_size = + g_variant_new_uint32(unaligned_read_be16(data8)); + break; + } + } else if (memcmp(oui, SD_LLDP_OUI_MUD, sizeof(oui)) == 0) { + switch (subtype) { + case SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION: + if (!v_mud_url) { + gs_free char *s_free = NULL; + const char * s; + + s = format_string(data8, len, TRUE, &s_free); + if (s) + v_mud_url = g_variant_new_string(s); + } + break; + } + } + } while (sd_lldp_neighbor_tlv_next(neigh->neighbor_sd) > 0); + + if (v_management_addresses_has) + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, + g_variant_builder_end(&v_management_addresses)); + if (v_ieee_802_1_pvid) + nm_g_variant_builder_add_sv(&builder, NM_LLDP_ATTR_IEEE_802_1_PVID, v_ieee_802_1_pvid); + if (v_ieee_802_1_ppvid) { + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_1_PPVID, + v_ieee_802_1_ppvid); + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, + v_ieee_802_1_ppvid_flags); + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_1_PPVIDS, + g_variant_builder_end(&v_ieee_802_1_ppvids)); + } + if (v_ieee_802_1_vid) { + nm_g_variant_builder_add_sv(&builder, NM_LLDP_ATTR_IEEE_802_1_VID, v_ieee_802_1_vid); + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, + v_ieee_802_1_vlan_name); + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_1_VLANS, + g_variant_builder_end(&v_ieee_802_1_vlans)); + } + if (v_ieee_802_3_mac_phy_conf) + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, + v_ieee_802_3_mac_phy_conf); + if (v_ieee_802_3_power_via_mdi) + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, + v_ieee_802_3_power_via_mdi); + if (v_ieee_802_3_max_frame_size) + nm_g_variant_builder_add_sv(&builder, + NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, + v_ieee_802_3_max_frame_size); + if (v_mud_url) + nm_g_variant_builder_add_sv(&builder, NM_LLDP_ATTR_MUD_URL, v_mud_url); + } + + return (neigh->variant = g_variant_ref_sink(g_variant_builder_end(&builder))); } /*****************************************************************************/ GVariant * -nmtst_lldp_parse_from_raw (const guint8 *raw_data, - gsize raw_len) +nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len) { - nm_auto (sd_lldp_neighbor_unrefp) sd_lldp_neighbor *neighbor_sd = NULL; - nm_auto (lldp_neighbor_freep) LldpNeighbor *neigh = NULL; - GVariant *variant; - int r; + nm_auto(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *neighbor_sd = NULL; + nm_auto(lldp_neighbor_freep) LldpNeighbor * neigh = NULL; + GVariant * variant; + int r; - g_assert (raw_data); - g_assert (raw_len > 0); + g_assert(raw_data); + g_assert(raw_len > 0); - r = sd_lldp_neighbor_from_raw (&neighbor_sd, raw_data, raw_len); - g_assert (r >= 0); + r = sd_lldp_neighbor_from_raw(&neighbor_sd, raw_data, raw_len); + g_assert(r >= 0); - neigh = lldp_neighbor_new (neighbor_sd); - g_assert (neigh); + neigh = lldp_neighbor_new(neighbor_sd); + g_assert(neigh); - variant = lldp_neighbor_to_variant (neigh); - g_assert (variant); + variant = lldp_neighbor_to_variant(neigh); + g_assert(variant); - return g_variant_ref (variant); + return g_variant_ref(variant); } /*****************************************************************************/ static void -data_changed_notify (NMLldpListener *self, NMLldpListenerPrivate *priv) +data_changed_notify(NMLldpListener *self, NMLldpListenerPrivate *priv) { - nm_clear_g_variant (&priv->variant); - _notify (self, PROP_NEIGHBORS); + nm_clear_g_variant(&priv->variant); + _notify(self, PROP_NEIGHBORS); } static gboolean -data_changed_timeout (gpointer user_data) +data_changed_timeout(gpointer user_data) { - NMLldpListener *self = user_data; - NMLldpListenerPrivate *priv; + NMLldpListener * self = user_data; + NMLldpListenerPrivate *priv; - g_return_val_if_fail (NM_IS_LLDP_LISTENER (self), G_SOURCE_REMOVE); + g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), G_SOURCE_REMOVE); - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - priv->ratelimit_id = 0; - priv->ratelimit_next_nsec = nm_utils_get_monotonic_timestamp_nsec() + MIN_UPDATE_INTERVAL_NSEC; - data_changed_notify (self, priv); - return G_SOURCE_REMOVE; + priv->ratelimit_id = 0; + priv->ratelimit_next_nsec = nm_utils_get_monotonic_timestamp_nsec() + MIN_UPDATE_INTERVAL_NSEC; + data_changed_notify(self, priv); + return G_SOURCE_REMOVE; } static void -data_changed_schedule (NMLldpListener *self) +data_changed_schedule(NMLldpListener *self) { - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE (self); - gint64 now_nsec; - - if (priv->ratelimit_id != 0) - return; - - now_nsec = nm_utils_get_monotonic_timestamp_nsec (); - if (now_nsec < priv->ratelimit_next_nsec) { - priv->ratelimit_id = g_timeout_add_full (G_PRIORITY_LOW, - NM_UTILS_NSEC_TO_MSEC_CEIL (priv->ratelimit_next_nsec - now_nsec), - data_changed_timeout, - self, - NULL); - return; - } - - priv->ratelimit_id = g_idle_add_full (G_PRIORITY_LOW, - data_changed_timeout, - self, - NULL); + NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); + gint64 now_nsec; + + if (priv->ratelimit_id != 0) + return; + + now_nsec = nm_utils_get_monotonic_timestamp_nsec(); + if (now_nsec < priv->ratelimit_next_nsec) { + priv->ratelimit_id = + g_timeout_add_full(G_PRIORITY_LOW, + NM_UTILS_NSEC_TO_MSEC_CEIL(priv->ratelimit_next_nsec - now_nsec), + data_changed_timeout, + self, + NULL); + return; + } + + priv->ratelimit_id = g_idle_add_full(G_PRIORITY_LOW, data_changed_timeout, self, NULL); } static void -process_lldp_neighbor (NMLldpListener *self, sd_lldp_neighbor *neighbor_sd, gboolean remove) +process_lldp_neighbor(NMLldpListener *self, sd_lldp_neighbor *neighbor_sd, gboolean remove) { - NMLldpListenerPrivate *priv; - nm_auto (lldp_neighbor_freep) LldpNeighbor *neigh = NULL; - LldpNeighbor *neigh_old; + NMLldpListenerPrivate * priv; + nm_auto(lldp_neighbor_freep) LldpNeighbor *neigh = NULL; + LldpNeighbor * neigh_old; - g_return_if_fail (NM_IS_LLDP_LISTENER (self)); + g_return_if_fail(NM_IS_LLDP_LISTENER(self)); - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - g_return_if_fail (priv->lldp_handle); - g_return_if_fail (neighbor_sd); + g_return_if_fail(priv->lldp_handle); + g_return_if_fail(neighbor_sd); - nm_assert (priv->lldp_neighbors); + nm_assert(priv->lldp_neighbors); - neigh = lldp_neighbor_new (neighbor_sd); - if (!neigh) { - _LOGT ("process: failed to parse neighbor"); - return; - } + neigh = lldp_neighbor_new(neighbor_sd); + if (!neigh) { + _LOGT("process: failed to parse neighbor"); + return; + } - neigh_old = g_hash_table_lookup (priv->lldp_neighbors, neigh); + neigh_old = g_hash_table_lookup(priv->lldp_neighbors, neigh); - if (remove) { - if (neigh_old) { - _LOGT ("process: %s neigh: "LOG_NEIGH_FMT, - "remove", LOG_NEIGH_ARG (neigh)); + if (remove) { + if (neigh_old) { + _LOGT("process: %s neigh: " LOG_NEIGH_FMT, "remove", LOG_NEIGH_ARG(neigh)); - g_hash_table_remove (priv->lldp_neighbors, neigh_old); - goto handle_changed; - } - return; - } + g_hash_table_remove(priv->lldp_neighbors, neigh_old); + goto handle_changed; + } + return; + } - if ( neigh_old - && lldp_neighbor_equal (neigh_old, neigh)) - return; + if (neigh_old && lldp_neighbor_equal(neigh_old, neigh)) + return; - _LOGD ("process: %s neigh: "LOG_NEIGH_FMT, - neigh_old ? "update" : "new", - LOG_NEIGH_ARG (neigh)); + _LOGD("process: %s neigh: " LOG_NEIGH_FMT, neigh_old ? "update" : "new", LOG_NEIGH_ARG(neigh)); - g_hash_table_add (priv->lldp_neighbors, g_steal_pointer (&neigh)); + g_hash_table_add(priv->lldp_neighbors, g_steal_pointer(&neigh)); handle_changed: - data_changed_schedule (self); + data_changed_schedule(self); } static void -lldp_event_handler (sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) +lldp_event_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) { - process_lldp_neighbor (userdata, - n, - !NM_IN_SET (event, SD_LLDP_EVENT_ADDED, - SD_LLDP_EVENT_UPDATED, - SD_LLDP_EVENT_REFRESHED)); + process_lldp_neighbor( + userdata, + n, + !NM_IN_SET(event, SD_LLDP_EVENT_ADDED, SD_LLDP_EVENT_UPDATED, SD_LLDP_EVENT_REFRESHED)); } gboolean -nm_lldp_listener_start (NMLldpListener *self, int ifindex, GError **error) +nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error) { - NMLldpListenerPrivate *priv; - int ret; - - g_return_val_if_fail (NM_IS_LLDP_LISTENER (self), FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); - - if (priv->lldp_handle) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "already running"); - return FALSE; - } - - ret = sd_lldp_new (&priv->lldp_handle); - if (ret < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "initialization failed"); - return FALSE; - } - - ret = sd_lldp_set_ifindex (priv->lldp_handle, ifindex); - if (ret < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "failed setting ifindex"); - goto err; - } - - ret = sd_lldp_set_callback (priv->lldp_handle, lldp_event_handler, self); - if (ret < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "set callback failed"); - goto err; - } - - ret = sd_lldp_set_neighbors_max (priv->lldp_handle, MAX_NEIGHBORS); - nm_assert (ret == 0); - - priv->ifindex = ifindex; - - ret = sd_lldp_attach_event (priv->lldp_handle, NULL, 0); - if (ret < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "attach event failed"); - goto err_free; - } - - ret = sd_lldp_start (priv->lldp_handle); - if (ret < 0) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "start failed"); - goto err; - } - - priv->lldp_neighbors = g_hash_table_new_full (lldp_neighbor_id_hash, - lldp_neighbor_id_equal, - (GDestroyNotify) lldp_neighbor_free, NULL); - - _LOGD ("start"); - - return TRUE; + NMLldpListenerPrivate *priv; + int ret; + + g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); + + if (priv->lldp_handle) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "already running"); + return FALSE; + } + + ret = sd_lldp_new(&priv->lldp_handle); + if (ret < 0) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "initialization failed"); + return FALSE; + } + + ret = sd_lldp_set_ifindex(priv->lldp_handle, ifindex); + if (ret < 0) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "failed setting ifindex"); + goto err; + } + + ret = sd_lldp_set_callback(priv->lldp_handle, lldp_event_handler, self); + if (ret < 0) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "set callback failed"); + goto err; + } + + ret = sd_lldp_set_neighbors_max(priv->lldp_handle, MAX_NEIGHBORS); + nm_assert(ret == 0); + + priv->ifindex = ifindex; + + ret = sd_lldp_attach_event(priv->lldp_handle, NULL, 0); + if (ret < 0) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "attach event failed"); + goto err_free; + } + + ret = sd_lldp_start(priv->lldp_handle); + if (ret < 0) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "start failed"); + goto err; + } + + priv->lldp_neighbors = g_hash_table_new_full(lldp_neighbor_id_hash, + lldp_neighbor_id_equal, + (GDestroyNotify) lldp_neighbor_free, + NULL); + + _LOGD("start"); + + return TRUE; err: - sd_lldp_detach_event (priv->lldp_handle); + sd_lldp_detach_event(priv->lldp_handle); err_free: - sd_lldp_unref (priv->lldp_handle); - priv->lldp_handle = NULL; - priv->ifindex = 0; - return FALSE; + sd_lldp_unref(priv->lldp_handle); + priv->lldp_handle = NULL; + priv->ifindex = 0; + return FALSE; } void -nm_lldp_listener_stop (NMLldpListener *self) +nm_lldp_listener_stop(NMLldpListener *self) { - NMLldpListenerPrivate *priv; - guint size; - gboolean changed = FALSE; - - g_return_if_fail (NM_IS_LLDP_LISTENER (self)); - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); - - if (priv->lldp_handle) { - _LOGD ("stop"); - sd_lldp_stop (priv->lldp_handle); - sd_lldp_detach_event (priv->lldp_handle); - sd_lldp_unref (priv->lldp_handle); - priv->lldp_handle = NULL; - - size = g_hash_table_size (priv->lldp_neighbors); - g_hash_table_remove_all (priv->lldp_neighbors); - nm_clear_pointer (&priv->lldp_neighbors, g_hash_table_unref); - if ( size > 0 - || priv->ratelimit_id != 0) - changed = TRUE; - } - - nm_clear_g_source (&priv->ratelimit_id); - priv->ratelimit_next_nsec = 0; - priv->ifindex = 0; - - if (changed) - data_changed_notify (self, priv); + NMLldpListenerPrivate *priv; + guint size; + gboolean changed = FALSE; + + g_return_if_fail(NM_IS_LLDP_LISTENER(self)); + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); + + if (priv->lldp_handle) { + _LOGD("stop"); + sd_lldp_stop(priv->lldp_handle); + sd_lldp_detach_event(priv->lldp_handle); + sd_lldp_unref(priv->lldp_handle); + priv->lldp_handle = NULL; + + size = g_hash_table_size(priv->lldp_neighbors); + g_hash_table_remove_all(priv->lldp_neighbors); + nm_clear_pointer(&priv->lldp_neighbors, g_hash_table_unref); + if (size > 0 || priv->ratelimit_id != 0) + changed = TRUE; + } + + nm_clear_g_source(&priv->ratelimit_id); + priv->ratelimit_next_nsec = 0; + priv->ifindex = 0; + + if (changed) + data_changed_notify(self, priv); } gboolean -nm_lldp_listener_is_running (NMLldpListener *self) +nm_lldp_listener_is_running(NMLldpListener *self) { - NMLldpListenerPrivate *priv; + NMLldpListenerPrivate *priv; - g_return_val_if_fail (NM_IS_LLDP_LISTENER (self), FALSE); + g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); - return !!priv->lldp_handle; + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); + return !!priv->lldp_handle; } GVariant * -nm_lldp_listener_get_neighbors (NMLldpListener *self) +nm_lldp_listener_get_neighbors(NMLldpListener *self) { - NMLldpListenerPrivate *priv; - - g_return_val_if_fail (NM_IS_LLDP_LISTENER (self), FALSE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE (self); - - if (G_UNLIKELY (!priv->variant)) { - gs_free LldpNeighbor **neighbors = NULL; - GVariantBuilder array_builder; - guint i, n; - - g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); - neighbors = (LldpNeighbor **) nm_utils_hash_keys_to_array (priv->lldp_neighbors, - lldp_neighbor_id_cmp_p, - NULL, - &n); - for (i = 0; i < n; i++) - g_variant_builder_add_value (&array_builder, lldp_neighbor_to_variant (neighbors[i])); - priv->variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); - } - return priv->variant; + NMLldpListenerPrivate *priv; + + g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); + + priv = NM_LLDP_LISTENER_GET_PRIVATE(self); + + if (G_UNLIKELY(!priv->variant)) { + gs_free LldpNeighbor **neighbors = NULL; + GVariantBuilder array_builder; + guint i, n; + + g_variant_builder_init(&array_builder, G_VARIANT_TYPE("aa{sv}")); + neighbors = (LldpNeighbor **) + nm_utils_hash_keys_to_array(priv->lldp_neighbors, lldp_neighbor_id_cmp_p, NULL, &n); + for (i = 0; i < n; i++) + g_variant_builder_add_value(&array_builder, lldp_neighbor_to_variant(neighbors[i])); + priv->variant = g_variant_ref_sink(g_variant_builder_end(&array_builder)); + } + return priv->variant; } static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMLldpListener *self = NM_LLDP_LISTENER (object); - - switch (prop_id) { - case PROP_NEIGHBORS: - g_value_set_variant (value, nm_lldp_listener_get_neighbors (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMLldpListener *self = NM_LLDP_LISTENER(object); + + switch (prop_id) { + case PROP_NEIGHBORS: + g_value_set_variant(value, nm_lldp_listener_get_neighbors(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -nm_lldp_listener_init (NMLldpListener *self) +nm_lldp_listener_init(NMLldpListener *self) { - _LOGT ("lldp listener created"); + _LOGT("lldp listener created"); } NMLldpListener * -nm_lldp_listener_new (void) +nm_lldp_listener_new(void) { - return (NMLldpListener *) g_object_new (NM_TYPE_LLDP_LISTENER, NULL); + return (NMLldpListener *) g_object_new(NM_TYPE_LLDP_LISTENER, NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - nm_lldp_listener_stop (NM_LLDP_LISTENER (object)); + nm_lldp_listener_stop(NM_LLDP_LISTENER(object)); - G_OBJECT_CLASS (nm_lldp_listener_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_lldp_listener_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMLldpListener *self = NM_LLDP_LISTENER (object); - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE (self); + NMLldpListener * self = NM_LLDP_LISTENER(object); + NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - nm_lldp_listener_stop (self); + nm_lldp_listener_stop(self); - nm_clear_g_variant (&priv->variant); + nm_clear_g_variant(&priv->variant); - _LOGT ("lldp listener destroyed"); + _LOGT("lldp listener destroyed"); - G_OBJECT_CLASS (nm_lldp_listener_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_lldp_listener_parent_class)->finalize(object); } static void -nm_lldp_listener_class_init (NMLldpListenerClass *klass) +nm_lldp_listener_class_init(NMLldpListenerClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); - object_class->dispose = dispose; - object_class->finalize = finalize; - object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; - obj_properties[PROP_NEIGHBORS] = - g_param_spec_variant (NM_LLDP_LISTENER_NEIGHBORS, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + obj_properties[PROP_NEIGHBORS] = + g_param_spec_variant(NM_LLDP_LISTENER_NEIGHBORS, + "", + "", + G_VARIANT_TYPE("aa{sv}"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/nm-lldp-listener.h b/src/devices/nm-lldp-listener.h index adea91b8..8c83cd67 100644 --- a/src/devices/nm-lldp-listener.h +++ b/src/devices/nm-lldp-listener.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -6,26 +6,28 @@ #ifndef __NM_LLDP_LISTENER__ #define __NM_LLDP_LISTENER__ -#define NM_TYPE_LLDP_LISTENER (nm_lldp_listener_get_type ()) -#define NM_LLDP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LLDP_LISTENER, NMLldpListener)) -#define NM_LLDP_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) -#define NM_IS_LLDP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LLDP_LISTENER)) -#define NM_IS_LLDP_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_LLDP_LISTENER)) -#define NM_LLDP_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) +#define NM_TYPE_LLDP_LISTENER (nm_lldp_listener_get_type()) +#define NM_LLDP_LISTENER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_LLDP_LISTENER, NMLldpListener)) +#define NM_LLDP_LISTENER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) +#define NM_IS_LLDP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_LLDP_LISTENER)) +#define NM_IS_LLDP_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_LLDP_LISTENER)) +#define NM_LLDP_LISTENER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) #define NM_LLDP_LISTENER_NEIGHBORS "neighbors" typedef struct _NMLldpListenerClass NMLldpListenerClass; -GType nm_lldp_listener_get_type (void); -NMLldpListener *nm_lldp_listener_new (void); -gboolean nm_lldp_listener_start (NMLldpListener *self, int ifindex, GError **error); -void nm_lldp_listener_stop (NMLldpListener *self); -gboolean nm_lldp_listener_is_running (NMLldpListener *self); +GType nm_lldp_listener_get_type(void); +NMLldpListener *nm_lldp_listener_new(void); +gboolean nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error); +void nm_lldp_listener_stop(NMLldpListener *self); +gboolean nm_lldp_listener_is_running(NMLldpListener *self); -GVariant *nm_lldp_listener_get_neighbors (NMLldpListener *self); +GVariant *nm_lldp_listener_get_neighbors(NMLldpListener *self); -GVariant *nmtst_lldp_parse_from_raw (const guint8 *raw_data, - gsize raw_len); +GVariant *nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len); #endif /* __NM_LLDP_LISTENER__ */ diff --git a/src/devices/ovs/nm-device-ovs-bridge.c b/src/devices/ovs/nm-device-ovs-bridge.c index 59096803..a7b7a539 100644 --- a/src/devices/ovs/nm-device-ovs-bridge.c +++ b/src/devices/ovs/nm-device-ovs-bridge.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -15,117 +15,111 @@ #include "nm-setting-ovs-bridge.h" #include "devices/nm-device-logging.h" -_LOG_DECLARE_SELF (NMDeviceOvsBridge); +_LOG_DECLARE_SELF(NMDeviceOvsBridge); /*****************************************************************************/ struct _NMDeviceOvsBridge { - NMDevice parent; + NMDevice parent; }; struct _NMDeviceOvsBridgeClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceOvsBridge, nm_device_ovs_bridge, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceOvsBridge, nm_device_ovs_bridge, NM_TYPE_DEVICE) /*****************************************************************************/ static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - return "ovs-bridge"; + return "ovs-bridge"; } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - /* The actual backing resources will be created on enslavement by the port - * when it can identify the port and the bridge. */ + /* The actual backing resources will be created on enslavement by the port + * when it can identify the port and the bridge. */ - return TRUE; + return TRUE; } static gboolean -unrealize (NMDevice *device, GError **error) +unrealize(NMDevice *device, GError **error) { - return TRUE; + return TRUE; } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - return NM_ACT_STAGE_RETURN_IP_FAIL; + return NM_ACT_STAGE_RETURN_IP_FAIL; } static gboolean -enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - if (!configure) - return TRUE; + if (!configure) + return TRUE; - if (!NM_IS_DEVICE_OVS_PORT (slave)) - return FALSE; + if (!NM_IS_DEVICE_OVS_PORT(slave)) + return FALSE; - return TRUE; + return TRUE; } static void -release_slave (NMDevice *device, NMDevice *slave, gboolean configure) -{ -} +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) +{} /*****************************************************************************/ static void -nm_device_ovs_bridge_init (NMDeviceOvsBridge *self) -{ -} +nm_device_ovs_bridge_init(NMDeviceOvsBridge *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_ovs_bridge = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Slaves", "ao", NM_DEVICE_SLAVES), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass) +nm_device_ovs_bridge_class_init(NMDeviceOvsBridgeClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_bridge); - - device_class->connection_type_supported = NM_SETTING_OVS_BRIDGE_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OVS_BRIDGE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (); - - device_class->is_master = TRUE; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->unrealize = unrealize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_bridge); + + device_class->connection_type_supported = NM_SETTING_OVS_BRIDGE_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_OVS_BRIDGE_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); + + device_class->is_master = TRUE; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->unrealize = unrealize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; } diff --git a/src/devices/ovs/nm-device-ovs-bridge.h b/src/devices/ovs/nm-device-ovs-bridge.h index 07a1fee7..ba04bfeb 100644 --- a/src/devices/ovs/nm-device-ovs-bridge.h +++ b/src/devices/ovs/nm-device-ovs-bridge.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -6,16 +6,20 @@ #ifndef __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__ #define __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__ -#define NM_TYPE_DEVICE_OVS_BRIDGE (nm_device_ovs_bridge_get_type ()) -#define NM_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridge)) -#define NM_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) -#define NM_IS_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_BRIDGE)) -#define NM_IS_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_BRIDGE)) -#define NM_DEVICE_OVS_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) +#define NM_TYPE_DEVICE_OVS_BRIDGE (nm_device_ovs_bridge_get_type()) +#define NM_DEVICE_OVS_BRIDGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridge)) +#define NM_DEVICE_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) +#define NM_IS_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_BRIDGE)) +#define NM_IS_DEVICE_OVS_BRIDGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_BRIDGE)) +#define NM_DEVICE_OVS_BRIDGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass)) -typedef struct _NMDeviceOvsBridge NMDeviceOvsBridge; +typedef struct _NMDeviceOvsBridge NMDeviceOvsBridge; typedef struct _NMDeviceOvsBridgeClass NMDeviceOvsBridgeClass; -GType nm_device_ovs_bridge_get_type (void); +GType nm_device_ovs_bridge_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__ */ diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c index 83954cf0..16b6e04d 100644 --- a/src/devices/ovs/nm-device-ovs-interface.c +++ b/src/devices/ovs/nm-device-ovs-interface.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -20,389 +20,379 @@ _LOG_DECLARE_SELF(NMDeviceOvsInterface); /*****************************************************************************/ typedef struct { - bool waiting_for_interface:1; + bool waiting_for_interface : 1; } NMDeviceOvsInterfacePrivate; struct _NMDeviceOvsInterface { - NMDevice parent; - NMDeviceOvsInterfacePrivate _priv; + NMDevice parent; + NMDeviceOvsInterfacePrivate _priv; }; struct _NMDeviceOvsInterfaceClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceOvsInterface, nm_device_ovs_interface, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceOvsInterface, nm_device_ovs_interface, NM_TYPE_DEVICE) -#define NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceOvsInterface, NM_IS_DEVICE_OVS_INTERFACE, NMDevice) +#define NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceOvsInterface, NM_IS_DEVICE_OVS_INTERFACE, NMDevice) /*****************************************************************************/ static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - return "ovs-interface"; + return "ovs-interface"; } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - /* The actual backing resources will be created once an interface is - * added to a port of ours, since there can be neither an empty port nor - * an empty bridge. */ + /* The actual backing resources will be created once an interface is + * added to a port of ours, since there can be neither an empty port nor + * an empty bridge. */ - return TRUE; + return TRUE; } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - return TRUE; + return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - NMSettingOvsInterface *s_ovs_iface; + NMSettingOvsInterface *s_ovs_iface; - if (!NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - s_ovs_iface = nm_connection_get_setting_ovs_interface (connection); + s_ovs_iface = nm_connection_get_setting_ovs_interface(connection); - if (!NM_IN_STRSET (nm_setting_ovs_interface_get_interface_type (s_ovs_iface), - "dpdk", - "internal", - "patch")) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "unsupported OVS interface type in profile"); - return FALSE; - } + if (!NM_IN_STRSET(nm_setting_ovs_interface_get_interface_type(s_ovs_iface), + "dpdk", + "internal", + "patch")) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "unsupported OVS interface type in profile"); + return FALSE; + } - return TRUE; + return TRUE; } static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) +link_changed(NMDevice *device, const NMPlatformLink *pllink) { - NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (device); - - if (!pllink || !priv->waiting_for_interface) - return; - - priv->waiting_for_interface = FALSE; - - if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { - if (!nm_device_hw_addr_set_cloned (device, - nm_device_get_applied_connection (device), - FALSE)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return; - } - nm_device_bring_up (device, TRUE, NULL); - nm_device_activate_schedule_stage3_ip_config_start (device); - } + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(device); + + if (!pllink || !priv->waiting_for_interface) + return; + + priv->waiting_for_interface = FALSE; + + if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) { + if (!nm_device_hw_addr_set_cloned(device, + nm_device_get_applied_connection(device), + FALSE)) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + nm_device_bring_up(device, TRUE, NULL); + nm_device_activate_schedule_stage3_ip_config_start(device); + } } static gboolean -_is_internal_interface (NMDevice *device) +_is_internal_interface(NMDevice *device) { - NMSettingOvsInterface *s_ovs_iface; + NMSettingOvsInterface *s_ovs_iface; - s_ovs_iface = nm_device_get_applied_setting (device, NM_TYPE_SETTING_OVS_INTERFACE); + s_ovs_iface = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OVS_INTERFACE); - g_return_val_if_fail (s_ovs_iface, FALSE); + g_return_val_if_fail(s_ovs_iface, FALSE); - return nm_streq (nm_setting_ovs_interface_get_interface_type (s_ovs_iface), "internal"); + return nm_streq(nm_setting_ovs_interface_get_interface_type(s_ovs_iface), "internal"); } static void -set_platform_mtu_cb (GError *error, gpointer user_data) +set_platform_mtu_cb(GError *error, gpointer user_data) { - NMDevice *device = user_data; - NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); + NMDevice * device = user_data; + NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device); - if ( error - && !g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { - _LOGW (LOGD_DEVICE, "could not change mtu of '%s': %s", - nm_device_get_iface (device), error->message); - } + if (error && !g_error_matches(error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { + _LOGW(LOGD_DEVICE, + "could not change mtu of '%s': %s", + nm_device_get_iface(device), + error->message); + } - g_object_unref (device); + g_object_unref(device); } static gboolean -set_platform_mtu (NMDevice *device, guint32 mtu) +set_platform_mtu(NMDevice *device, guint32 mtu) { - /* - * If the MTU is not set in ovsdb, Open vSwitch will change - * the MTU of an internal interface to match the minimum of - * the other interfaces in the bridge. - */ - /* FIXME(shutdown): the function should become cancellable so - * that it doesn't need to hold a reference to the device, and - * it can be stopped during shutdown. - */ - if (_is_internal_interface (device)) { - nm_ovsdb_set_interface_mtu (nm_ovsdb_get (), - nm_device_get_ip_iface (device), - mtu, set_platform_mtu_cb, - g_object_ref (device)); - } - - return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->set_platform_mtu (device, mtu); + /* + * If the MTU is not set in ovsdb, Open vSwitch will change + * the MTU of an internal interface to match the minimum of + * the other interfaces in the bridge. + */ + /* FIXME(shutdown): the function should become cancellable so + * that it doesn't need to hold a reference to the device, and + * it can be stopped during shutdown. + */ + if (_is_internal_interface(device)) { + nm_ovsdb_set_interface_mtu(nm_ovsdb_get(), + nm_device_get_ip_iface(device), + mtu, + set_platform_mtu_cb, + g_object_ref(device)); + } + + return NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class)->set_platform_mtu(device, mtu); } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); - NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (device); - - if (!_is_internal_interface (device)) - return NM_ACT_STAGE_RETURN_IP_FAIL; - - if (nm_device_get_ip_ifindex (device) <= 0) { - _LOGT (LOGD_DEVICE, "waiting for link to appear"); - priv->waiting_for_interface = TRUE; - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (!nm_device_hw_addr_set_cloned (device, - nm_device_get_applied_connection (device), - FALSE)) { - *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device); + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(device); + + if (!_is_internal_interface(device)) + return NM_ACT_STAGE_RETURN_IP_FAIL; + + if (nm_device_get_ip_ifindex(device) <= 0) { + _LOGT(LOGD_DEVICE, "waiting for link to appear"); + priv->waiting_for_interface = TRUE; + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (!nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE)) { + *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static gboolean -can_unmanaged_external_down (NMDevice *self) +can_unmanaged_external_down(NMDevice *self) { - return FALSE; + return FALSE; } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); - NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (self); + NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device); + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self); - priv->waiting_for_interface = FALSE; + priv->waiting_for_interface = FALSE; } typedef struct { - NMDeviceOvsInterface *self; - GCancellable *cancellable; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; - gulong link_changed_id; - gulong cancelled_id; - guint link_timeout_id; + NMDeviceOvsInterface * self; + GCancellable * cancellable; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gulong link_changed_id; + gulong cancelled_id; + guint link_timeout_id; } DeactivateData; static void -deactivate_invoke_cb (DeactivateData *data, GError *error) +deactivate_invoke_cb(DeactivateData *data, GError *error) { - NMDeviceOvsInterface *self = data->self; - - _LOGT (LOGD_CORE, - "deactivate: async callback (%s)", - error ? error->message : "success"); - data->callback (NM_DEVICE (data->self), - error, - data->callback_user_data); - - nm_clear_g_signal_handler (nm_device_get_platform (NM_DEVICE (data->self)), - &data->link_changed_id); - nm_clear_g_signal_handler (data->cancellable, - &data->cancelled_id); - nm_clear_g_source (&data->link_timeout_id); - g_object_unref (data->self); - g_object_unref (data->cancellable); - nm_g_slice_free (data); + NMDeviceOvsInterface *self = data->self; + + _LOGT(LOGD_CORE, "deactivate: async callback (%s)", error ? error->message : "success"); + data->callback(NM_DEVICE(data->self), error, data->callback_user_data); + + nm_clear_g_signal_handler(nm_device_get_platform(NM_DEVICE(data->self)), + &data->link_changed_id); + nm_clear_g_signal_handler(data->cancellable, &data->cancelled_id); + nm_clear_g_source(&data->link_timeout_id); + g_object_unref(data->self); + g_object_unref(data->cancellable); + nm_g_slice_free(data); } static void -deactivate_link_changed_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *info, - int change_type_i, - DeactivateData *data) +deactivate_link_changed_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *info, + int change_type_i, + DeactivateData *data) { - NMDeviceOvsInterface *self = data->self; - const NMPlatformSignalChangeType change_type = change_type_i; - - if ( change_type == NM_PLATFORM_SIGNAL_REMOVED - && nm_streq0 (info->name, nm_device_get_iface (NM_DEVICE (self)))) { - _LOGT (LOGD_DEVICE, "deactivate: link removed, proceeding"); - nm_device_update_from_platform_link (NM_DEVICE (self), NULL); - deactivate_invoke_cb (data, NULL); - return; - } + NMDeviceOvsInterface * self = data->self; + const NMPlatformSignalChangeType change_type = change_type_i; + + if (change_type == NM_PLATFORM_SIGNAL_REMOVED + && nm_streq0(info->name, nm_device_get_iface(NM_DEVICE(self)))) { + _LOGT(LOGD_DEVICE, "deactivate: link removed, proceeding"); + nm_device_update_from_platform_link(NM_DEVICE(self), NULL); + deactivate_invoke_cb(data, NULL); + return; + } } static gboolean -deactivate_link_timeout (gpointer user_data) +deactivate_link_timeout(gpointer user_data) { - DeactivateData *data = user_data; - NMDeviceOvsInterface *self = data->self; + DeactivateData * data = user_data; + NMDeviceOvsInterface *self = data->self; - _LOGT (LOGD_DEVICE, "deactivate: timeout waiting link removal"); - deactivate_invoke_cb (data, NULL); - return G_SOURCE_REMOVE; + _LOGT(LOGD_DEVICE, "deactivate: timeout waiting link removal"); + deactivate_invoke_cb(data, NULL); + return G_SOURCE_REMOVE; } static void -deactivate_cancelled_cb (GCancellable *cancellable, - gpointer user_data) +deactivate_cancelled_cb(GCancellable *cancellable, gpointer user_data) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - nm_utils_error_set_cancelled (&error, FALSE, NULL); - deactivate_invoke_cb ((DeactivateData *) user_data, error); + nm_utils_error_set_cancelled(&error, FALSE, NULL); + deactivate_invoke_cb((DeactivateData *) user_data, error); } static void -deactivate_cb_on_idle (gpointer user_data, - GCancellable *cancellable) +deactivate_cb_on_idle(gpointer user_data, GCancellable *cancellable) { - DeactivateData *data = user_data; - gs_free_error GError *cancelled_error = NULL; + DeactivateData *data = user_data; + gs_free_error GError *cancelled_error = NULL; - g_cancellable_set_error_if_cancelled (data->cancellable, &cancelled_error); - deactivate_invoke_cb (data, cancelled_error); + g_cancellable_set_error_if_cancelled(data->cancellable, &cancelled_error); + deactivate_invoke_cb(data, cancelled_error); } static void -deactivate_async (NMDevice *device, - GCancellable *cancellable, - NMDeviceDeactivateCallback callback, - gpointer callback_user_data) { - - NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device); - NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (self); - DeactivateData *data; - - _LOGT (LOGD_CORE, "deactivate: start async"); - - /* We want to ensure that the kernel link for this device is - * removed upon disconnection so that it will not interfere with - * later activations of the same device. Unfortunately there is - * no synchronization mechanism with vswitchd, we only update - * ovsdb and wait that changes are picked up. - */ - - data = g_slice_new (DeactivateData); - *data = (DeactivateData) { - .self = g_object_ref (self), - .cancellable = g_object_ref (cancellable), - .callback = callback, - .callback_user_data = callback_user_data, - }; - - if ( !priv->waiting_for_interface - && !nm_platform_link_get_by_ifname (nm_device_get_platform (device), - nm_device_get_iface (device))) { - _LOGT (LOGD_CORE, "deactivate: link not present, proceeding"); - nm_device_update_from_platform_link (NM_DEVICE (self), NULL); - nm_utils_invoke_on_idle (cancellable, deactivate_cb_on_idle, data); - return; - } - - if (priv->waiting_for_interface) { - /* At this point we have issued an INSERT and a DELETE - * command for the interface to ovsdb. We don't know if - * vswitchd will see the two updates or only one. We - * must add a timeout to avoid waiting forever in case - * the link doesn't appear. - */ - data->link_timeout_id = g_timeout_add (6000, deactivate_link_timeout, data); - _LOGT (LOGD_DEVICE, "deactivate: waiting for link to disappear in 6 seconds"); - } else - _LOGT (LOGD_DEVICE, "deactivate: waiting for link to disappear"); - - data->cancelled_id = g_cancellable_connect (cancellable, - G_CALLBACK (deactivate_cancelled_cb), - data, - NULL); - data->link_changed_id = g_signal_connect (nm_device_get_platform (device), - NM_PLATFORM_SIGNAL_LINK_CHANGED, - G_CALLBACK (deactivate_link_changed_cb), - data); +deactivate_async(NMDevice * device, + GCancellable * cancellable, + NMDeviceDeactivateCallback callback, + gpointer callback_user_data) +{ + NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device); + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self); + DeactivateData * data; + + _LOGT(LOGD_CORE, "deactivate: start async"); + + /* We want to ensure that the kernel link for this device is + * removed upon disconnection so that it will not interfere with + * later activations of the same device. Unfortunately there is + * no synchronization mechanism with vswitchd, we only update + * ovsdb and wait that changes are picked up. + */ + + data = g_slice_new(DeactivateData); + *data = (DeactivateData){ + .self = g_object_ref(self), + .cancellable = g_object_ref(cancellable), + .callback = callback, + .callback_user_data = callback_user_data, + }; + + if (!priv->waiting_for_interface + && !nm_platform_link_get_by_ifname(nm_device_get_platform(device), + nm_device_get_iface(device))) { + _LOGT(LOGD_CORE, "deactivate: link not present, proceeding"); + nm_device_update_from_platform_link(NM_DEVICE(self), NULL); + nm_utils_invoke_on_idle(cancellable, deactivate_cb_on_idle, data); + return; + } + + if (priv->waiting_for_interface) { + /* At this point we have issued an INSERT and a DELETE + * command for the interface to ovsdb. We don't know if + * vswitchd will see the two updates or only one. We + * must add a timeout to avoid waiting forever in case + * the link doesn't appear. + */ + data->link_timeout_id = g_timeout_add(6000, deactivate_link_timeout, data); + _LOGT(LOGD_DEVICE, "deactivate: waiting for link to disappear in 6 seconds"); + } else + _LOGT(LOGD_DEVICE, "deactivate: waiting for link to disappear"); + + data->cancelled_id = + g_cancellable_connect(cancellable, G_CALLBACK(deactivate_cancelled_cb), data, NULL); + data->link_changed_id = g_signal_connect(nm_device_get_platform(device), + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(deactivate_link_changed_cb), + data); } static gboolean -can_update_from_platform_link (NMDevice *device, const NMPlatformLink *plink) +can_update_from_platform_link(NMDevice *device, const NMPlatformLink *plink) { - /* If the device is deactivating, we already sent the - * deletion command to ovsdb and we don't want to deal - * with any new link appearing from the previous - * activation. - */ - return !plink - || nm_device_get_state (device) != NM_DEVICE_STATE_DEACTIVATING; + /* If the device is deactivating, we already sent the + * deletion command to ovsdb and we don't want to deal + * with any new link appearing from the previous + * activation. + */ + return !plink || nm_device_get_state(device) != NM_DEVICE_STATE_DEACTIVATING; } /*****************************************************************************/ static void -nm_device_ovs_interface_init (NMDeviceOvsInterface *self) -{ -} +nm_device_ovs_interface_init(NMDeviceOvsInterface *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) +nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_interface); - - device_class->connection_type_supported = NM_SETTING_OVS_INTERFACE_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH); - - device_class->can_update_from_platform_link = can_update_from_platform_link; - device_class->deactivate = deactivate; - device_class->deactivate_async = deactivate_async; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->is_available = is_available; - device_class->check_connection_compatible = check_connection_compatible; - device_class->link_changed = link_changed; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->can_unmanaged_external_down = can_unmanaged_external_down; - device_class->set_platform_mtu = set_platform_mtu; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + dbus_object_class->interface_infos = + NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_interface); + + device_class->connection_type_supported = NM_SETTING_OVS_INTERFACE_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_OPENVSWITCH); + + device_class->can_update_from_platform_link = can_update_from_platform_link; + device_class->deactivate = deactivate; + device_class->deactivate_async = deactivate_async; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->is_available = is_available; + device_class->check_connection_compatible = check_connection_compatible; + device_class->link_changed = link_changed; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->can_unmanaged_external_down = can_unmanaged_external_down; + device_class->set_platform_mtu = set_platform_mtu; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; } diff --git a/src/devices/ovs/nm-device-ovs-interface.h b/src/devices/ovs/nm-device-ovs-interface.h index e31dac8b..902847de 100644 --- a/src/devices/ovs/nm-device-ovs-interface.h +++ b/src/devices/ovs/nm-device-ovs-interface.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -6,16 +6,21 @@ #ifndef __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__ #define __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__ -#define NM_TYPE_DEVICE_OVS_INTERFACE (nm_device_ovs_interface_get_type ()) -#define NM_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterface)) -#define NM_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) -#define NM_IS_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_INTERFACE)) -#define NM_IS_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_INTERFACE)) -#define NM_DEVICE_OVS_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) +#define NM_TYPE_DEVICE_OVS_INTERFACE (nm_device_ovs_interface_get_type()) +#define NM_DEVICE_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterface)) +#define NM_DEVICE_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) +#define NM_IS_DEVICE_OVS_INTERFACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_INTERFACE)) +#define NM_IS_DEVICE_OVS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_INTERFACE)) +#define NM_DEVICE_OVS_INTERFACE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass)) -typedef struct _NMDeviceOvsInterface NMDeviceOvsInterface; +typedef struct _NMDeviceOvsInterface NMDeviceOvsInterface; typedef struct _NMDeviceOvsInterfaceClass NMDeviceOvsInterfaceClass; -GType nm_device_ovs_interface_get_type (void); +GType nm_device_ovs_interface_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__ */ diff --git a/src/devices/ovs/nm-device-ovs-port.c b/src/devices/ovs/nm-device-ovs-port.c index e0216377..de98e29e 100644 --- a/src/devices/ovs/nm-device-ovs-port.c +++ b/src/devices/ovs/nm-device-ovs-port.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -16,181 +16,177 @@ #include "nm-setting-ovs-port.h" #include "devices/nm-device-logging.h" -_LOG_DECLARE_SELF (NMDeviceOvsPort); +_LOG_DECLARE_SELF(NMDeviceOvsPort); /*****************************************************************************/ struct _NMDeviceOvsPort { - NMDevice parent; + NMDevice parent; }; struct _NMDeviceOvsPortClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceOvsPort, nm_device_ovs_port, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceOvsPort, nm_device_ovs_port, NM_TYPE_DEVICE) /*****************************************************************************/ static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - return "ovs-port"; + return "ovs-port"; } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - /* The port will be added to ovsdb when an interface is enslaved, - * because there's no such thing like an empty port. */ + /* The port will be added to ovsdb when an interface is enslaved, + * because there's no such thing like an empty port. */ - return TRUE; + return TRUE; } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_IS_SOFTWARE; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - return NM_ACT_STAGE_RETURN_IP_FAIL; + return NM_ACT_STAGE_RETURN_IP_FAIL; } static void -add_iface_cb (GError *error, gpointer user_data) +add_iface_cb(GError *error, gpointer user_data) { - NMDevice *slave = user_data; - - if ( error - && !g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { - nm_log_warn (LOGD_DEVICE, "device %s could not be added to a ovs port: %s", - nm_device_get_iface (slave), error->message); - nm_device_state_changed (slave, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_OVSDB_FAILED); - } - - g_object_unref (slave); + NMDevice *slave = user_data; + + if (error && !g_error_matches(error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { + nm_log_warn(LOGD_DEVICE, + "device %s could not be added to a ovs port: %s", + nm_device_get_iface(slave), + error->message); + nm_device_state_changed(slave, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_OVSDB_FAILED); + } + + g_object_unref(slave); } static gboolean -enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT (device); - NMActiveConnection *ac_port = NULL; - NMActiveConnection *ac_bridge = NULL; - NMDevice *bridge_device; - - if (!configure) - return TRUE; - - ac_port = NM_ACTIVE_CONNECTION (nm_device_get_act_request (device)); - ac_bridge = nm_active_connection_get_master (ac_port); - if (!ac_bridge) { - _LOGW (LOGD_DEVICE, "can't enslave %s: bridge active-connection not found", - nm_device_get_iface (slave)); - return FALSE; - } - - bridge_device = nm_active_connection_get_device (ac_bridge); - if (!bridge_device) { - _LOGW (LOGD_DEVICE, "can't enslave %s: bridge device not found", - nm_device_get_iface (slave)); - return FALSE; - } - - nm_ovsdb_add_interface (nm_ovsdb_get (), - nm_active_connection_get_applied_connection (ac_bridge), - nm_device_get_applied_connection (device), - nm_device_get_applied_connection (slave), - bridge_device, - slave, - add_iface_cb, g_object_ref (slave)); - - return TRUE; + NMDeviceOvsPort * self = NM_DEVICE_OVS_PORT(device); + NMActiveConnection *ac_port = NULL; + NMActiveConnection *ac_bridge = NULL; + NMDevice * bridge_device; + + if (!configure) + return TRUE; + + ac_port = NM_ACTIVE_CONNECTION(nm_device_get_act_request(device)); + ac_bridge = nm_active_connection_get_master(ac_port); + if (!ac_bridge) { + _LOGW(LOGD_DEVICE, + "can't enslave %s: bridge active-connection not found", + nm_device_get_iface(slave)); + return FALSE; + } + + bridge_device = nm_active_connection_get_device(ac_bridge); + if (!bridge_device) { + _LOGW(LOGD_DEVICE, "can't enslave %s: bridge device not found", nm_device_get_iface(slave)); + return FALSE; + } + + nm_ovsdb_add_interface(nm_ovsdb_get(), + nm_active_connection_get_applied_connection(ac_bridge), + nm_device_get_applied_connection(device), + nm_device_get_applied_connection(slave), + bridge_device, + slave, + add_iface_cb, + g_object_ref(slave)); + + return TRUE; } static void -del_iface_cb (GError *error, gpointer user_data) +del_iface_cb(GError *error, gpointer user_data) { - NMDevice *slave = user_data; - - if ( error - && !g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { - nm_log_warn (LOGD_DEVICE, "device %s could not be removed from a ovs port: %s", - nm_device_get_iface (slave), error->message); - nm_device_state_changed (slave, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_OVSDB_FAILED); - } - - g_object_unref (slave); + NMDevice *slave = user_data; + + if (error && !g_error_matches(error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) { + nm_log_warn(LOGD_DEVICE, + "device %s could not be removed from a ovs port: %s", + nm_device_get_iface(slave), + error->message); + nm_device_state_changed(slave, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_OVSDB_FAILED); + } + + g_object_unref(slave); } static void -release_slave (NMDevice *device, NMDevice *slave, gboolean configure) +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT (device); - - if (configure) { - _LOGI (LOGD_DEVICE, "releasing ovs interface %s", nm_device_get_ip_iface (slave)); - nm_ovsdb_del_interface (nm_ovsdb_get (), nm_device_get_iface (slave), - del_iface_cb, g_object_ref (slave)); - /* Open VSwitch is going to delete this one. We must ignore what happens - * next with the interface. */ - if (NM_IS_DEVICE_OVS_INTERFACE (slave)) - nm_device_update_from_platform_link (slave, NULL); - } else - _LOGI (LOGD_DEVICE, "ovs interface %s was released", nm_device_get_ip_iface (slave)); + NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device); + + if (configure) { + _LOGI(LOGD_DEVICE, "releasing ovs interface %s", nm_device_get_ip_iface(slave)); + nm_ovsdb_del_interface(nm_ovsdb_get(), + nm_device_get_iface(slave), + del_iface_cb, + g_object_ref(slave)); + /* Open VSwitch is going to delete this one. We must ignore what happens + * next with the interface. */ + if (NM_IS_DEVICE_OVS_INTERFACE(slave)) + nm_device_update_from_platform_link(slave, NULL); + } else + _LOGI(LOGD_DEVICE, "ovs interface %s was released", nm_device_get_ip_iface(slave)); } /*****************************************************************************/ static void -nm_device_ovs_port_init (NMDeviceOvsPort *self) -{ -} +nm_device_ovs_port_init(NMDeviceOvsPort *self) +{} static const NMDBusInterfaceInfoExtended interface_info_device_ovs_port = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_OVS_PORT, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Slaves", "ao", NM_DEVICE_SLAVES), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_OVS_PORT, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass) +nm_device_ovs_port_class_init(NMDeviceOvsPortClass *klass) { - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_port); - - device_class->connection_type_supported = NM_SETTING_OVS_PORT_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OVS_PORT_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (); - - device_class->is_master = TRUE; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_ovs_port); + + device_class->connection_type_supported = NM_SETTING_OVS_PORT_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_OVS_PORT_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); + + device_class->is_master = TRUE; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; } diff --git a/src/devices/ovs/nm-device-ovs-port.h b/src/devices/ovs/nm-device-ovs-port.h index 7edbf02f..3f5d7793 100644 --- a/src/devices/ovs/nm-device-ovs-port.h +++ b/src/devices/ovs/nm-device-ovs-port.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -6,16 +6,20 @@ #ifndef __NETWORKMANAGER_DEVICE_OVS_PORT_H__ #define __NETWORKMANAGER_DEVICE_OVS_PORT_H__ -#define NM_TYPE_DEVICE_OVS_PORT (nm_device_ovs_port_get_type ()) -#define NM_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPort)) -#define NM_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) -#define NM_IS_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_PORT)) -#define NM_IS_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_PORT)) -#define NM_DEVICE_OVS_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) +#define NM_TYPE_DEVICE_OVS_PORT (nm_device_ovs_port_get_type()) +#define NM_DEVICE_OVS_PORT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPort)) +#define NM_DEVICE_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) +#define NM_IS_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OVS_PORT)) +#define NM_IS_DEVICE_OVS_PORT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OVS_PORT)) +#define NM_DEVICE_OVS_PORT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass)) -typedef struct _NMDeviceOvsPort NMDeviceOvsPort; +typedef struct _NMDeviceOvsPort NMDeviceOvsPort; typedef struct _NMDeviceOvsPortClass NMDeviceOvsPortClass; -GType nm_device_ovs_port_get_type (void); +GType nm_device_ovs_port_get_type(void); #endif /* __NETWORKMANAGER_DEVICE_OVS_PORT_H__ */ diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c index d7bd0a09..e1feacbd 100644 --- a/src/devices/ovs/nm-ovs-factory.c +++ b/src/devices/ovs/nm-ovs-factory.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -19,228 +19,251 @@ /*****************************************************************************/ typedef struct { - NMDeviceFactory parent; + NMDeviceFactory parent; } NMOvsFactory; typedef struct { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; } NMOvsFactoryClass; -#define NM_TYPE_OVS_FACTORY (nm_ovs_factory_get_type ()) -#define NM_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_OVS_FACTORY, NMOvsFactory)) -#define NM_OVS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass)) -#define NM_IS_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_OVS_FACTORY)) -#define NM_IS_OVS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_OVS_FACTORY)) -#define NM_OVS_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass)) +#define NM_TYPE_OVS_FACTORY (nm_ovs_factory_get_type()) +#define NM_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_OVS_FACTORY, NMOvsFactory)) +#define NM_OVS_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass)) +#define NM_IS_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_OVS_FACTORY)) +#define NM_IS_OVS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_OVS_FACTORY)) +#define NM_OVS_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass)) -static GType nm_ovs_factory_get_type (void); -G_DEFINE_TYPE (NMOvsFactory, nm_ovs_factory, NM_TYPE_DEVICE_FACTORY) +static GType nm_ovs_factory_get_type(void); +G_DEFINE_TYPE(NMOvsFactory, nm_ovs_factory, NM_TYPE_DEVICE_FACTORY) /*****************************************************************************/ -#define _NMLOG_DOMAIN LOGD_DEVICE -#define _NMLOG(level, ifname, con_uuid, ...) \ - G_STMT_START { \ - nm_log ((level), _NMLOG_DOMAIN, (ifname), (con_uuid), \ - "ovs: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END - +#define _NMLOG_DOMAIN LOGD_DEVICE +#define _NMLOG(level, ifname, con_uuid, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + (ifname), \ + (con_uuid), \ + "ovs: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_OVS_BRIDGE_SETTING_NAME, - NM_SETTING_OVS_INTERFACE_SETTING_NAME, - NM_SETTING_OVS_PORT_SETTING_NAME) -) +NM_DEVICE_FACTORY_DECLARE_TYPES( + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_OPENVSWITCH) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_OVS_BRIDGE_SETTING_NAME, + NM_SETTING_OVS_INTERFACE_SETTING_NAME, + NM_SETTING_OVS_PORT_SETTING_NAME)) G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - nm_manager_set_capability (NM_MANAGER_GET, NM_CAPABILITY_OVS); - return (NMDeviceFactory *) g_object_new (NM_TYPE_OVS_FACTORY, NULL); + nm_manager_set_capability(NM_MANAGER_GET, NM_CAPABILITY_OVS); + return (NMDeviceFactory *) g_object_new(NM_TYPE_OVS_FACTORY, NULL); } static NMDevice * -new_device_from_type (const char *name, NMDeviceType device_type) +new_device_from_type(const char *name, NMDeviceType device_type) { - GType type; - const char *type_desc; - NMLinkType link_type = NM_LINK_TYPE_NONE; - - if (nm_manager_get_device (NM_MANAGER_GET, name, device_type)) - return NULL; - - if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) { - type = NM_TYPE_DEVICE_OVS_INTERFACE; - type_desc = "Open vSwitch Interface"; - link_type = NM_LINK_TYPE_OPENVSWITCH; - } else if (device_type == NM_DEVICE_TYPE_OVS_PORT) { - type = NM_TYPE_DEVICE_OVS_PORT; - type_desc = "Open vSwitch Port"; - } else if (device_type == NM_DEVICE_TYPE_OVS_BRIDGE) { - type = NM_TYPE_DEVICE_OVS_BRIDGE; - type_desc = "Open vSwitch Bridge"; - } else { - return NULL; - } - - return g_object_new (type, - NM_DEVICE_IFACE, name, - NM_DEVICE_DRIVER, "openvswitch", - NM_DEVICE_DEVICE_TYPE, device_type, - NM_DEVICE_TYPE_DESC, type_desc, - NM_DEVICE_LINK_TYPE, link_type, - NULL); + GType type; + const char *type_desc; + NMLinkType link_type = NM_LINK_TYPE_NONE; + + if (nm_manager_get_device(NM_MANAGER_GET, name, device_type)) + return NULL; + + if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) { + type = NM_TYPE_DEVICE_OVS_INTERFACE; + type_desc = "Open vSwitch Interface"; + link_type = NM_LINK_TYPE_OPENVSWITCH; + } else if (device_type == NM_DEVICE_TYPE_OVS_PORT) { + type = NM_TYPE_DEVICE_OVS_PORT; + type_desc = "Open vSwitch Port"; + } else if (device_type == NM_DEVICE_TYPE_OVS_BRIDGE) { + type = NM_TYPE_DEVICE_OVS_BRIDGE; + type_desc = "Open vSwitch Bridge"; + } else { + return NULL; + } + + return g_object_new(type, + NM_DEVICE_IFACE, + name, + NM_DEVICE_DRIVER, + "openvswitch", + NM_DEVICE_DEVICE_TYPE, + device_type, + NM_DEVICE_TYPE_DESC, + type_desc, + NM_DEVICE_LINK_TYPE, + link_type, + NULL); } static void -ovsdb_device_added (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type, - NMDeviceFactory *self) +ovsdb_device_added(NMOvsdb * ovsdb, + const char * name, + NMDeviceType device_type, + NMDeviceFactory *self) { - NMDevice *device = NULL; + NMDevice *device = NULL; - device = new_device_from_type (name, device_type); - if (!device) - return; + device = new_device_from_type(name, device_type); + if (!device) + return; - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); - g_object_unref (device); + g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + g_object_unref(device); } static void -ovsdb_device_removed (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type, - NMDeviceFactory *self) +ovsdb_device_removed(NMOvsdb * ovsdb, + const char * name, + NMDeviceType device_type, + NMDeviceFactory *self) { - NMDevice *device; - NMDeviceState device_state; - - device = nm_manager_get_device (NM_MANAGER_GET, name, device_type); - if (!device) - return; - - device_state = nm_device_get_state (device); - if ( device_type == NM_DEVICE_TYPE_OVS_INTERFACE - && device_state > NM_DEVICE_STATE_DISCONNECTED - && device_state < NM_DEVICE_STATE_DEACTIVATING) { - nm_device_state_changed (device, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); - } else if (device_state == NM_DEVICE_STATE_UNMANAGED) { - nm_device_unrealize (device, TRUE, NULL); - } + NMDevice * device; + NMDeviceState device_state; + + device = nm_manager_get_device(NM_MANAGER_GET, name, device_type); + if (!device) + return; + + device_state = nm_device_get_state(device); + if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE && device_state > NM_DEVICE_STATE_DISCONNECTED + && device_state < NM_DEVICE_STATE_DEACTIVATING) { + nm_device_state_changed(device, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); + } else if (device_state == NM_DEVICE_STATE_UNMANAGED) { + nm_device_unrealize(device, TRUE, NULL); + } } static void -ovsdb_interface_failed (NMOvsdb *ovsdb, - const char *name, - const char *connection_uuid, - const char *error, - NMDeviceFactory *self) +ovsdb_interface_failed(NMOvsdb * ovsdb, + const char * name, + const char * connection_uuid, + const char * error, + NMDeviceFactory *self) { - NMDevice *device = NULL; - NMSettingsConnection *connection = NULL; - NMConnection *c; - const char *type; - NMSettingOvsInterface *s_ovs_int; - gboolean is_patch = FALSE; - gboolean ignore; - - device = nm_manager_get_device (NM_MANAGER_GET, name, NM_DEVICE_TYPE_OVS_INTERFACE); - if (device && connection_uuid) { - connection = nm_settings_get_connection_by_uuid (nm_device_get_settings (device), - connection_uuid); - } - - /* The patch interface which gets created first is expected to - * fail because the second patch doesn't exist yet. Ignore all - * failures of patch interfaces. */ - if ( connection - && (c = nm_settings_connection_get_connection (connection)) - && (type = nm_connection_get_connection_type (c)) - && nm_streq0 (type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) - && (s_ovs_int = nm_connection_get_setting_ovs_interface (c)) - && nm_streq0 (nm_setting_ovs_interface_get_interface_type (s_ovs_int), "patch")) - is_patch = TRUE; - - ignore = !device || is_patch; - - _NMLOG (ignore ? LOGL_DEBUG : LOGL_INFO, - name, connection_uuid, - "ovs interface \"%s\" (%s) failed%s: %s", - name, connection_uuid, - ignore ? " (ignored)" : "", - error); - - if (ignore) - return; - - if (connection) { - nm_settings_connection_autoconnect_blocked_reason_set (connection, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, - TRUE); - } - - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_OVSDB_FAILED); + NMDevice * device = NULL; + NMSettingsConnection * connection = NULL; + NMConnection * c; + const char * type; + NMSettingOvsInterface *s_ovs_int; + gboolean is_patch = FALSE; + gboolean ignore; + + device = nm_manager_get_device(NM_MANAGER_GET, name, NM_DEVICE_TYPE_OVS_INTERFACE); + if (device && connection_uuid) { + connection = + nm_settings_get_connection_by_uuid(nm_device_get_settings(device), connection_uuid); + } + + /* The patch interface which gets created first is expected to + * fail because the second patch doesn't exist yet. Ignore all + * failures of patch interfaces. */ + if (connection && (c = nm_settings_connection_get_connection(connection)) + && (type = nm_connection_get_connection_type(c)) + && nm_streq0(type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) + && (s_ovs_int = nm_connection_get_setting_ovs_interface(c)) + && nm_streq0(nm_setting_ovs_interface_get_interface_type(s_ovs_int), "patch")) + is_patch = TRUE; + + ignore = !device || is_patch; + + _NMLOG(ignore ? LOGL_DEBUG : LOGL_INFO, + name, + connection_uuid, + "ovs interface \"%s\" (%s) failed%s: %s", + name, + connection_uuid, + ignore ? " (ignored)" : "", + error); + + if (ignore) + return; + + if (connection) { + nm_settings_connection_autoconnect_blocked_reason_set( + connection, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + } + + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_OVSDB_FAILED); } static void -start (NMDeviceFactory *self) +start(NMDeviceFactory *self) { - NMOvsdb *ovsdb; - - ovsdb = nm_ovsdb_get (); - - g_signal_connect_object (ovsdb, NM_OVSDB_DEVICE_ADDED, G_CALLBACK (ovsdb_device_added), self, (GConnectFlags) 0); - g_signal_connect_object (ovsdb, NM_OVSDB_DEVICE_REMOVED, G_CALLBACK (ovsdb_device_removed), self, (GConnectFlags) 0); - g_signal_connect_object (ovsdb, NM_OVSDB_INTERFACE_FAILED, G_CALLBACK (ovsdb_interface_failed), self, (GConnectFlags) 0); + NMOvsdb *ovsdb; + + ovsdb = nm_ovsdb_get(); + + g_signal_connect_object(ovsdb, + NM_OVSDB_DEVICE_ADDED, + G_CALLBACK(ovsdb_device_added), + self, + (GConnectFlags) 0); + g_signal_connect_object(ovsdb, + NM_OVSDB_DEVICE_REMOVED, + G_CALLBACK(ovsdb_device_removed), + self, + (GConnectFlags) 0); + g_signal_connect_object(ovsdb, + NM_OVSDB_INTERFACE_FAILED, + G_CALLBACK(ovsdb_interface_failed), + self, + (GConnectFlags) 0); } static NMDevice * -create_device (NMDeviceFactory *self, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * self, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - NMDeviceType device_type = NM_DEVICE_TYPE_UNKNOWN; - const char *connection_type = NULL; - - if (g_strcmp0 (iface, "ovs-system") == 0) { - *out_ignore = TRUE; - return NULL; - } - - if (connection) - connection_type = nm_connection_get_connection_type (connection); - - if (plink) - device_type = NM_DEVICE_TYPE_OVS_INTERFACE; - else if (g_strcmp0 (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) - device_type = NM_DEVICE_TYPE_OVS_INTERFACE; - else if (g_strcmp0 (connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0) - device_type = NM_DEVICE_TYPE_OVS_PORT; - else if (g_strcmp0 (connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME) == 0) - device_type = NM_DEVICE_TYPE_OVS_BRIDGE; - - return new_device_from_type (iface, device_type); + NMDeviceType device_type = NM_DEVICE_TYPE_UNKNOWN; + const char * connection_type = NULL; + + if (g_strcmp0(iface, "ovs-system") == 0) { + *out_ignore = TRUE; + return NULL; + } + + if (connection) + connection_type = nm_connection_get_connection_type(connection); + + if (plink) + device_type = NM_DEVICE_TYPE_OVS_INTERFACE; + else if (g_strcmp0(connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) + device_type = NM_DEVICE_TYPE_OVS_INTERFACE; + else if (g_strcmp0(connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0) + device_type = NM_DEVICE_TYPE_OVS_PORT; + else if (g_strcmp0(connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME) == 0) + device_type = NM_DEVICE_TYPE_OVS_BRIDGE; + + return new_device_from_type(iface, device_type); } static void -nm_ovs_factory_init (NMOvsFactory *self) -{ -} +nm_ovs_factory_init(NMOvsFactory *self) +{} static void -nm_ovs_factory_class_init (NMOvsFactoryClass *klass) +nm_ovs_factory_class_init(NMOvsFactoryClass *klass) { - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - factory_class->get_supported_types = get_supported_types; - factory_class->start = start; - factory_class->create_device = create_device; + factory_class->get_supported_types = get_supported_types; + factory_class->start = start; + factory_class->create_device = create_device; } diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c index 0b3fa3fd..9826c1b7 100644 --- a/src/devices/ovs/nm-ovsdb.c +++ b/src/devices/ovs/nm-ovsdb.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -18,163 +18,161 @@ /*****************************************************************************/ #if JANSSON_VERSION_HEX < 0x020400 -#warning "requires at least libjansson 2.4" + #warning "requires at least libjansson 2.4" #endif typedef struct { - char *name; - char *connection_uuid; - GPtrArray *interfaces; /* interface uuids */ + char * name; + char * connection_uuid; + GPtrArray *interfaces; /* interface uuids */ } OpenvswitchPort; typedef struct { - char *name; - char *connection_uuid; - GPtrArray *ports; /* port uuids */ + char * name; + char * connection_uuid; + GPtrArray *ports; /* port uuids */ } OpenvswitchBridge; typedef struct { - char *name; - char *type; - char *connection_uuid; + char *name; + char *type; + char *connection_uuid; } OpenvswitchInterface; /*****************************************************************************/ -enum { - DEVICE_ADDED, - DEVICE_REMOVED, - INTERFACE_FAILED, - LAST_SIGNAL -}; +enum { DEVICE_ADDED, DEVICE_REMOVED, INTERFACE_FAILED, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - GSocketClient *client; - GSocketConnection *conn; - GCancellable *cancellable; - char buf[4096]; /* Input buffer */ - size_t bufp; /* Last decoded byte in the input buffer. */ - GString *input; /* JSON stream waiting for decoding. */ - GString *output; /* JSON stream to be sent. */ - gint64 seq; - GArray *calls; /* Method calls waiting for a response. */ - GHashTable *interfaces; /* interface uuid => OpenvswitchInterface */ - GHashTable *ports; /* port uuid => OpenvswitchPort */ - GHashTable *bridges; /* bridge uuid => OpenvswitchBridge */ - char *db_uuid; - guint num_failures; + GSocketClient * client; + GSocketConnection *conn; + GCancellable * cancellable; + char buf[4096]; /* Input buffer */ + size_t bufp; /* Last decoded byte in the input buffer. */ + GString * input; /* JSON stream waiting for decoding. */ + GString * output; /* JSON stream to be sent. */ + gint64 seq; + GArray * calls; /* Method calls waiting for a response. */ + GHashTable * interfaces; /* interface uuid => OpenvswitchInterface */ + GHashTable * ports; /* port uuid => OpenvswitchPort */ + GHashTable * bridges; /* bridge uuid => OpenvswitchBridge */ + char * db_uuid; + guint num_failures; } NMOvsdbPrivate; struct _NMOvsdb { - GObject parent; - NMOvsdbPrivate _priv; + GObject parent; + NMOvsdbPrivate _priv; }; struct _NMOvsdbClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMOvsdb, nm_ovsdb, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMOvsdb, nm_ovsdb, G_TYPE_OBJECT) -#define NM_OVSDB_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMOvsdb, NM_IS_OVSDB) +#define NM_OVSDB_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMOvsdb, NM_IS_OVSDB) #define _NMLOG_DOMAIN LOGD_DEVICE -#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "ovsdb", __VA_ARGS__) +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "ovsdb", __VA_ARGS__) -NM_DEFINE_SINGLETON_GETTER (NMOvsdb, nm_ovsdb_get, NM_TYPE_OVSDB); +NM_DEFINE_SINGLETON_GETTER(NMOvsdb, nm_ovsdb_get, NM_TYPE_OVSDB); /*****************************************************************************/ -static void ovsdb_try_connect (NMOvsdb *self); -static void ovsdb_disconnect (NMOvsdb *self, gboolean retry, gboolean is_disposing); -static void ovsdb_read (NMOvsdb *self); -static void ovsdb_write (NMOvsdb *self); -static void ovsdb_next_command (NMOvsdb *self); +static void ovsdb_try_connect(NMOvsdb *self); +static void ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing); +static void ovsdb_read(NMOvsdb *self); +static void ovsdb_write(NMOvsdb *self); +static void ovsdb_next_command(NMOvsdb *self); /*****************************************************************************/ /* ovsdb command abstraction. */ -typedef void (*OvsdbMethodCallback) (NMOvsdb *self, json_t *response, - GError *error, gpointer user_data); +typedef void (*OvsdbMethodCallback)(NMOvsdb *self, + json_t * response, + GError * error, + gpointer user_data); typedef enum { - OVSDB_MONITOR, - OVSDB_ADD_INTERFACE, - OVSDB_DEL_INTERFACE, - OVSDB_SET_INTERFACE_MTU, + OVSDB_MONITOR, + OVSDB_ADD_INTERFACE, + OVSDB_DEL_INTERFACE, + OVSDB_SET_INTERFACE_MTU, } OvsdbCommand; typedef struct { - gint64 id; -#define COMMAND_PENDING -1 /* id not yet assigned */ - OvsdbCommand command; - OvsdbMethodCallback callback; - gpointer user_data; - union { - struct { - char *ifname; - guint32 mtu; - }; - struct { - NMConnection *bridge; - NMConnection *port; - NMConnection *interface; - NMDevice *bridge_device; - NMDevice *interface_device; - }; - }; + gint64 id; +#define COMMAND_PENDING -1 /* id not yet assigned */ + OvsdbCommand command; + OvsdbMethodCallback callback; + gpointer user_data; + union { + struct { + char * ifname; + guint32 mtu; + }; + struct { + NMConnection *bridge; + NMConnection *port; + NMConnection *interface; + NMDevice * bridge_device; + NMDevice * interface_device; + }; + }; } OvsdbMethodCall; -#define OVSDB_MAX_FAILURES 3 +#define OVSDB_MAX_FAILURES 3 static void -_LOGT_call_do (const char *comment, OvsdbMethodCall *call, json_t *msg) +_LOGT_call_do(const char *comment, OvsdbMethodCall *call, json_t *msg) { - gs_free char *str = NULL; - - if (msg) - str = json_dumps (msg, 0); - - switch (call->command) { - case OVSDB_MONITOR: - _LOGT ("%s: monitor%s%s", - comment, - msg ? ": " : "", - msg ? str : ""); - break; - case OVSDB_ADD_INTERFACE: - _LOGT ("%s: add-iface bridge=%s port=%s interface=%s%s%s", - comment, - nm_connection_get_interface_name (call->bridge), - nm_connection_get_interface_name (call->port), - nm_connection_get_interface_name (call->interface), - msg ? ": " : "", - msg ? str : ""); - break; - case OVSDB_DEL_INTERFACE: - _LOGT ("%s: del-iface interface=%s%s%s", - comment, call->ifname, - msg ? ": " : "", - msg ? str : ""); - break; - case OVSDB_SET_INTERFACE_MTU: - _LOGT ("%s: set-iface-mtu interface=%s%s%s mtu=%u", - comment, call->ifname, - msg ? ": " : "", - msg ? str : "", - call->mtu); - break; - } + gs_free char *str = NULL; + + if (msg) + str = json_dumps(msg, 0); + + switch (call->command) { + case OVSDB_MONITOR: + _LOGT("%s: monitor%s%s", comment, msg ? ": " : "", msg ? str : ""); + break; + case OVSDB_ADD_INTERFACE: + _LOGT("%s: add-iface bridge=%s port=%s interface=%s%s%s", + comment, + nm_connection_get_interface_name(call->bridge), + nm_connection_get_interface_name(call->port), + nm_connection_get_interface_name(call->interface), + msg ? ": " : "", + msg ? str : ""); + break; + case OVSDB_DEL_INTERFACE: + _LOGT("%s: del-iface interface=%s%s%s", + comment, + call->ifname, + msg ? ": " : "", + msg ? str : ""); + break; + case OVSDB_SET_INTERFACE_MTU: + _LOGT("%s: set-iface-mtu interface=%s%s%s mtu=%u", + comment, + call->ifname, + msg ? ": " : "", + msg ? str : "", + call->mtu); + break; + } } -#define _LOGT_call(comment, call, message) \ - G_STMT_START { \ - if (_LOGT_ENABLED ()) \ - _LOGT_call_do ((comment), (call), (message)); \ - } G_STMT_END +#define _LOGT_call(comment, call, message) \ + G_STMT_START \ + { \ + if (_LOGT_ENABLED()) \ + _LOGT_call_do((comment), (call), (message)); \ + } \ + G_STMT_END /** * ovsdb_call_method: @@ -183,53 +181,59 @@ _LOGT_call_do (const char *comment, OvsdbMethodCall *call, json_t *msg) * there's no command pending completion. */ static void -ovsdb_call_method (NMOvsdb *self, OvsdbCommand command, - const char *ifname, - NMConnection *bridge, NMConnection *port, NMConnection *interface, - NMDevice *bridge_device, NMDevice *interface_device, - guint32 mtu, OvsdbMethodCallback callback, gpointer user_data, - gboolean add_first) +ovsdb_call_method(NMOvsdb * self, + OvsdbCommand command, + const char * ifname, + NMConnection * bridge, + NMConnection * port, + NMConnection * interface, + NMDevice * bridge_device, + NMDevice * interface_device, + guint32 mtu, + OvsdbMethodCallback callback, + gpointer user_data, + gboolean add_first) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - OvsdbMethodCall *call; - - /* Ensure we're not unsynchronized before we queue the method call. */ - ovsdb_try_connect (self); - - if (add_first) { - g_array_prepend_val (priv->calls, (OvsdbMethodCall) {}); - call = &g_array_index (priv->calls, OvsdbMethodCall, 0); - } else { - g_array_set_size (priv->calls, priv->calls->len + 1); - call = &g_array_index (priv->calls, OvsdbMethodCall, priv->calls->len - 1); - } - call->id = COMMAND_PENDING; - call->command = command; - call->callback = callback; - call->user_data = user_data; - - switch (call->command) { - case OVSDB_MONITOR: - break; - case OVSDB_ADD_INTERFACE: - call->bridge = nm_simple_connection_new_clone (bridge); - call->port = nm_simple_connection_new_clone (port); - call->interface = nm_simple_connection_new_clone (interface); - call->bridge_device = g_object_ref (bridge_device); - call->interface_device = g_object_ref (interface_device); - break; - case OVSDB_DEL_INTERFACE: - call->ifname = g_strdup (ifname); - break; - case OVSDB_SET_INTERFACE_MTU: - call->ifname = g_strdup (ifname); - call->mtu = mtu; - break; - } - - _LOGT_call ("enqueue", call, NULL); - - ovsdb_next_command (self); + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + OvsdbMethodCall *call; + + /* Ensure we're not unsynchronized before we queue the method call. */ + ovsdb_try_connect(self); + + if (add_first) { + g_array_prepend_val(priv->calls, (OvsdbMethodCall){}); + call = &g_array_index(priv->calls, OvsdbMethodCall, 0); + } else { + g_array_set_size(priv->calls, priv->calls->len + 1); + call = &g_array_index(priv->calls, OvsdbMethodCall, priv->calls->len - 1); + } + call->id = COMMAND_PENDING; + call->command = command; + call->callback = callback; + call->user_data = user_data; + + switch (call->command) { + case OVSDB_MONITOR: + break; + case OVSDB_ADD_INTERFACE: + call->bridge = nm_simple_connection_new_clone(bridge); + call->port = nm_simple_connection_new_clone(port); + call->interface = nm_simple_connection_new_clone(interface); + call->bridge_device = g_object_ref(bridge_device); + call->interface_device = g_object_ref(interface_device); + break; + case OVSDB_DEL_INTERFACE: + call->ifname = g_strdup(ifname); + break; + case OVSDB_SET_INTERFACE_MTU: + call->ifname = g_strdup(ifname); + call->mtu = mtu; + break; + } + + _LOGT_call("enqueue", call, NULL); + + ovsdb_next_command(self); } /*****************************************************************************/ @@ -245,15 +249,30 @@ ovsdb_call_method (NMOvsdb *self, OvsdbCommand command, * at the same time. */ static void -_expect_ovs_bridges (json_t *params, const char *db_uuid, json_t *bridges) +_expect_ovs_bridges(json_t *params, const char *db_uuid, json_t *bridges) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, [s, s]]]}", - "op", "wait", "table", "Open_vSwitch", - "timeout", 0, "columns", "bridges", - "until", "==", "rows", "bridges", "set", bridges, - "where", "_uuid", "==", "uuid", db_uuid) - ); + json_array_append_new( + params, + json_pack("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, [s, s]]]}", + "op", + "wait", + "table", + "Open_vSwitch", + "timeout", + 0, + "columns", + "bridges", + "until", + "==", + "rows", + "bridges", + "set", + bridges, + "where", + "_uuid", + "==", + "uuid", + db_uuid)); } /** @@ -263,14 +282,23 @@ _expect_ovs_bridges (json_t *params, const char *db_uuid, json_t *bridges) * database to @new_bridges. */ static void -_set_ovs_bridges (json_t *params, const char *db_uuid, json_t *new_bridges) +_set_ovs_bridges(json_t *params, const char *db_uuid, json_t *new_bridges) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, [s, s]]]}", - "op", "update", "table", "Open_vSwitch", - "row", "bridges", "set", new_bridges, - "where", "_uuid", "==", "uuid", db_uuid) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, [s, s]]]}", + "op", + "update", + "table", + "Open_vSwitch", + "row", + "bridges", + "set", + new_bridges, + "where", + "_uuid", + "==", + "uuid", + db_uuid)); } /** @@ -282,15 +310,28 @@ _set_ovs_bridges (json_t *params, const char *db_uuid, json_t *new_bridges) * bridge ports at the same time. */ static void -_expect_bridge_ports (json_t *params, const char *ifname, json_t *ports) +_expect_bridge_ports(json_t *params, const char *ifname, json_t *ports) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, s]]}", - "op", "wait", "table", "Bridge", - "timeout", 0, "columns", "ports", - "until", "==", "rows", "ports", "set", ports, - "where", "name", "==", ifname) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, s]]}", + "op", + "wait", + "table", + "Bridge", + "timeout", + 0, + "columns", + "ports", + "until", + "==", + "rows", + "ports", + "set", + ports, + "where", + "name", + "==", + ifname)); } /** @@ -300,26 +341,42 @@ _expect_bridge_ports (json_t *params, const char *ifname, json_t *ports) * @ifname to @new_ports. */ static void -_set_bridge_ports (json_t *params, const char *ifname, json_t *new_ports) +_set_bridge_ports(json_t *params, const char *ifname, json_t *new_ports) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, s]]}", - "op", "update", "table", "Bridge", - "row", "ports", "set", new_ports, - "where", "name", "==", ifname) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, s]]}", + "op", + "update", + "table", + "Bridge", + "row", + "ports", + "set", + new_ports, + "where", + "name", + "==", + ifname)); } static void -_set_bridge_mac (json_t *params, const char *ifname, const char *mac) +_set_bridge_mac(json_t *params, const char *ifname, const char *mac) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:{s:[s, [[s, s]]]}, s:[[s, s, s]]}", - "op", "update", "table", "Bridge", - "row", "other_config", "map", - "hwaddr", mac, - "where", "name", "==", ifname) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:{s:[s, [[s, s]]]}, s:[[s, s, s]]}", + "op", + "update", + "table", + "Bridge", + "row", + "other_config", + "map", + "hwaddr", + mac, + "where", + "name", + "==", + ifname)); } /** @@ -331,15 +388,28 @@ _set_bridge_mac (json_t *params, const char *ifname, const char *mac) * or removing port interfaces at the same time. */ static void -_expect_port_interfaces (json_t *params, const char *ifname, json_t *interfaces) +_expect_port_interfaces(json_t *params, const char *ifname, json_t *interfaces) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, s]]}", - "op", "wait", "table", "Port", - "timeout", 0, "columns", "interfaces", - "until", "==", "rows", "interfaces", "set", interfaces, - "where", "name", "==", ifname) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:i, s:[s], s:s, s:[{s:[s, O]}], s:[[s, s, s]]}", + "op", + "wait", + "table", + "Port", + "timeout", + 0, + "columns", + "interfaces", + "until", + "==", + "rows", + "interfaces", + "set", + interfaces, + "where", + "name", + "==", + ifname)); } /** @@ -349,14 +419,22 @@ _expect_port_interfaces (json_t *params, const char *ifname, json_t *interfaces) * to @new_interfaces. */ static void -_set_port_interfaces (json_t *params, const char *ifname, json_t *new_interfaces) +_set_port_interfaces(json_t *params, const char *ifname, json_t *new_interfaces) { - json_array_append_new (params, - json_pack ("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, s]]}", - "op", "update", "table", "Port", - "row", "interfaces", "set", new_interfaces, - "where", "name", "==", ifname) - ); + json_array_append_new(params, + json_pack("{s:s, s:s, s:{s:[s, O]}, s:[[s, s, s]]}", + "op", + "update", + "table", + "Port", + "row", + "interfaces", + "set", + new_interfaces, + "where", + "name", + "==", + ifname)); } /** @@ -365,69 +443,78 @@ _set_port_interfaces (json_t *params, const char *ifname, json_t *new_interfaces * Returns an commands that adds new interface from a given connection. */ static void -_insert_interface (json_t *params, - NMConnection *interface, - NMDevice *interface_device, - const char *cloned_mac) +_insert_interface(json_t * params, + NMConnection *interface, + NMDevice * interface_device, + const char * cloned_mac) { - const char *type = NULL; - NMSettingOvsInterface *s_ovs_iface; - NMSettingOvsDpdk *s_ovs_dpdk; - NMSettingOvsPatch *s_ovs_patch; - json_t *options = json_array (); - json_t *row; - guint32 mtu = 0; - - s_ovs_iface = nm_connection_get_setting_ovs_interface (interface); - if (s_ovs_iface) - type = nm_setting_ovs_interface_get_interface_type (s_ovs_iface); - - if (nm_streq0 (type, "internal")) { - NMSettingWired *s_wired; - - s_wired = _nm_connection_get_setting (interface, NM_TYPE_SETTING_WIRED); - if (s_wired) - mtu = nm_setting_wired_get_mtu (s_wired); - } - - json_array_append_new (options, json_string ("map")); - - s_ovs_dpdk = (NMSettingOvsDpdk *) nm_connection_get_setting (interface, - NM_TYPE_SETTING_OVS_DPDK); - if (!s_ovs_dpdk) - s_ovs_patch = nm_connection_get_setting_ovs_patch (interface); - - if (s_ovs_dpdk) { - json_array_append_new (options, json_pack ("[[s, s]]", - "dpdk-devargs", - nm_setting_ovs_dpdk_get_devargs (s_ovs_dpdk))); - } else if (s_ovs_patch) { - json_array_append_new (options, json_pack ("[[s, s]]", - "peer", - nm_setting_ovs_patch_get_peer (s_ovs_patch))); - } else { - json_array_append_new (options, json_array ()); - } - - row = json_pack ("{s:s, s:s, s:o, s:[s, [[s, s]]]}", - "name", nm_connection_get_interface_name (interface), - "type", type ?: "", - "options", options, - "external_ids", "map", - "NM.connection.uuid", nm_connection_get_uuid (interface)); - - if (cloned_mac) - json_object_set_new (row, "mac", json_string (cloned_mac)); - - if (mtu != 0) - json_object_set_new (row, "mtu_request", json_integer (mtu)); - - json_array_append_new (params, - json_pack ("{s:s, s:s, s:o, s:s}", - "op", "insert", - "table", "Interface", - "row", row, - "uuid-name", "rowInterface")); + const char * type = NULL; + NMSettingOvsInterface *s_ovs_iface; + NMSettingOvsDpdk * s_ovs_dpdk; + NMSettingOvsPatch * s_ovs_patch; + json_t * options = json_array(); + json_t * row; + guint32 mtu = 0; + + s_ovs_iface = nm_connection_get_setting_ovs_interface(interface); + if (s_ovs_iface) + type = nm_setting_ovs_interface_get_interface_type(s_ovs_iface); + + if (nm_streq0(type, "internal")) { + NMSettingWired *s_wired; + + s_wired = _nm_connection_get_setting(interface, NM_TYPE_SETTING_WIRED); + if (s_wired) + mtu = nm_setting_wired_get_mtu(s_wired); + } + + json_array_append_new(options, json_string("map")); + + s_ovs_dpdk = + (NMSettingOvsDpdk *) nm_connection_get_setting(interface, NM_TYPE_SETTING_OVS_DPDK); + if (!s_ovs_dpdk) + s_ovs_patch = nm_connection_get_setting_ovs_patch(interface); + + if (s_ovs_dpdk) { + json_array_append_new( + options, + json_pack("[[s, s]]", "dpdk-devargs", nm_setting_ovs_dpdk_get_devargs(s_ovs_dpdk))); + } else if (s_ovs_patch) { + json_array_append_new( + options, + json_pack("[[s, s]]", "peer", nm_setting_ovs_patch_get_peer(s_ovs_patch))); + } else { + json_array_append_new(options, json_array()); + } + + row = json_pack("{s:s, s:s, s:o, s:[s, [[s, s]]]}", + "name", + nm_connection_get_interface_name(interface), + "type", + type ?: "", + "options", + options, + "external_ids", + "map", + "NM.connection.uuid", + nm_connection_get_uuid(interface)); + + if (cloned_mac) + json_object_set_new(row, "mac", json_string(cloned_mac)); + + if (mtu != 0) + json_object_set_new(row, "mtu_request", json_integer(mtu)); + + json_array_append_new(params, + json_pack("{s:s, s:s, s:o, s:s}", + "op", + "insert", + "table", + "Interface", + "row", + row, + "uuid-name", + "rowInterface")); } /** @@ -436,53 +523,61 @@ _insert_interface (json_t *params, * Returns an commands that adds new port from a given connection. */ static void -_insert_port (json_t *params, NMConnection *port, json_t *new_interfaces) +_insert_port(json_t *params, NMConnection *port, json_t *new_interfaces) { - NMSettingOvsPort *s_ovs_port; - const char *vlan_mode = NULL; - guint tag = 0; - const char *lacp = NULL; - const char *bond_mode = NULL; - guint bond_updelay = 0; - guint bond_downdelay = 0; - json_t *row; - - s_ovs_port = nm_connection_get_setting_ovs_port (port); - - row = json_object (); - - if (s_ovs_port) { - vlan_mode = nm_setting_ovs_port_get_vlan_mode (s_ovs_port); - tag = nm_setting_ovs_port_get_tag (s_ovs_port); - lacp = nm_setting_ovs_port_get_lacp (s_ovs_port); - bond_mode = nm_setting_ovs_port_get_bond_mode (s_ovs_port); - bond_updelay = nm_setting_ovs_port_get_bond_updelay (s_ovs_port); - bond_downdelay = nm_setting_ovs_port_get_bond_downdelay (s_ovs_port); - } - - if (vlan_mode) - json_object_set_new (row, "vlan_mode", json_string (vlan_mode)); - if (tag) - json_object_set_new (row, "tag", json_integer (tag)); - if (lacp) - json_object_set_new (row, "lacp", json_string (lacp)); - if (bond_mode) - json_object_set_new (row, "bond_mode", json_string (bond_mode)); - if (bond_updelay) - json_object_set_new (row, "bond_updelay", json_integer (bond_updelay)); - if (bond_downdelay) - json_object_set_new (row, "bond_downdelay", json_integer (bond_downdelay)); - - json_object_set_new (row, "name", json_string (nm_connection_get_interface_name (port))); - json_object_set_new (row, "interfaces", json_pack ("[s, O]", "set", new_interfaces)); - json_object_set_new (row, "external_ids", - json_pack ("[s, [[s, s]]]", "map", - "NM.connection.uuid", nm_connection_get_uuid (port))); - - /* Create a new one. */ - json_array_append_new (params, - json_pack ("{s:s, s:s, s:o, s:s}", "op", "insert", "table", "Port", - "row", row, "uuid-name", "rowPort")); + NMSettingOvsPort *s_ovs_port; + const char * vlan_mode = NULL; + guint tag = 0; + const char * lacp = NULL; + const char * bond_mode = NULL; + guint bond_updelay = 0; + guint bond_downdelay = 0; + json_t * row; + + s_ovs_port = nm_connection_get_setting_ovs_port(port); + + row = json_object(); + + if (s_ovs_port) { + vlan_mode = nm_setting_ovs_port_get_vlan_mode(s_ovs_port); + tag = nm_setting_ovs_port_get_tag(s_ovs_port); + lacp = nm_setting_ovs_port_get_lacp(s_ovs_port); + bond_mode = nm_setting_ovs_port_get_bond_mode(s_ovs_port); + bond_updelay = nm_setting_ovs_port_get_bond_updelay(s_ovs_port); + bond_downdelay = nm_setting_ovs_port_get_bond_downdelay(s_ovs_port); + } + + if (vlan_mode) + json_object_set_new(row, "vlan_mode", json_string(vlan_mode)); + if (tag) + json_object_set_new(row, "tag", json_integer(tag)); + if (lacp) + json_object_set_new(row, "lacp", json_string(lacp)); + if (bond_mode) + json_object_set_new(row, "bond_mode", json_string(bond_mode)); + if (bond_updelay) + json_object_set_new(row, "bond_updelay", json_integer(bond_updelay)); + if (bond_downdelay) + json_object_set_new(row, "bond_downdelay", json_integer(bond_downdelay)); + + json_object_set_new(row, "name", json_string(nm_connection_get_interface_name(port))); + json_object_set_new(row, "interfaces", json_pack("[s, O]", "set", new_interfaces)); + json_object_set_new( + row, + "external_ids", + json_pack("[s, [[s, s]]]", "map", "NM.connection.uuid", nm_connection_get_uuid(port))); + + /* Create a new one. */ + json_array_append_new(params, + json_pack("{s:s, s:s, s:o, s:s}", + "op", + "insert", + "table", + "Port", + "row", + row, + "uuid-name", + "rowPort")); } /** @@ -491,59 +586,67 @@ _insert_port (json_t *params, NMConnection *port, json_t *new_interfaces) * Returns an commands that adds new bridge from a given connection. */ static void -_insert_bridge (json_t *params, - NMConnection *bridge, - NMDevice *bridge_device, - json_t *new_ports, - const char *cloned_mac) +_insert_bridge(json_t * params, + NMConnection *bridge, + NMDevice * bridge_device, + json_t * new_ports, + const char * cloned_mac) { - NMSettingOvsBridge *s_ovs_bridge; - const char *fail_mode = NULL; - gboolean mcast_snooping_enable = FALSE; - gboolean rstp_enable = FALSE; - gboolean stp_enable = FALSE; - const char *datapath_type = NULL; - json_t *row; - - s_ovs_bridge = nm_connection_get_setting_ovs_bridge (bridge); - - row = json_object (); - - if (s_ovs_bridge) { - fail_mode = nm_setting_ovs_bridge_get_fail_mode (s_ovs_bridge); - mcast_snooping_enable = nm_setting_ovs_bridge_get_mcast_snooping_enable (s_ovs_bridge); - rstp_enable = nm_setting_ovs_bridge_get_rstp_enable (s_ovs_bridge); - stp_enable = nm_setting_ovs_bridge_get_stp_enable (s_ovs_bridge); - datapath_type = nm_setting_ovs_bridge_get_datapath_type (s_ovs_bridge); - } - - if (fail_mode) - json_object_set_new (row, "fail_mode", json_string (fail_mode)); - if (mcast_snooping_enable) - json_object_set_new (row, "mcast_snooping_enable", json_boolean (mcast_snooping_enable)); - if (rstp_enable) - json_object_set_new (row, "rstp_enable", json_boolean (rstp_enable)); - if (stp_enable) - json_object_set_new (row, "stp_enable", json_boolean (stp_enable)); - if (datapath_type) - json_object_set_new (row, "datapath_type", json_string (datapath_type)); - - json_object_set_new (row, "name", json_string (nm_connection_get_interface_name (bridge))); - json_object_set_new (row, "ports", json_pack ("[s, O]", "set", new_ports)); - json_object_set_new (row, "external_ids", - json_pack ("[s, [[s, s]]]", "map", - "NM.connection.uuid", nm_connection_get_uuid (bridge))); - - if (cloned_mac) { - json_object_set_new (row, "other_config", - json_pack ("[s, [[s, s]]]", "map", - "hwaddr", cloned_mac)); - } - - /* Create a new one. */ - json_array_append_new (params, - json_pack ("{s:s, s:s, s:o, s:s}", "op", "insert", "table", "Bridge", - "row", row, "uuid-name", "rowBridge")); + NMSettingOvsBridge *s_ovs_bridge; + const char * fail_mode = NULL; + gboolean mcast_snooping_enable = FALSE; + gboolean rstp_enable = FALSE; + gboolean stp_enable = FALSE; + const char * datapath_type = NULL; + json_t * row; + + s_ovs_bridge = nm_connection_get_setting_ovs_bridge(bridge); + + row = json_object(); + + if (s_ovs_bridge) { + fail_mode = nm_setting_ovs_bridge_get_fail_mode(s_ovs_bridge); + mcast_snooping_enable = nm_setting_ovs_bridge_get_mcast_snooping_enable(s_ovs_bridge); + rstp_enable = nm_setting_ovs_bridge_get_rstp_enable(s_ovs_bridge); + stp_enable = nm_setting_ovs_bridge_get_stp_enable(s_ovs_bridge); + datapath_type = nm_setting_ovs_bridge_get_datapath_type(s_ovs_bridge); + } + + if (fail_mode) + json_object_set_new(row, "fail_mode", json_string(fail_mode)); + if (mcast_snooping_enable) + json_object_set_new(row, "mcast_snooping_enable", json_boolean(mcast_snooping_enable)); + if (rstp_enable) + json_object_set_new(row, "rstp_enable", json_boolean(rstp_enable)); + if (stp_enable) + json_object_set_new(row, "stp_enable", json_boolean(stp_enable)); + if (datapath_type) + json_object_set_new(row, "datapath_type", json_string(datapath_type)); + + json_object_set_new(row, "name", json_string(nm_connection_get_interface_name(bridge))); + json_object_set_new(row, "ports", json_pack("[s, O]", "set", new_ports)); + json_object_set_new( + row, + "external_ids", + json_pack("[s, [[s, s]]]", "map", "NM.connection.uuid", nm_connection_get_uuid(bridge))); + + if (cloned_mac) { + json_object_set_new(row, + "other_config", + json_pack("[s, [[s, s]]]", "map", "hwaddr", cloned_mac)); + } + + /* Create a new one. */ + json_array_append_new(params, + json_pack("{s:s, s:s, s:o, s:s}", + "op", + "insert", + "table", + "Bridge", + "row", + row, + "uuid-name", + "rowBridge")); } /** @@ -553,12 +656,22 @@ _insert_bridge (json_t *params, * of the transaction it is in. */ static json_t * -_inc_next_cfg (const char *db_uuid) +_inc_next_cfg(const char *db_uuid) { - return json_pack ("{s:s, s:s, s:[[s, s, i]], s:[[s, s, [s, s]]]}", - "op", "mutate", "table", "Open_vSwitch", - "mutations", "next_cfg", "+=", 1, - "where", "_uuid", "==", "uuid", db_uuid); + return json_pack("{s:s, s:s, s:[[s, s, i]], s:[[s, s, [s, s]]]}", + "op", + "mutate", + "table", + "Open_vSwitch", + "mutations", + "next_cfg", + "+=", + 1, + "where", + "_uuid", + "==", + "uuid", + db_uuid); } /** @@ -568,160 +681,165 @@ _inc_next_cfg (const char *db_uuid) * a parent @port and @bridge if needed. */ static void -_add_interface (NMOvsdb *self, json_t *params, - NMConnection *bridge, NMConnection *port, NMConnection *interface, - NMDevice *bridge_device, NMDevice *interface_device) +_add_interface(NMOvsdb * self, + json_t * params, + NMConnection *bridge, + NMConnection *port, + NMConnection *interface, + NMDevice * bridge_device, + NMDevice * interface_device) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GHashTableIter iter; - const char *bridge_uuid; - const char *port_uuid; - const char *interface_uuid; - const char *bridge_name; - const char *port_name; - const char *interface_name; - OpenvswitchBridge *ovs_bridge = NULL; - OpenvswitchPort *ovs_port = NULL; - OpenvswitchInterface *ovs_interface = NULL; - nm_auto_decref_json json_t *bridges = NULL; - nm_auto_decref_json json_t *new_bridges = NULL; - nm_auto_decref_json json_t *ports = NULL; - nm_auto_decref_json json_t *new_ports = NULL; - nm_auto_decref_json json_t *interfaces = NULL; - nm_auto_decref_json json_t *new_interfaces = NULL; - gboolean has_interface = FALSE; - gboolean interface_is_internal; - gs_free char *bridge_cloned_mac = NULL; - gs_free char *interface_cloned_mac = NULL; - GError *error = NULL; - int pi; - int ii; - - bridges = json_array (); - ports = json_array (); - interfaces = json_array (); - new_bridges = json_array (); - new_ports = json_array (); - new_interfaces = json_array (); - - bridge_name = nm_connection_get_interface_name (bridge); - port_name = nm_connection_get_interface_name (port); - interface_name = nm_connection_get_interface_name (interface); - interface_is_internal = nm_streq0 (bridge_name, interface_name); - - /* Determine cloned MAC addresses */ - if (!nm_device_hw_addr_get_cloned (bridge_device, - bridge, - FALSE, - &bridge_cloned_mac, - NULL, - &error)) { - _LOGW ("Cannot determine cloned mac for OVS %s '%s': %s", - "bridge", - bridge_name, - error->message); - g_clear_error (&error); - } - - if (!nm_device_hw_addr_get_cloned (interface_device, - interface, - FALSE, - &interface_cloned_mac, - NULL, - &error)) { - _LOGW ("Cannot determine cloned mac for OVS %s '%s': %s", - "interface", - interface_name, - error->message); - g_clear_error (&error); - } - - if ( interface_is_internal - && !bridge_cloned_mac - && interface_cloned_mac) { - _LOGT ("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'", - interface_name, bridge_name); - bridge_cloned_mac = g_steal_pointer (&interface_cloned_mac); - } - - g_hash_table_iter_init (&iter, priv->bridges); - while (g_hash_table_iter_next (&iter, (gpointer) &bridge_uuid, (gpointer) &ovs_bridge)) { - json_array_append_new (bridges, json_pack ("[s, s]", "uuid", bridge_uuid)); - - if ( g_strcmp0 (ovs_bridge->name, bridge_name) != 0 - || g_strcmp0 (ovs_bridge->connection_uuid, nm_connection_get_uuid (bridge)) != 0) - continue; - - for (pi = 0; pi < ovs_bridge->ports->len; pi++) { - port_uuid = g_ptr_array_index (ovs_bridge->ports, pi); - ovs_port = g_hash_table_lookup (priv->ports, port_uuid); - - json_array_append_new (ports, json_pack ("[s, s]", "uuid", port_uuid)); - - if (!ovs_port) { - /* This would be a violation of ovsdb's reference integrity (a bug). */ - _LOGW ("Unknown port '%s' in bridge '%s'", port_uuid, bridge_uuid); - continue; - } else if ( strcmp (ovs_port->name, port_name) != 0 - || g_strcmp0 (ovs_port->connection_uuid, nm_connection_get_uuid (port)) != 0) { - continue; - } - - for (ii = 0; ii < ovs_port->interfaces->len; ii++) { - interface_uuid = g_ptr_array_index (ovs_port->interfaces, ii); - ovs_interface = g_hash_table_lookup (priv->interfaces, interface_uuid); - - json_array_append_new (interfaces, json_pack ("[s, s]", "uuid", interface_uuid)); - - if (!ovs_interface) { - /* This would be a violation of ovsdb's reference integrity (a bug). */ - _LOGW ("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid); - } else if ( strcmp (ovs_interface->name, interface_name) == 0 - && g_strcmp0 (ovs_interface->connection_uuid, nm_connection_get_uuid (interface)) == 0) { - has_interface = TRUE; - } - } - - break; - } - - break; - } - - json_array_extend (new_bridges, bridges); - json_array_extend (new_ports, ports); - json_array_extend (new_interfaces, interfaces); - - if (json_array_size (interfaces) == 0) { - /* Need to create a port. */ - if (json_array_size (ports) == 0) { - /* Need to create a bridge. */ - _expect_ovs_bridges (params, priv->db_uuid, bridges); - json_array_append_new (new_bridges, json_pack ("[s, s]", "named-uuid", "rowBridge")); - _set_ovs_bridges (params, priv->db_uuid, new_bridges); - _insert_bridge (params, bridge, bridge_device, new_ports, bridge_cloned_mac); - } else { - /* Bridge already exists. */ - g_return_if_fail (ovs_bridge); - _expect_bridge_ports (params, ovs_bridge->name, ports); - _set_bridge_ports (params, bridge_name, new_ports); - if (bridge_cloned_mac && interface_is_internal) - _set_bridge_mac (params, bridge_name, bridge_cloned_mac); - } - - json_array_append_new (new_ports, json_pack ("[s, s]", "named-uuid", "rowPort")); - _insert_port (params, port, new_interfaces); - } else { - /* Port already exists */ - g_return_if_fail (ovs_port); - _expect_port_interfaces (params, ovs_port->name, interfaces); - _set_port_interfaces (params, port_name, new_interfaces); - } - - if (!has_interface) { - _insert_interface (params, interface, interface_device, interface_cloned_mac); - json_array_append_new (new_interfaces, json_pack ("[s, s]", "named-uuid", "rowInterface")); - } + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + GHashTableIter iter; + const char * bridge_uuid; + const char * port_uuid; + const char * interface_uuid; + const char * bridge_name; + const char * port_name; + const char * interface_name; + OpenvswitchBridge * ovs_bridge = NULL; + OpenvswitchPort * ovs_port = NULL; + OpenvswitchInterface *ovs_interface = NULL; + nm_auto_decref_json json_t *bridges = NULL; + nm_auto_decref_json json_t *new_bridges = NULL; + nm_auto_decref_json json_t *ports = NULL; + nm_auto_decref_json json_t *new_ports = NULL; + nm_auto_decref_json json_t *interfaces = NULL; + nm_auto_decref_json json_t *new_interfaces = NULL; + gboolean has_interface = FALSE; + gboolean interface_is_internal; + gs_free char * bridge_cloned_mac = NULL; + gs_free char * interface_cloned_mac = NULL; + GError * error = NULL; + int pi; + int ii; + + bridges = json_array(); + ports = json_array(); + interfaces = json_array(); + new_bridges = json_array(); + new_ports = json_array(); + new_interfaces = json_array(); + + bridge_name = nm_connection_get_interface_name(bridge); + port_name = nm_connection_get_interface_name(port); + interface_name = nm_connection_get_interface_name(interface); + interface_is_internal = nm_streq0(bridge_name, interface_name); + + /* Determine cloned MAC addresses */ + if (!nm_device_hw_addr_get_cloned(bridge_device, + bridge, + FALSE, + &bridge_cloned_mac, + NULL, + &error)) { + _LOGW("Cannot determine cloned mac for OVS %s '%s': %s", + "bridge", + bridge_name, + error->message); + g_clear_error(&error); + } + + if (!nm_device_hw_addr_get_cloned(interface_device, + interface, + FALSE, + &interface_cloned_mac, + NULL, + &error)) { + _LOGW("Cannot determine cloned mac for OVS %s '%s': %s", + "interface", + interface_name, + error->message); + g_clear_error(&error); + } + + if (interface_is_internal && !bridge_cloned_mac && interface_cloned_mac) { + _LOGT("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'", + interface_name, + bridge_name); + bridge_cloned_mac = g_steal_pointer(&interface_cloned_mac); + } + + g_hash_table_iter_init(&iter, priv->bridges); + while (g_hash_table_iter_next(&iter, (gpointer) &bridge_uuid, (gpointer) &ovs_bridge)) { + json_array_append_new(bridges, json_pack("[s, s]", "uuid", bridge_uuid)); + + if (g_strcmp0(ovs_bridge->name, bridge_name) != 0 + || g_strcmp0(ovs_bridge->connection_uuid, nm_connection_get_uuid(bridge)) != 0) + continue; + + for (pi = 0; pi < ovs_bridge->ports->len; pi++) { + port_uuid = g_ptr_array_index(ovs_bridge->ports, pi); + ovs_port = g_hash_table_lookup(priv->ports, port_uuid); + + json_array_append_new(ports, json_pack("[s, s]", "uuid", port_uuid)); + + if (!ovs_port) { + /* This would be a violation of ovsdb's reference integrity (a bug). */ + _LOGW("Unknown port '%s' in bridge '%s'", port_uuid, bridge_uuid); + continue; + } else if (strcmp(ovs_port->name, port_name) != 0 + || g_strcmp0(ovs_port->connection_uuid, nm_connection_get_uuid(port)) != 0) { + continue; + } + + for (ii = 0; ii < ovs_port->interfaces->len; ii++) { + interface_uuid = g_ptr_array_index(ovs_port->interfaces, ii); + ovs_interface = g_hash_table_lookup(priv->interfaces, interface_uuid); + + json_array_append_new(interfaces, json_pack("[s, s]", "uuid", interface_uuid)); + + if (!ovs_interface) { + /* This would be a violation of ovsdb's reference integrity (a bug). */ + _LOGW("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid); + } else if (strcmp(ovs_interface->name, interface_name) == 0 + && g_strcmp0(ovs_interface->connection_uuid, + nm_connection_get_uuid(interface)) + == 0) { + has_interface = TRUE; + } + } + + break; + } + + break; + } + + json_array_extend(new_bridges, bridges); + json_array_extend(new_ports, ports); + json_array_extend(new_interfaces, interfaces); + + if (json_array_size(interfaces) == 0) { + /* Need to create a port. */ + if (json_array_size(ports) == 0) { + /* Need to create a bridge. */ + _expect_ovs_bridges(params, priv->db_uuid, bridges); + json_array_append_new(new_bridges, json_pack("[s, s]", "named-uuid", "rowBridge")); + _set_ovs_bridges(params, priv->db_uuid, new_bridges); + _insert_bridge(params, bridge, bridge_device, new_ports, bridge_cloned_mac); + } else { + /* Bridge already exists. */ + g_return_if_fail(ovs_bridge); + _expect_bridge_ports(params, ovs_bridge->name, ports); + _set_bridge_ports(params, bridge_name, new_ports); + if (bridge_cloned_mac && interface_is_internal) + _set_bridge_mac(params, bridge_name, bridge_cloned_mac); + } + + json_array_append_new(new_ports, json_pack("[s, s]", "named-uuid", "rowPort")); + _insert_port(params, port, new_interfaces); + } else { + /* Port already exists */ + g_return_if_fail(ovs_port); + _expect_port_interfaces(params, ovs_port->name, interfaces); + _set_port_interfaces(params, port_name, new_interfaces); + } + + if (!has_interface) { + _insert_interface(params, interface, interface_device, interface_cloned_mac); + json_array_append_new(new_interfaces, json_pack("[s, s]", "named-uuid", "rowInterface")); + } } /** @@ -731,104 +849,104 @@ _add_interface (NMOvsdb *self, json_t *params, * if last item is removed from them. */ static void -_delete_interface (NMOvsdb *self, json_t *params, const char *ifname) +_delete_interface(NMOvsdb *self, json_t *params, const char *ifname) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GHashTableIter iter; - char *bridge_uuid; - char *port_uuid; - char *interface_uuid; - OpenvswitchBridge *ovs_bridge; - OpenvswitchPort *ovs_port; - OpenvswitchInterface *ovs_interface; - nm_auto_decref_json json_t *bridges = NULL; - nm_auto_decref_json json_t *new_bridges = NULL; - gboolean bridges_changed; - gboolean ports_changed; - gboolean interfaces_changed; - int pi; - int ii; - - bridges = json_array (); - new_bridges = json_array (); - bridges_changed = FALSE; - - g_hash_table_iter_init (&iter, priv->bridges); - while (g_hash_table_iter_next (&iter, (gpointer) &bridge_uuid, (gpointer) &ovs_bridge)) { - nm_auto_decref_json json_t *ports = NULL; - nm_auto_decref_json json_t *new_ports = NULL; - - ports = json_array (); - new_ports = json_array (); - ports_changed = FALSE; - - json_array_append_new (bridges, json_pack ("[s,s]", "uuid", bridge_uuid)); - - for (pi = 0; pi < ovs_bridge->ports->len; pi++) { - nm_auto_decref_json json_t *interfaces = NULL; - nm_auto_decref_json json_t *new_interfaces = NULL; - - interfaces = json_array (); - new_interfaces = json_array (); - port_uuid = g_ptr_array_index (ovs_bridge->ports, pi); - ovs_port = g_hash_table_lookup (priv->ports, port_uuid); - - json_array_append_new (ports, json_pack ("[s,s]", "uuid", port_uuid)); - - interfaces_changed = FALSE; - - if (!ovs_port) { - /* This would be a violation of ovsdb's reference integrity (a bug). */ - _LOGW ("Unknown port '%s' in bridge '%s'", port_uuid, bridge_uuid); - continue; - } - - for (ii = 0; ii < ovs_port->interfaces->len; ii++) { - interface_uuid = g_ptr_array_index (ovs_port->interfaces, ii); - ovs_interface = g_hash_table_lookup (priv->interfaces, interface_uuid); - - json_array_append_new (interfaces, json_pack ("[s,s]", "uuid", interface_uuid)); - - if (ovs_interface) { - if (strcmp (ovs_interface->name, ifname) == 0) { - /* skip the interface */ - interfaces_changed = TRUE; - continue; - } - } else { - /* This would be a violation of ovsdb's reference integrity (a bug). */ - _LOGW ("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid); - } - - json_array_append_new (new_interfaces, json_pack ("[s,s]", "uuid", interface_uuid)); - } - - if (json_array_size (new_interfaces) == 0) { - ports_changed = TRUE; - } else { - if (interfaces_changed) { - _expect_port_interfaces (params, ovs_port->name, interfaces); - _set_port_interfaces (params, ovs_port->name, new_interfaces); - } - json_array_append_new (new_ports, json_pack ("[s,s]", "uuid", port_uuid)); - } - } - - if (json_array_size (new_ports) == 0) { - bridges_changed = TRUE; - } else { - if (ports_changed) { - _expect_bridge_ports (params, ovs_bridge->name, ports); - _set_bridge_ports (params, ovs_bridge->name, new_ports); - } - json_array_append_new (new_bridges, json_pack ("[s,s]", "uuid", bridge_uuid)); - } - } - - if (bridges_changed) { - _expect_ovs_bridges (params, priv->db_uuid, bridges); - _set_ovs_bridges (params, priv->db_uuid, new_bridges); - } + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + GHashTableIter iter; + char * bridge_uuid; + char * port_uuid; + char * interface_uuid; + OpenvswitchBridge * ovs_bridge; + OpenvswitchPort * ovs_port; + OpenvswitchInterface *ovs_interface; + nm_auto_decref_json json_t *bridges = NULL; + nm_auto_decref_json json_t *new_bridges = NULL; + gboolean bridges_changed; + gboolean ports_changed; + gboolean interfaces_changed; + int pi; + int ii; + + bridges = json_array(); + new_bridges = json_array(); + bridges_changed = FALSE; + + g_hash_table_iter_init(&iter, priv->bridges); + while (g_hash_table_iter_next(&iter, (gpointer) &bridge_uuid, (gpointer) &ovs_bridge)) { + nm_auto_decref_json json_t *ports = NULL; + nm_auto_decref_json json_t *new_ports = NULL; + + ports = json_array(); + new_ports = json_array(); + ports_changed = FALSE; + + json_array_append_new(bridges, json_pack("[s,s]", "uuid", bridge_uuid)); + + for (pi = 0; pi < ovs_bridge->ports->len; pi++) { + nm_auto_decref_json json_t *interfaces = NULL; + nm_auto_decref_json json_t *new_interfaces = NULL; + + interfaces = json_array(); + new_interfaces = json_array(); + port_uuid = g_ptr_array_index(ovs_bridge->ports, pi); + ovs_port = g_hash_table_lookup(priv->ports, port_uuid); + + json_array_append_new(ports, json_pack("[s,s]", "uuid", port_uuid)); + + interfaces_changed = FALSE; + + if (!ovs_port) { + /* This would be a violation of ovsdb's reference integrity (a bug). */ + _LOGW("Unknown port '%s' in bridge '%s'", port_uuid, bridge_uuid); + continue; + } + + for (ii = 0; ii < ovs_port->interfaces->len; ii++) { + interface_uuid = g_ptr_array_index(ovs_port->interfaces, ii); + ovs_interface = g_hash_table_lookup(priv->interfaces, interface_uuid); + + json_array_append_new(interfaces, json_pack("[s,s]", "uuid", interface_uuid)); + + if (ovs_interface) { + if (strcmp(ovs_interface->name, ifname) == 0) { + /* skip the interface */ + interfaces_changed = TRUE; + continue; + } + } else { + /* This would be a violation of ovsdb's reference integrity (a bug). */ + _LOGW("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid); + } + + json_array_append_new(new_interfaces, json_pack("[s,s]", "uuid", interface_uuid)); + } + + if (json_array_size(new_interfaces) == 0) { + ports_changed = TRUE; + } else { + if (interfaces_changed) { + _expect_port_interfaces(params, ovs_port->name, interfaces); + _set_port_interfaces(params, ovs_port->name, new_interfaces); + } + json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid)); + } + } + + if (json_array_size(new_ports) == 0) { + bridges_changed = TRUE; + } else { + if (ports_changed) { + _expect_bridge_ports(params, ovs_bridge->name, ports); + _set_bridge_ports(params, ovs_bridge->name, new_ports); + } + json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", bridge_uuid)); + } + } + + if (bridges_changed) { + _expect_ovs_bridges(params, priv->db_uuid, bridges); + _set_ovs_bridges(params, priv->db_uuid, new_bridges); + } } /** @@ -842,87 +960,111 @@ _delete_interface (NMOvsdb *self, json_t *params, const char *ifname) * include an up to date bridge list in their transactions to rule out races). */ static void -ovsdb_next_command (NMOvsdb *self) +ovsdb_next_command(NMOvsdb *self) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - OvsdbMethodCall *call = NULL; - char *cmd; - nm_auto_decref_json json_t *msg = NULL; - json_t *params; - - if (!priv->conn) - return; - if (!priv->calls->len) - return; - call = &g_array_index (priv->calls, OvsdbMethodCall, 0); - if (call->id != COMMAND_PENDING) - return; - call->id = priv->seq++; - - switch (call->command) { - case OVSDB_MONITOR: - msg = json_pack ("{s:i, s:s, s:[s, n, {" - " s:[{s:[s, s, s]}]," - " s:[{s:[s, s, s]}]," - " s:[{s:[s, s, s, s]}]," - " s:[{s:[]}]" - "}]}", - "id", call->id, - "method", "monitor", "params", "Open_vSwitch", - "Bridge", "columns", "name", "ports", "external_ids", - "Port", "columns", "name", "interfaces", "external_ids", - "Interface", "columns", "name", "type", "external_ids", "error", - "Open_vSwitch", "columns"); - break; - case OVSDB_ADD_INTERFACE: - params = json_array (); - json_array_append_new (params, json_string ("Open_vSwitch")); - json_array_append_new (params, _inc_next_cfg (priv->db_uuid)); - - _add_interface (self, params, call->bridge, call->port, call->interface, - call->bridge_device, call->interface_device); - - msg = json_pack ("{s:i, s:s, s:o}", - "id", call->id, - "method", "transact", "params", params); - break; - case OVSDB_DEL_INTERFACE: - params = json_array (); - json_array_append_new (params, json_string ("Open_vSwitch")); - json_array_append_new (params, _inc_next_cfg (priv->db_uuid)); - - _delete_interface (self, params, call->ifname); - - msg = json_pack ("{s:i, s:s, s:o}", - "id", call->id, - "method", "transact", "params", params); - break; - case OVSDB_SET_INTERFACE_MTU: - params = json_array (); - json_array_append_new (params, json_string ("Open_vSwitch")); - json_array_append_new (params, _inc_next_cfg (priv->db_uuid)); - - json_array_append_new (params, - json_pack ("{s:s, s:s, s:{s: i}, s:[[s, s, s]]}", - "op", "update", - "table", "Interface", - "row", "mtu_request", call->mtu, - "where", "name", "==", call->ifname)); - - msg = json_pack ("{s:i, s:s, s:o}", - "id", call->id, - "method", "transact", "params", params); - break; - } - - g_return_if_fail (msg); - _LOGT_call ("send", call, msg); - cmd = json_dumps (msg, 0); - - g_string_append (priv->output, cmd); - free (cmd); - - ovsdb_write (self); + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + OvsdbMethodCall * call = NULL; + char * cmd; + nm_auto_decref_json json_t *msg = NULL; + json_t * params; + + if (!priv->conn) + return; + if (!priv->calls->len) + return; + call = &g_array_index(priv->calls, OvsdbMethodCall, 0); + if (call->id != COMMAND_PENDING) + return; + call->id = priv->seq++; + + switch (call->command) { + case OVSDB_MONITOR: + msg = json_pack("{s:i, s:s, s:[s, n, {" + " s:[{s:[s, s, s]}]," + " s:[{s:[s, s, s]}]," + " s:[{s:[s, s, s, s]}]," + " s:[{s:[]}]" + "}]}", + "id", + call->id, + "method", + "monitor", + "params", + "Open_vSwitch", + "Bridge", + "columns", + "name", + "ports", + "external_ids", + "Port", + "columns", + "name", + "interfaces", + "external_ids", + "Interface", + "columns", + "name", + "type", + "external_ids", + "error", + "Open_vSwitch", + "columns"); + break; + case OVSDB_ADD_INTERFACE: + params = json_array(); + json_array_append_new(params, json_string("Open_vSwitch")); + json_array_append_new(params, _inc_next_cfg(priv->db_uuid)); + + _add_interface(self, + params, + call->bridge, + call->port, + call->interface, + call->bridge_device, + call->interface_device); + + msg = json_pack("{s:i, s:s, s:o}", "id", call->id, "method", "transact", "params", params); + break; + case OVSDB_DEL_INTERFACE: + params = json_array(); + json_array_append_new(params, json_string("Open_vSwitch")); + json_array_append_new(params, _inc_next_cfg(priv->db_uuid)); + + _delete_interface(self, params, call->ifname); + + msg = json_pack("{s:i, s:s, s:o}", "id", call->id, "method", "transact", "params", params); + break; + case OVSDB_SET_INTERFACE_MTU: + params = json_array(); + json_array_append_new(params, json_string("Open_vSwitch")); + json_array_append_new(params, _inc_next_cfg(priv->db_uuid)); + + json_array_append_new(params, + json_pack("{s:s, s:s, s:{s: i}, s:[[s, s, s]]}", + "op", + "update", + "table", + "Interface", + "row", + "mtu_request", + call->mtu, + "where", + "name", + "==", + call->ifname)); + + msg = json_pack("{s:i, s:s, s:o}", "id", call->id, "method", "transact", "params", params); + break; + } + + g_return_if_fail(msg); + _LOGT_call("send", call, msg); + cmd = json_dumps(msg, 0); + + g_string_append(priv->output, cmd); + free(cmd); + + ovsdb_write(self); } /** @@ -939,48 +1081,50 @@ ovsdb_next_command (NMOvsdb *self) * [ "uuid", "185c93f6-0b39-424e-8587-77d074aa7ce0" ], ... ] ] */ static void -_uuids_to_array (GPtrArray *array, const json_t *items) +_uuids_to_array(GPtrArray *array, const json_t *items) { - const char *key; - json_t *value; - size_t index = 0; - json_t *set_value; - size_t set_index; - - while (index < json_array_size (items)) { - key = json_string_value (json_array_get (items, index)); - index++; - value = json_array_get (items, index); - index++; - - if (!value) - return; - - if (g_strcmp0 (key, "uuid") == 0 && json_is_string (value)) { - g_ptr_array_add (array, g_strdup (json_string_value (value))); - } else if (g_strcmp0 (key, "set") == 0 && json_is_array (value)) { - json_array_foreach (value, set_index, set_value) { - _uuids_to_array (array, set_value); - } - } - } + const char *key; + json_t * value; + size_t index = 0; + json_t * set_value; + size_t set_index; + + while (index < json_array_size(items)) { + key = json_string_value(json_array_get(items, index)); + index++; + value = json_array_get(items, index); + index++; + + if (!value) + return; + + if (g_strcmp0(key, "uuid") == 0 && json_is_string(value)) { + g_ptr_array_add(array, g_strdup(json_string_value(value))); + } else if (g_strcmp0(key, "set") == 0 && json_is_array(value)) { + json_array_foreach(value, set_index, set_value) + { + _uuids_to_array(array, set_value); + } + } + } } static char * -_connection_uuid_from_external_ids (json_t *external_ids) +_connection_uuid_from_external_ids(json_t *external_ids) { - json_t *value; - size_t index; + json_t *value; + size_t index; - if (g_strcmp0 ("map", json_string_value (json_array_get (external_ids, 0))) != 0) - return NULL; + if (g_strcmp0("map", json_string_value(json_array_get(external_ids, 0))) != 0) + return NULL; - json_array_foreach (json_array_get (external_ids, 1), index, value) { - if (g_strcmp0 ("NM.connection.uuid", json_string_value (json_array_get (value, 0))) == 0) - return g_strdup (json_string_value (json_array_get (value, 1))); - } + json_array_foreach(json_array_get(external_ids, 1), index, value) + { + if (g_strcmp0("NM.connection.uuid", json_string_value(json_array_get(value, 0))) == 0) + return g_strdup(json_string_value(json_array_get(value, 1))); + } - return NULL; + return NULL; } /** @@ -991,205 +1135,266 @@ _connection_uuid_from_external_ids (json_t *external_ids) * whether the changes are done by us or externally. */ static void -ovsdb_got_update (NMOvsdb *self, json_t *msg) +ovsdb_got_update(NMOvsdb *self, json_t *msg) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - json_t *ovs = NULL; - json_t *bridge = NULL; - json_t *port = NULL; - json_t *interface = NULL; - json_t *items; - json_t *external_ids; - json_error_t json_error = { 0, }; - void *iter; - const char *name; - const char *key; - const char *type; - json_t *value; - OpenvswitchBridge *ovs_bridge; - OpenvswitchPort *ovs_port; - OpenvswitchInterface *ovs_interface; - - if (json_unpack_ex (msg, &json_error, 0, "{s?:o, s?:o, s?:o, s?:o}", - "Open_vSwitch", &ovs, - "Bridge", &bridge, - "Port", &port, - "Interface", &interface) == -1) { - /* This doesn't really have to be an error; the key might - * be missing if there really are no bridges present. */ - _LOGD ("Bad update: %s", json_error.text); - } - - if (ovs) { - iter = json_object_iter (ovs); - priv->db_uuid = iter ? g_strdup (json_object_iter_key (iter)) : NULL; - } - - /* Interfaces */ - json_object_foreach (interface, key, value) { - json_t *error = NULL; - gboolean old = FALSE; - gboolean new = FALSE; - - if (json_unpack (value, "{s:{}}", "old") == 0) - old = TRUE; - - if (json_unpack (value, "{s:{s:s, s:s, s?:o, s:o}}", "new", - "name", &name, - "type", &type, - "error", &error, - "external_ids", &external_ids) == 0) - new = TRUE; - - if (old) { - ovs_interface = g_hash_table_lookup (priv->interfaces, key); - if (!ovs_interface) { - _LOGW ("Interface '%s' was not seen", key); - } else if (!new || strcmp (ovs_interface->name, name) != 0) { - old = FALSE; - _LOGT ("removed an '%s' interface: %s%s%s", - ovs_interface->type, ovs_interface->name, - ovs_interface->connection_uuid ? ", " : "", - ovs_interface->connection_uuid ?: ""); - if (g_strcmp0 (ovs_interface->type, "internal") == 0) { - /* Currently the factory only creates NMDevices for - * internal interfaces. Ignore the rest. */ - g_signal_emit (self, signals[DEVICE_REMOVED], 0, - ovs_interface->name, NM_DEVICE_TYPE_OVS_INTERFACE); - } - } - g_hash_table_remove (priv->interfaces, key); - } - - if (new) { - ovs_interface = g_slice_new (OpenvswitchInterface); - ovs_interface->name = g_strdup (name); - ovs_interface->type = g_strdup (type); - ovs_interface->connection_uuid = _connection_uuid_from_external_ids (external_ids); - g_hash_table_insert (priv->interfaces, g_strdup (key), ovs_interface); - if (old) { - _LOGT ("changed an '%s' interface: %s%s%s", type, ovs_interface->name, - ovs_interface->connection_uuid ? ", " : "", - ovs_interface->connection_uuid ?: ""); - } else { - _LOGT ("added an '%s' interface: %s%s%s", - ovs_interface->type, ovs_interface->name, - ovs_interface->connection_uuid ? ", " : "", - ovs_interface->connection_uuid ?: ""); - if (g_strcmp0 (ovs_interface->type, "internal") == 0) { - /* Currently the factory only creates NMDevices for - * internal interfaces. Ignore the rest. */ - g_signal_emit (self, signals[DEVICE_ADDED], 0, - ovs_interface->name, NM_DEVICE_TYPE_OVS_INTERFACE); - } - } - /* The error is a string. No error is indicated by an empty set, - * because why the fuck not: [ "set": [] ] */ - if (error && json_is_string (error)) { - g_signal_emit (self, signals[INTERFACE_FAILED], 0, - ovs_interface->name, - ovs_interface->connection_uuid, - json_string_value (error)); - } - } - } - - /* Ports */ - json_object_foreach (port, key, value) { - gboolean old = FALSE; - gboolean new = FALSE; - - if (json_unpack (value, "{s:{}}", "old") == 0) - old = TRUE; - - if (json_unpack (value, "{s:{s:s, s:o, s:o}}", "new", - "name", &name, - "external_ids", &external_ids, - "interfaces", &items) == 0) - new = TRUE; - - if (old) { - ovs_port = g_hash_table_lookup (priv->ports, key); - if (!new || g_strcmp0 (ovs_port->name, name) != 0) { - old = FALSE; - _LOGT ("removed a port: %s%s%s", ovs_port->name, - ovs_port->connection_uuid ? ", " : "", - ovs_port->connection_uuid ?: ""); - g_signal_emit (self, signals[DEVICE_REMOVED], 0, - ovs_port->name, NM_DEVICE_TYPE_OVS_PORT); - } - g_hash_table_remove (priv->ports, key); - } - - if (new) { - ovs_port = g_slice_new (OpenvswitchPort); - ovs_port->name = g_strdup (name); - ovs_port->connection_uuid = _connection_uuid_from_external_ids (external_ids); - ovs_port->interfaces = g_ptr_array_new_with_free_func (g_free); - _uuids_to_array (ovs_port->interfaces, items); - g_hash_table_insert (priv->ports, g_strdup (key), ovs_port); - if (old) { - _LOGT ("changed a port: %s%s%s", ovs_port->name, - ovs_port->connection_uuid ? ", " : "", - ovs_port->connection_uuid ?: ""); - } else { - _LOGT ("added a port: %s%s%s", ovs_port->name, - ovs_port->connection_uuid ? ", " : "", - ovs_port->connection_uuid ?: ""); - g_signal_emit (self, signals[DEVICE_ADDED], 0, - ovs_port->name, NM_DEVICE_TYPE_OVS_PORT); - } - } - } - - /* Bridges */ - json_object_foreach (bridge, key, value) { - gboolean old = FALSE; - gboolean new = FALSE; - - if (json_unpack (value, "{s:{}}", "old") == 0) - old = TRUE; - - if (json_unpack (value, "{s:{s:s, s:o, s:o}}", "new", - "name", &name, - "external_ids", &external_ids, - "ports", &items) == 0) - new = TRUE; - - if (old) { - ovs_bridge = g_hash_table_lookup (priv->bridges, key); - if (!new || g_strcmp0 (ovs_bridge->name, name) != 0) { - old = FALSE; - _LOGT ("removed a bridge: %s%s%s", ovs_bridge->name, - ovs_bridge->connection_uuid ? ", " : "", - ovs_bridge->connection_uuid ?: ""); - g_signal_emit (self, signals[DEVICE_REMOVED], 0, - ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE); - } - g_hash_table_remove (priv->bridges, key); - } - - if (new) { - ovs_bridge = g_slice_new (OpenvswitchBridge); - ovs_bridge->name = g_strdup (name); - ovs_bridge->connection_uuid = _connection_uuid_from_external_ids (external_ids); - ovs_bridge->ports = g_ptr_array_new_with_free_func (g_free); - _uuids_to_array (ovs_bridge->ports, items); - g_hash_table_insert (priv->bridges, g_strdup (key), ovs_bridge); - if (old) { - _LOGT ("changed a bridge: %s%s%s", ovs_bridge->name, - ovs_bridge->connection_uuid ? ", " : "", - ovs_bridge->connection_uuid ?: ""); - } else { - _LOGT ("added a bridge: %s%s%s", ovs_bridge->name, - ovs_bridge->connection_uuid ? ", " : "", - ovs_bridge->connection_uuid ?: ""); - g_signal_emit (self, signals[DEVICE_ADDED], 0, - ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE); - } - } - } - + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + json_t * ovs = NULL; + json_t * bridge = NULL; + json_t * port = NULL; + json_t * interface = NULL; + json_t * items; + json_t * external_ids; + json_error_t json_error = { + 0, + }; + void * iter; + const char * name; + const char * key; + const char * type; + json_t * value; + OpenvswitchBridge * ovs_bridge; + OpenvswitchPort * ovs_port; + OpenvswitchInterface *ovs_interface; + + if (json_unpack_ex(msg, + &json_error, + 0, + "{s?:o, s?:o, s?:o, s?:o}", + "Open_vSwitch", + &ovs, + "Bridge", + &bridge, + "Port", + &port, + "Interface", + &interface) + == -1) { + /* This doesn't really have to be an error; the key might + * be missing if there really are no bridges present. */ + _LOGD("Bad update: %s", json_error.text); + } + + if (ovs) { + iter = json_object_iter(ovs); + priv->db_uuid = iter ? g_strdup(json_object_iter_key(iter)) : NULL; + } + + /* Interfaces */ + json_object_foreach(interface, key, value) + { + json_t * error = NULL; + gboolean old = FALSE; + gboolean new = FALSE; + + if (json_unpack(value, "{s:{}}", "old") == 0) + old = TRUE; + + if (json_unpack(value, + "{s:{s:s, s:s, s?:o, s:o}}", + "new", + "name", + &name, + "type", + &type, + "error", + &error, + "external_ids", + &external_ids) + == 0) + new = TRUE; + + if (old) { + ovs_interface = g_hash_table_lookup(priv->interfaces, key); + if (!ovs_interface) { + _LOGW("Interface '%s' was not seen", key); + } else if (!new || strcmp(ovs_interface->name, name) != 0) { + old = FALSE; + _LOGT("removed an '%s' interface: %s%s%s", + ovs_interface->type, + ovs_interface->name, + ovs_interface->connection_uuid ? ", " : "", + ovs_interface->connection_uuid ?: ""); + if (g_strcmp0(ovs_interface->type, "internal") == 0) { + /* Currently, the factory only creates NMDevices for + * internal interfaces. Ignore the rest. */ + g_signal_emit(self, + signals[DEVICE_REMOVED], + 0, + ovs_interface->name, + NM_DEVICE_TYPE_OVS_INTERFACE); + } + } + g_hash_table_remove(priv->interfaces, key); + } + + if (new) { + ovs_interface = g_slice_new(OpenvswitchInterface); + ovs_interface->name = g_strdup(name); + ovs_interface->type = g_strdup(type); + ovs_interface->connection_uuid = _connection_uuid_from_external_ids(external_ids); + g_hash_table_insert(priv->interfaces, g_strdup(key), ovs_interface); + if (old) { + _LOGT("changed an '%s' interface: %s%s%s", + type, + ovs_interface->name, + ovs_interface->connection_uuid ? ", " : "", + ovs_interface->connection_uuid ?: ""); + } else { + _LOGT("added an '%s' interface: %s%s%s", + ovs_interface->type, + ovs_interface->name, + ovs_interface->connection_uuid ? ", " : "", + ovs_interface->connection_uuid ?: ""); + if (g_strcmp0(ovs_interface->type, "internal") == 0) { + /* Currently, the factory only creates NMDevices for + * internal interfaces. Ignore the rest. */ + g_signal_emit(self, + signals[DEVICE_ADDED], + 0, + ovs_interface->name, + NM_DEVICE_TYPE_OVS_INTERFACE); + } + } + /* The error is a string. No error is indicated by an empty set, + * because why the fuck not: [ "set": [] ] */ + if (error && json_is_string(error)) { + g_signal_emit(self, + signals[INTERFACE_FAILED], + 0, + ovs_interface->name, + ovs_interface->connection_uuid, + json_string_value(error)); + } + } + } + + /* Ports */ + json_object_foreach(port, key, value) + { + gboolean old = FALSE; + gboolean new = FALSE; + + if (json_unpack(value, "{s:{}}", "old") == 0) + old = TRUE; + + if (json_unpack(value, + "{s:{s:s, s:o, s:o}}", + "new", + "name", + &name, + "external_ids", + &external_ids, + "interfaces", + &items) + == 0) + new = TRUE; + + if (old) { + ovs_port = g_hash_table_lookup(priv->ports, key); + if (!new || g_strcmp0(ovs_port->name, name) != 0) { + old = FALSE; + _LOGT("removed a port: %s%s%s", + ovs_port->name, + ovs_port->connection_uuid ? ", " : "", + ovs_port->connection_uuid ?: ""); + g_signal_emit(self, + signals[DEVICE_REMOVED], + 0, + ovs_port->name, + NM_DEVICE_TYPE_OVS_PORT); + } + g_hash_table_remove(priv->ports, key); + } + + if (new) { + ovs_port = g_slice_new(OpenvswitchPort); + ovs_port->name = g_strdup(name); + ovs_port->connection_uuid = _connection_uuid_from_external_ids(external_ids); + ovs_port->interfaces = g_ptr_array_new_with_free_func(g_free); + _uuids_to_array(ovs_port->interfaces, items); + g_hash_table_insert(priv->ports, g_strdup(key), ovs_port); + if (old) { + _LOGT("changed a port: %s%s%s", + ovs_port->name, + ovs_port->connection_uuid ? ", " : "", + ovs_port->connection_uuid ?: ""); + } else { + _LOGT("added a port: %s%s%s", + ovs_port->name, + ovs_port->connection_uuid ? ", " : "", + ovs_port->connection_uuid ?: ""); + g_signal_emit(self, + signals[DEVICE_ADDED], + 0, + ovs_port->name, + NM_DEVICE_TYPE_OVS_PORT); + } + } + } + + /* Bridges */ + json_object_foreach(bridge, key, value) + { + gboolean old = FALSE; + gboolean new = FALSE; + + if (json_unpack(value, "{s:{}}", "old") == 0) + old = TRUE; + + if (json_unpack(value, + "{s:{s:s, s:o, s:o}}", + "new", + "name", + &name, + "external_ids", + &external_ids, + "ports", + &items) + == 0) + new = TRUE; + + if (old) { + ovs_bridge = g_hash_table_lookup(priv->bridges, key); + if (!new || g_strcmp0(ovs_bridge->name, name) != 0) { + old = FALSE; + _LOGT("removed a bridge: %s%s%s", + ovs_bridge->name, + ovs_bridge->connection_uuid ? ", " : "", + ovs_bridge->connection_uuid ?: ""); + g_signal_emit(self, + signals[DEVICE_REMOVED], + 0, + ovs_bridge->name, + NM_DEVICE_TYPE_OVS_BRIDGE); + } + g_hash_table_remove(priv->bridges, key); + } + + if (new) { + ovs_bridge = g_slice_new(OpenvswitchBridge); + ovs_bridge->name = g_strdup(name); + ovs_bridge->connection_uuid = _connection_uuid_from_external_ids(external_ids); + ovs_bridge->ports = g_ptr_array_new_with_free_func(g_free); + _uuids_to_array(ovs_bridge->ports, items); + g_hash_table_insert(priv->bridges, g_strdup(key), ovs_bridge); + if (old) { + _LOGT("changed a bridge: %s%s%s", + ovs_bridge->name, + ovs_bridge->connection_uuid ? ", " : "", + ovs_bridge->connection_uuid ?: ""); + } else { + _LOGT("added a bridge: %s%s%s", + ovs_bridge->name, + ovs_bridge->connection_uuid ? ", " : "", + ovs_bridge->connection_uuid ?: ""); + g_signal_emit(self, + signals[DEVICE_ADDED], + 0, + ovs_bridge->name, + NM_DEVICE_TYPE_OVS_BRIDGE); + } + } + } } /** @@ -1199,123 +1404,138 @@ ovsdb_got_update (NMOvsdb *self, json_t *msg) * seen doing this. */ static void -ovsdb_got_echo (NMOvsdb *self, json_int_t id, json_t *data) +ovsdb_got_echo(NMOvsdb *self, json_int_t id, json_t *data) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - nm_auto_decref_json json_t *msg = NULL; - char *reply; - gboolean output_was_empty; + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + nm_auto_decref_json json_t *msg = NULL; + char * reply; + gboolean output_was_empty; - output_was_empty = priv->output->len == 0; + output_was_empty = priv->output->len == 0; - msg = json_pack ("{s:I, s:O}", "id", id, "result", data); - reply = json_dumps (msg, 0); - g_string_append (priv->output, reply); - free (reply); + msg = json_pack("{s:I, s:O}", "id", id, "result", data); + reply = json_dumps(msg, 0); + g_string_append(priv->output, reply); + free(reply); - if (output_was_empty) - ovsdb_write (self); + if (output_was_empty) + ovsdb_write(self); } /** * ovsdb_got_msg:: * - * Called when when a complete JSON object was seen and unmarshalled. + * Called when a complete JSON object was seen and unmarshalled. * Either finishes a method call or processes a method call. */ static void -ovsdb_got_msg (NMOvsdb *self, json_t *msg) +ovsdb_got_msg(NMOvsdb *self, json_t *msg) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - json_error_t json_error = { 0, }; - json_t *json_id = NULL; - gint64 id = -1; - const char *method = NULL; - json_t *params = NULL; - json_t *result = NULL; - json_t *error = NULL; - OvsdbMethodCall *call = NULL; - OvsdbMethodCallback callback; - gpointer user_data; - gs_free_error GError *local = NULL; - - if (json_unpack_ex (msg, &json_error, 0, "{s?:o, s?:s, s?:o, s?:o, s?:o}", - "id", &json_id, - "method", &method, - "params", ¶ms, - "result", &result, - "error", &error) == -1) { - _LOGW ("couldn't grok the message: %s", json_error.text); - ovsdb_disconnect (self, FALSE, FALSE); - return; - } - - if (json_is_number (json_id)) - id = json_integer_value (json_id); - - if (method) { - /* It's a method call! */ - if (!params) { - _LOGW ("a method call with no params: '%s'", method); - ovsdb_disconnect (self, FALSE, FALSE); - return; - } - - if (g_strcmp0 (method, "update") == 0) { - /* This is a update method call. */ - ovsdb_got_update (self, json_array_get (params, 1)); - } else if (g_strcmp0 (method, "echo") == 0) { - /* This is an echo request. */ - ovsdb_got_echo (self, id, params); - } else { - _LOGW ("got an unknown method call: '%s'", method); - } - return; - } - - if (id > -1) { - /* This is a response to a method call. */ - if (!priv->calls->len) { - _LOGE ("there are no queued calls expecting response %" G_GUINT64_FORMAT, id); - ovsdb_disconnect (self, FALSE, FALSE); - return; - } - call = &g_array_index (priv->calls, OvsdbMethodCall, 0); - if (call->id != id) { - _LOGE ("expected a response to call %" G_GUINT64_FORMAT ", not %" G_GUINT64_FORMAT, call->id, id); - ovsdb_disconnect (self, FALSE, FALSE); - return; - } - /* Cool, we found a corresponding call. Finish it. */ - - _LOGT_call ("response", call, msg); - - if (!json_is_null (error)) { - /* The response contains an error. */ - g_set_error (&local, G_IO_ERROR, G_IO_ERROR_FAILED, - "Error call to OVSDB returned an error: %s", - json_string_value (error)); - } - - callback = call->callback; - user_data = call->user_data; - g_array_remove_index (priv->calls, 0); - callback (self, result, local, user_data); - priv->num_failures = 0; - - /* Don't progress further commands in case the callback hit an error - * and disconnected us. */ - if (!priv->conn) - return; - - /* Now we're free to serialize and send the next command, if any. */ - ovsdb_next_command (self); - - return; - } - - /* This is a message we are not interested in. */ - _LOGW ("got an unknown message, ignoring"); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + json_error_t json_error = { + 0, + }; + json_t * json_id = NULL; + gint64 id = -1; + const char * method = NULL; + json_t * params = NULL; + json_t * result = NULL; + json_t * error = NULL; + OvsdbMethodCall * call = NULL; + OvsdbMethodCallback callback; + gpointer user_data; + gs_free_error GError *local = NULL; + + if (json_unpack_ex(msg, + &json_error, + 0, + "{s?:o, s?:s, s?:o, s?:o, s?:o}", + "id", + &json_id, + "method", + &method, + "params", + ¶ms, + "result", + &result, + "error", + &error) + == -1) { + _LOGW("couldn't grok the message: %s", json_error.text); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + + if (json_is_number(json_id)) + id = json_integer_value(json_id); + + if (method) { + /* It's a method call! */ + if (!params) { + _LOGW("a method call with no params: '%s'", method); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + + if (g_strcmp0(method, "update") == 0) { + /* This is a update method call. */ + ovsdb_got_update(self, json_array_get(params, 1)); + } else if (g_strcmp0(method, "echo") == 0) { + /* This is an echo request. */ + ovsdb_got_echo(self, id, params); + } else { + _LOGW("got an unknown method call: '%s'", method); + } + return; + } + + if (id > -1) { + /* This is a response to a method call. */ + if (!priv->calls->len) { + _LOGE("there are no queued calls expecting response %" G_GUINT64_FORMAT, id); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + call = &g_array_index(priv->calls, OvsdbMethodCall, 0); + if (call->id != id) { + _LOGE("expected a response to call %" G_GUINT64_FORMAT ", not %" G_GUINT64_FORMAT, + call->id, + id); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + /* Cool, we found a corresponding call. Finish it. */ + + _LOGT_call("response", call, msg); + + if (!json_is_null(error)) { + /* The response contains an error. */ + g_set_error(&local, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Error call to OVSDB returned an error: %s", + json_string_value(error)); + } + + callback = call->callback; + user_data = call->user_data; + g_array_remove_index(priv->calls, 0); + callback(self, result, local, user_data); + priv->num_failures = 0; + + /* Don't progress further commands in case the callback hit an error + * and disconnected us. */ + if (!priv->conn) + return; + + /* Now we're free to serialize and send the next command, if any. */ + ovsdb_next_command(self); + + return; + } + + /* This is a message we are not interested in. */ + _LOGW("got an unknown message, ignoring"); } /*****************************************************************************/ @@ -1324,21 +1544,21 @@ ovsdb_got_msg (NMOvsdb *self, json_t *msg) * ovsdb socket. */ static size_t -_json_callback (void *buffer, size_t buflen, void *user_data) +_json_callback(void *buffer, size_t buflen, void *user_data) { - NMOvsdb *self = NM_OVSDB (user_data); - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); + NMOvsdb * self = NM_OVSDB(user_data); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); - if (priv->bufp == priv->input->len) { - /* No more bytes buffered for decoding. */ - return 0; - } + if (priv->bufp == priv->input->len) { + /* No more bytes buffered for decoding. */ + return 0; + } - /* Pass one more byte to the JSON decoder. */ - *(char *)buffer = priv->input->str[priv->bufp]; - priv->bufp++; + /* Pass one more byte to the JSON decoder. */ + *(char *) buffer = priv->input->str[priv->bufp]; + priv->bufp++; - return (size_t)1; + return (size_t) 1; } /** @@ -1348,100 +1568,110 @@ _json_callback (void *buffer, size_t buflen, void *user_data) * the JSON. If we see a complete object, pass it upwards to ovsdb_got_msg(). */ static void -ovsdb_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +ovsdb_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMOvsdb *self = NM_OVSDB (user_data); - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GInputStream *stream = G_INPUT_STREAM (source_object); - GError *error = NULL; - gssize size; - json_t *msg; - json_error_t json_error = { 0, }; - - size = g_input_stream_read_finish (stream, res, &error); - if (size == -1) { - /* ovsdb-server was possibly restarted */ - _LOGW ("short read from ovsdb: %s", error->message); - priv->num_failures++; - g_clear_error (&error); - ovsdb_disconnect (self, priv->num_failures <= OVSDB_MAX_FAILURES, FALSE); - return; - } - - g_string_append_len (priv->input, priv->buf, size); - do { - priv->bufp = 0; - /* The callback always eats up only up to a single byte. This makes - * it possible for us to identify complete JSON objects in spite of - * us not knowing the length in advance. */ - msg = json_load_callback (_json_callback, self, JSON_DISABLE_EOF_CHECK, &json_error); - if (msg) { - ovsdb_got_msg (self, msg); - g_string_erase (priv->input, 0, priv->bufp); - } - json_decref (msg); - } while (msg); - - if (!priv->conn) - return; - - if (size) - ovsdb_read (self); + NMOvsdb * self = NM_OVSDB(user_data); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + GInputStream * stream = G_INPUT_STREAM(source_object); + GError * error = NULL; + gssize size; + json_t * msg; + json_error_t json_error = { + 0, + }; + + size = g_input_stream_read_finish(stream, res, &error); + if (size == -1) { + /* ovsdb-server was possibly restarted */ + _LOGW("short read from ovsdb: %s", error->message); + priv->num_failures++; + g_clear_error(&error); + ovsdb_disconnect(self, priv->num_failures <= OVSDB_MAX_FAILURES, FALSE); + return; + } + + g_string_append_len(priv->input, priv->buf, size); + do { + priv->bufp = 0; + /* The callback always eats up only up to a single byte. This makes + * it possible for us to identify complete JSON objects in spite of + * us not knowing the length in advance. */ + msg = json_load_callback(_json_callback, self, JSON_DISABLE_EOF_CHECK, &json_error); + if (msg) { + ovsdb_got_msg(self, msg); + g_string_erase(priv->input, 0, priv->bufp); + } + json_decref(msg); + } while (msg); + + if (!priv->conn) + return; + + if (size) + ovsdb_read(self); } static void -ovsdb_read (NMOvsdb *self) +ovsdb_read(NMOvsdb *self) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - - g_input_stream_read_async (g_io_stream_get_input_stream (G_IO_STREAM (priv->conn)), - priv->buf, sizeof(priv->buf), - G_PRIORITY_DEFAULT, NULL, ovsdb_read_cb, self); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + + g_input_stream_read_async(g_io_stream_get_input_stream(G_IO_STREAM(priv->conn)), + priv->buf, + sizeof(priv->buf), + G_PRIORITY_DEFAULT, + NULL, + ovsdb_read_cb, + self); } static void -ovsdb_write_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +ovsdb_write_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - GOutputStream *stream = G_OUTPUT_STREAM (source_object); - NMOvsdb *self = NM_OVSDB (user_data); - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GError *error = NULL; - gssize size; - - size = g_output_stream_write_finish (stream, res, &error); - if (size == -1) { - /* ovsdb-server was possibly restarted */ - _LOGW ("short write to ovsdb: %s", error->message); - priv->num_failures++; - g_clear_error (&error); - ovsdb_disconnect (self, priv->num_failures <= OVSDB_MAX_FAILURES, FALSE); - return; - } - - if (!priv->conn) - return; - - g_string_erase (priv->output, 0, size); - - ovsdb_write (self); + GOutputStream * stream = G_OUTPUT_STREAM(source_object); + NMOvsdb * self = NM_OVSDB(user_data); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + GError * error = NULL; + gssize size; + + size = g_output_stream_write_finish(stream, res, &error); + if (size == -1) { + /* ovsdb-server was possibly restarted */ + _LOGW("short write to ovsdb: %s", error->message); + priv->num_failures++; + g_clear_error(&error); + ovsdb_disconnect(self, priv->num_failures <= OVSDB_MAX_FAILURES, FALSE); + return; + } + + if (!priv->conn) + return; + + g_string_erase(priv->output, 0, size); + + ovsdb_write(self); } static void -ovsdb_write (NMOvsdb *self) +ovsdb_write(NMOvsdb *self) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GOutputStream *stream; - - if (!priv->output->len) - return; - - stream = g_io_stream_get_output_stream (G_IO_STREAM (priv->conn)); - if (g_output_stream_has_pending (stream)) - return; - - g_output_stream_write_async (stream, - priv->output->str, priv->output->len, - G_PRIORITY_DEFAULT, NULL, ovsdb_write_cb, self); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + GOutputStream * stream; + + if (!priv->output->len) + return; + + stream = g_io_stream_get_output_stream(G_IO_STREAM(priv->conn)); + if (g_output_stream_has_pending(stream)) + return; + + g_output_stream_write_async(stream, + priv->output->str, + priv->output->len, + G_PRIORITY_DEFAULT, + NULL, + ovsdb_write_cb, + self); } /*****************************************************************************/ @@ -1457,89 +1687,89 @@ ovsdb_write (NMOvsdb *self) * puts us back in sync. */ static void -ovsdb_disconnect (NMOvsdb *self, gboolean retry, gboolean is_disposing) +ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - OvsdbMethodCall *call; - OvsdbMethodCallback callback; - gpointer user_data; - gs_free_error GError *error = NULL; - - nm_assert (!retry || !is_disposing); - - if (!priv->client) - return; - - _LOGD ("disconnecting from ovsdb, retry %d", retry); - - if (retry) { - if (priv->calls->len != 0) - g_array_index (priv->calls, OvsdbMethodCall, 0).id = COMMAND_PENDING; - } else { - nm_utils_error_set_cancelled (&error, is_disposing, "NMOvsdb"); - - while (priv->calls->len) { - call = &g_array_index (priv->calls, OvsdbMethodCall, priv->calls->len - 1); - callback = call->callback; - user_data = call->user_data; - g_array_remove_index (priv->calls, priv->calls->len - 1); - callback (self, NULL, error, user_data); - } - } - - priv->bufp = 0; - g_string_truncate (priv->input, 0); - g_string_truncate (priv->output, 0); - g_clear_object (&priv->client); - g_clear_object (&priv->conn); - nm_clear_g_free (&priv->db_uuid); - nm_clear_g_cancellable (&priv->cancellable); - - if (retry) - ovsdb_try_connect (self); + NMOvsdbPrivate * priv = NM_OVSDB_GET_PRIVATE(self); + OvsdbMethodCall * call; + OvsdbMethodCallback callback; + gpointer user_data; + gs_free_error GError *error = NULL; + + nm_assert(!retry || !is_disposing); + + if (!priv->client) + return; + + _LOGD("disconnecting from ovsdb, retry %d", retry); + + if (retry) { + if (priv->calls->len != 0) + g_array_index(priv->calls, OvsdbMethodCall, 0).id = COMMAND_PENDING; + } else { + nm_utils_error_set_cancelled(&error, is_disposing, "NMOvsdb"); + + while (priv->calls->len) { + call = &g_array_index(priv->calls, OvsdbMethodCall, priv->calls->len - 1); + callback = call->callback; + user_data = call->user_data; + g_array_remove_index(priv->calls, priv->calls->len - 1); + callback(self, NULL, error, user_data); + } + } + + priv->bufp = 0; + g_string_truncate(priv->input, 0); + g_string_truncate(priv->output, 0); + g_clear_object(&priv->client); + g_clear_object(&priv->conn); + nm_clear_g_free(&priv->db_uuid); + nm_clear_g_cancellable(&priv->cancellable); + + if (retry) + ovsdb_try_connect(self); } static void -_monitor_bridges_cb (NMOvsdb *self, json_t *result, GError *error, gpointer user_data) +_monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_data) { - if (error) { - if (!nm_utils_error_is_cancelled_or_disposing (error)) { - _LOGI ("%s", error->message); - ovsdb_disconnect (self, FALSE, FALSE); - } - return; - } - - /* Treat the first response the same as the subsequent "update" - * messages we eventually get. */ - ovsdb_got_update (self, result); + if (error) { + if (!nm_utils_error_is_cancelled_or_disposing(error)) { + _LOGI("%s", error->message); + ovsdb_disconnect(self, FALSE, FALSE); + } + return; + } + + /* Treat the first response the same as the subsequent "update" + * messages we eventually get. */ + ovsdb_got_update(self, result); } static void -_client_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +_client_connect_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - GSocketClient *client = G_SOCKET_CLIENT (source_object); - NMOvsdb *self = NM_OVSDB (user_data); - NMOvsdbPrivate *priv; - GError *error = NULL; - GSocketConnection *conn; - - conn = g_socket_client_connect_finish (client, res, &error); - if (conn == NULL) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - _LOGI ("%s", error->message); - - ovsdb_disconnect (self, FALSE, FALSE); - g_clear_error (&error); - return; - } - - priv = NM_OVSDB_GET_PRIVATE (self); - priv->conn = conn; - g_clear_object (&priv->cancellable); - - ovsdb_read (self); - ovsdb_next_command (self); + GSocketClient * client = G_SOCKET_CLIENT(source_object); + NMOvsdb * self = NM_OVSDB(user_data); + NMOvsdbPrivate * priv; + GError * error = NULL; + GSocketConnection *conn; + + conn = g_socket_client_connect_finish(client, res, &error); + if (conn == NULL) { + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + _LOGI("%s", error->message); + + ovsdb_disconnect(self, FALSE, FALSE); + g_clear_error(&error); + return; + } + + priv = NM_OVSDB_GET_PRIVATE(self); + priv->conn = conn; + g_clear_object(&priv->cancellable); + + ovsdb_read(self); + ovsdb_next_command(self); } /** @@ -1550,28 +1780,40 @@ _client_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat * sync when other commands are issued. */ static void -ovsdb_try_connect (NMOvsdb *self) +ovsdb_try_connect(NMOvsdb *self) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - GSocketAddress *addr; - - if (priv->client) - return; - - /* XXX: This should probably be made configurable via NetworkManager.conf */ - addr = g_unix_socket_address_new (RUNSTATEDIR "/openvswitch/db.sock"); - - priv->client = g_socket_client_new (); - priv->cancellable = g_cancellable_new (); - g_socket_client_connect_async (priv->client, G_SOCKET_CONNECTABLE (addr), - priv->cancellable, _client_connect_cb, self); - g_object_unref (addr); - - /* Queue a monitor call before any other command, ensuring that we have an up - * to date view of existing bridged that we need for add and remove ops. */ - ovsdb_call_method (self, OVSDB_MONITOR, NULL, - NULL, NULL, NULL, NULL, NULL, 0, - _monitor_bridges_cb, NULL, TRUE); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + GSocketAddress *addr; + + if (priv->client) + return; + + /* TODO: This should probably be made configurable via NetworkManager.conf */ + addr = g_unix_socket_address_new(RUNSTATEDIR "/openvswitch/db.sock"); + + priv->client = g_socket_client_new(); + priv->cancellable = g_cancellable_new(); + g_socket_client_connect_async(priv->client, + G_SOCKET_CONNECTABLE(addr), + priv->cancellable, + _client_connect_cb, + self); + g_object_unref(addr); + + /* Queue a monitor call before any other command, ensuring that we have an up + * to date view of existing bridged that we need for add and remove ops. */ + ovsdb_call_method(self, + OVSDB_MONITOR, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + _monitor_bridges_cb, + NULL, + TRUE); } /*****************************************************************************/ @@ -1580,209 +1822,259 @@ ovsdb_try_connect (NMOvsdb *self) * their ovsdb entries without having to deal with ovsdb complexities themselves. */ typedef struct { - NMOvsdbCallback callback; - gpointer user_data; + NMOvsdbCallback callback; + gpointer user_data; } OvsdbCall; static void -_transact_cb (NMOvsdb *self, json_t *result, GError *error, gpointer user_data) +_transact_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_data) { - OvsdbCall *call = user_data; - const char *err; - const char *err_details; - size_t index; - json_t *value; - - if (error) - goto out; - - json_array_foreach (result, index, value) { - if (json_unpack (value, "{s:s, s:s}", "error", &err, "details", &err_details) == 0) { - g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Error running the transaction: %s: %s", err, err_details); - goto out; - } - } + OvsdbCall * call = user_data; + const char *err; + const char *err_details; + size_t index; + json_t * value; + + if (error) + goto out; + + json_array_foreach(result, index, value) + { + if (json_unpack(value, "{s:s, s:s}", "error", &err, "details", &err_details) == 0) { + g_set_error(&error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Error running the transaction: %s: %s", + err, + err_details); + goto out; + } + } out: - call->callback (error, call->user_data); - g_slice_free (OvsdbCall, call); + call->callback(error, call->user_data); + g_slice_free(OvsdbCall, call); } static OvsdbCall * -ovsdb_call_new (NMOvsdbCallback callback, gpointer user_data) +ovsdb_call_new(NMOvsdbCallback callback, gpointer user_data) { - OvsdbCall *call; + OvsdbCall *call; - call = g_slice_new (OvsdbCall); - call->callback = callback; - call->user_data = user_data; + call = g_slice_new(OvsdbCall); + call->callback = callback; + call->user_data = user_data; - return call; + return call; } void -nm_ovsdb_add_interface (NMOvsdb *self, - NMConnection *bridge, NMConnection *port, NMConnection *interface, - NMDevice *bridge_device, NMDevice *interface_device, - NMOvsdbCallback callback, gpointer user_data) +nm_ovsdb_add_interface(NMOvsdb * self, + NMConnection * bridge, + NMConnection * port, + NMConnection * interface, + NMDevice * bridge_device, + NMDevice * interface_device, + NMOvsdbCallback callback, + gpointer user_data) { - ovsdb_call_method (self, OVSDB_ADD_INTERFACE, NULL, - bridge, port, interface, - bridge_device, interface_device, - 0, - _transact_cb, - ovsdb_call_new (callback, user_data), - FALSE); + ovsdb_call_method(self, + OVSDB_ADD_INTERFACE, + NULL, + bridge, + port, + interface, + bridge_device, + interface_device, + 0, + _transact_cb, + ovsdb_call_new(callback, user_data), + FALSE); } void -nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname, - NMOvsdbCallback callback, gpointer user_data) +nm_ovsdb_del_interface(NMOvsdb * self, + const char * ifname, + NMOvsdbCallback callback, + gpointer user_data) { - ovsdb_call_method (self, OVSDB_DEL_INTERFACE, ifname, - NULL, NULL, NULL, NULL, NULL, 0, - _transact_cb, - ovsdb_call_new (callback, user_data), - FALSE); + ovsdb_call_method(self, + OVSDB_DEL_INTERFACE, + ifname, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + _transact_cb, + ovsdb_call_new(callback, user_data), + FALSE); } -void nm_ovsdb_set_interface_mtu (NMOvsdb *self, const char *ifname, guint32 mtu, - NMOvsdbCallback callback, gpointer user_data) +void +nm_ovsdb_set_interface_mtu(NMOvsdb * self, + const char * ifname, + guint32 mtu, + NMOvsdbCallback callback, + gpointer user_data) { - ovsdb_call_method (self, OVSDB_SET_INTERFACE_MTU, ifname, - NULL, NULL, NULL, NULL, NULL, mtu, - _transact_cb, - ovsdb_call_new (callback, user_data), - FALSE); + ovsdb_call_method(self, + OVSDB_SET_INTERFACE_MTU, + ifname, + NULL, + NULL, + NULL, + NULL, + NULL, + mtu, + _transact_cb, + ovsdb_call_new(callback, user_data), + FALSE); } /*****************************************************************************/ static void -_clear_call (gpointer data) +_clear_call(gpointer data) { - OvsdbMethodCall *call = data; - - switch (call->command) { - case OVSDB_MONITOR: - break; - case OVSDB_ADD_INTERFACE: - g_clear_object (&call->bridge); - g_clear_object (&call->port); - g_clear_object (&call->interface); - g_clear_object (&call->bridge_device); - g_clear_object (&call->interface_device); - break; - case OVSDB_DEL_INTERFACE: - case OVSDB_SET_INTERFACE_MTU: - nm_clear_g_free (&call->ifname); - break; - } + OvsdbMethodCall *call = data; + + switch (call->command) { + case OVSDB_MONITOR: + break; + case OVSDB_ADD_INTERFACE: + g_clear_object(&call->bridge); + g_clear_object(&call->port); + g_clear_object(&call->interface); + g_clear_object(&call->bridge_device); + g_clear_object(&call->interface_device); + break; + case OVSDB_DEL_INTERFACE: + case OVSDB_SET_INTERFACE_MTU: + nm_clear_g_free(&call->ifname); + break; + } } static void -_free_bridge (gpointer data) +_free_bridge(gpointer data) { - OpenvswitchBridge *ovs_bridge = data; + OpenvswitchBridge *ovs_bridge = data; - g_free (ovs_bridge->name); - g_free (ovs_bridge->connection_uuid); - g_ptr_array_free (ovs_bridge->ports, TRUE); - g_slice_free (OpenvswitchBridge, ovs_bridge); + g_free(ovs_bridge->name); + g_free(ovs_bridge->connection_uuid); + g_ptr_array_free(ovs_bridge->ports, TRUE); + g_slice_free(OpenvswitchBridge, ovs_bridge); } static void -_free_port (gpointer data) +_free_port(gpointer data) { - OpenvswitchPort *ovs_port = data; + OpenvswitchPort *ovs_port = data; - g_free (ovs_port->name); - g_free (ovs_port->connection_uuid); - g_ptr_array_free (ovs_port->interfaces, TRUE); - g_slice_free (OpenvswitchPort, ovs_port); + g_free(ovs_port->name); + g_free(ovs_port->connection_uuid); + g_ptr_array_free(ovs_port->interfaces, TRUE); + g_slice_free(OpenvswitchPort, ovs_port); } static void -_free_interface (gpointer data) +_free_interface(gpointer data) { - OpenvswitchInterface *ovs_interface = data; + OpenvswitchInterface *ovs_interface = data; - g_free (ovs_interface->name); - g_free (ovs_interface->connection_uuid); - g_free (ovs_interface->type); - g_slice_free (OpenvswitchInterface, ovs_interface); + g_free(ovs_interface->name); + g_free(ovs_interface->connection_uuid); + g_free(ovs_interface->type); + g_slice_free(OpenvswitchInterface, ovs_interface); } static void -nm_ovsdb_init (NMOvsdb *self) +nm_ovsdb_init(NMOvsdb *self) { - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); - priv->calls = g_array_new (FALSE, TRUE, sizeof (OvsdbMethodCall)); - g_array_set_clear_func (priv->calls, _clear_call); - priv->input = g_string_new (NULL); - priv->output = g_string_new (NULL); - priv->bridges = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, _free_bridge); - priv->ports = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, _free_port); - priv->interfaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, _free_interface); + priv->calls = g_array_new(FALSE, TRUE, sizeof(OvsdbMethodCall)); + g_array_set_clear_func(priv->calls, _clear_call); + priv->input = g_string_new(NULL); + priv->output = g_string_new(NULL); + priv->bridges = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, _free_bridge); + priv->ports = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, _free_port); + priv->interfaces = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, _free_interface); - ovsdb_try_connect (self); + ovsdb_try_connect(self); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMOvsdb *self = NM_OVSDB (object); - NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self); - - ovsdb_disconnect (self, FALSE, TRUE); - - if (priv->input) { - g_string_free (priv->input, TRUE); - priv->input = NULL; - } - if (priv->output) { - g_string_free (priv->output, TRUE); - priv->output = NULL; - } - if (priv->calls) { - g_array_free (priv->calls, TRUE); - priv->calls = NULL; - } - - nm_clear_pointer (&priv->bridges, g_hash_table_destroy); - nm_clear_pointer (&priv->ports, g_hash_table_destroy); - nm_clear_pointer (&priv->interfaces, g_hash_table_destroy); - - G_OBJECT_CLASS (nm_ovsdb_parent_class)->dispose (object); + NMOvsdb * self = NM_OVSDB(object); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + + ovsdb_disconnect(self, FALSE, TRUE); + + if (priv->input) { + g_string_free(priv->input, TRUE); + priv->input = NULL; + } + if (priv->output) { + g_string_free(priv->output, TRUE); + priv->output = NULL; + } + if (priv->calls) { + g_array_free(priv->calls, TRUE); + priv->calls = NULL; + } + + nm_clear_pointer(&priv->bridges, g_hash_table_destroy); + nm_clear_pointer(&priv->ports, g_hash_table_destroy); + nm_clear_pointer(&priv->interfaces, g_hash_table_destroy); + + G_OBJECT_CLASS(nm_ovsdb_parent_class)->dispose(object); } static void -nm_ovsdb_class_init (NMOvsdbClass *klass) +nm_ovsdb_class_init(NMOvsdbClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = dispose; - - signals[DEVICE_ADDED] = - g_signal_new (NM_OVSDB_DEVICE_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); - - signals[DEVICE_REMOVED] = - g_signal_new (NM_OVSDB_DEVICE_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); - - signals[INTERFACE_FAILED] = - g_signal_new (NM_OVSDB_INTERFACE_FAILED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->dispose = dispose; + + signals[DEVICE_ADDED] = g_signal_new(NM_OVSDB_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_UINT); + + signals[DEVICE_REMOVED] = g_signal_new(NM_OVSDB_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_UINT); + + signals[INTERFACE_FAILED] = g_signal_new(NM_OVSDB_INTERFACE_FAILED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); } diff --git a/src/devices/ovs/nm-ovsdb.h b/src/devices/ovs/nm-ovsdb.h index 72a2dc73..c9eee19c 100644 --- a/src/devices/ovs/nm-ovsdb.h +++ b/src/devices/ovs/nm-ovsdb.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -6,35 +6,44 @@ #ifndef __NETWORKMANAGER_OVSDB_H__ #define __NETWORKMANAGER_OVSDB_H__ -#define NM_TYPE_OVSDB (nm_ovsdb_get_type ()) -#define NM_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_OVSDB, NMOvsdb)) -#define NM_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_OVSDB, NMOvsdbClass)) -#define NM_IS_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_OVSDB)) -#define NM_IS_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_OVSDB)) -#define NM_OVSDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OVSDB, NMOvsdbClass)) +#define NM_TYPE_OVSDB (nm_ovsdb_get_type()) +#define NM_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_OVSDB, NMOvsdb)) +#define NM_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_OVSDB, NMOvsdbClass)) +#define NM_IS_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_OVSDB)) +#define NM_IS_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_OVSDB)) +#define NM_OVSDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_OVSDB, NMOvsdbClass)) -#define NM_OVSDB_DEVICE_ADDED "device-added" -#define NM_OVSDB_DEVICE_REMOVED "device-removed" -#define NM_OVSDB_INTERFACE_FAILED "interface-failed" +#define NM_OVSDB_DEVICE_ADDED "device-added" +#define NM_OVSDB_DEVICE_REMOVED "device-removed" +#define NM_OVSDB_INTERFACE_FAILED "interface-failed" -typedef struct _NMOvsdb NMOvsdb; +typedef struct _NMOvsdb NMOvsdb; typedef struct _NMOvsdbClass NMOvsdbClass; -typedef void (*NMOvsdbCallback) (GError *error, gpointer user_data); +typedef void (*NMOvsdbCallback)(GError *error, gpointer user_data); -NMOvsdb *nm_ovsdb_get (void); +NMOvsdb *nm_ovsdb_get(void); -GType nm_ovsdb_get_type (void); +GType nm_ovsdb_get_type(void); -void nm_ovsdb_add_interface (NMOvsdb *self, - NMConnection *bridge, NMConnection *port, NMConnection *interface, - NMDevice *bridge_device, NMDevice *interface_device, - NMOvsdbCallback callback, gpointer user_data); +void nm_ovsdb_add_interface(NMOvsdb * self, + NMConnection * bridge, + NMConnection * port, + NMConnection * interface, + NMDevice * bridge_device, + NMDevice * interface_device, + NMOvsdbCallback callback, + gpointer user_data); -void nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname, - NMOvsdbCallback callback, gpointer user_data); +void nm_ovsdb_del_interface(NMOvsdb * self, + const char * ifname, + NMOvsdbCallback callback, + gpointer user_data); -void nm_ovsdb_set_interface_mtu (NMOvsdb *self, const char *ifname, guint32 mtu, - NMOvsdbCallback callback, gpointer user_data); +void nm_ovsdb_set_interface_mtu(NMOvsdb * self, + const char * ifname, + guint32 mtu, + NMOvsdbCallback callback, + gpointer user_data); #endif /* __NETWORKMANAGER_OVSDB_H__ */ diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 7ba30342..27aa3004 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Jiri Pirko * Copyright (C) 2018 Red Hat, Inc. @@ -30,1042 +30,1067 @@ _LOG_DECLARE_SELF(NMDeviceTeam); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceTeam, - PROP_CONFIG, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceTeam, PROP_CONFIG, ); typedef struct { - struct teamdctl *tdc; - char *config; - GPid teamd_pid; - guint teamd_process_watch; - guint teamd_timeout; - guint teamd_read_timeout; - guint teamd_dbus_watch; - bool kill_in_progress:1; - GFileMonitor *usock_monitor; - NMDeviceStageState stage1_state:3; + struct teamdctl * tdc; + char * config; + GPid teamd_pid; + guint teamd_process_watch; + guint teamd_timeout; + guint teamd_read_timeout; + guint teamd_dbus_watch; + bool kill_in_progress : 1; + GFileMonitor * usock_monitor; + NMDeviceStageState stage1_state : 3; } NMDeviceTeamPrivate; struct _NMDeviceTeam { - NMDevice parent; - NMDeviceTeamPrivate _priv; + NMDevice parent; + NMDeviceTeamPrivate _priv; }; struct _NMDeviceTeamClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) -#define NM_DEVICE_TEAM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceTeam, NM_IS_DEVICE_TEAM, NMDevice) +#define NM_DEVICE_TEAM_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceTeam, NM_IS_DEVICE_TEAM, NMDevice) /*****************************************************************************/ -static gboolean teamd_start (NMDeviceTeam *self); +static gboolean teamd_start(NMDeviceTeam *self); /*****************************************************************************/ static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingTeam *s_team; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_TEAM_SETTING_NAME, - existing_connections, - NULL, - _("Team connection"), - "team", - NULL, - TRUE); - - s_team = nm_connection_get_setting_team (connection); - if (!s_team) { - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team)); - } - - return TRUE; + NMSettingTeam *s_team; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_TEAM_SETTING_NAME, + existing_connections, + NULL, + _("Team connection"), + "team", + NULL, + TRUE); + + s_team = nm_connection_get_setting_team(connection); + if (!s_team) { + s_team = (NMSettingTeam *) nm_setting_team_new(); + nm_connection_add_setting(connection, NM_SETTING(s_team)); + } + + return TRUE; } static gboolean -ensure_teamd_connection (NMDevice *device) +ensure_teamd_connection(NMDevice *device) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - int err; - - if (priv->tdc) - return TRUE; - - priv->tdc = teamdctl_alloc (); - g_assert (priv->tdc); - err = teamdctl_connect (priv->tdc, nm_device_get_iface (device), NULL, NULL); - if (err != 0) { - _LOGE (LOGD_TEAM, "failed to connect to teamd (err=%d)", err); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } - - return !!priv->tdc; + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + int err; + + if (priv->tdc) + return TRUE; + + priv->tdc = teamdctl_alloc(); + g_assert(priv->tdc); + err = teamdctl_connect(priv->tdc, nm_device_get_iface(device), NULL, NULL); + if (err != 0) { + _LOGE(LOGD_TEAM, "failed to connect to teamd (err=%d)", err); + teamdctl_free(priv->tdc); + priv->tdc = NULL; + } + + return !!priv->tdc; } static const char * -_get_config (NMDeviceTeam *self) +_get_config(NMDeviceTeam *self) { - return nm_str_not_empty (NM_DEVICE_TEAM_GET_PRIVATE (self)->config); + return nm_str_not_empty(NM_DEVICE_TEAM_GET_PRIVATE(self)->config); } static gboolean -teamd_read_config (NMDeviceTeam *self) +teamd_read_config(NMDeviceTeam *self) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - const char *config = NULL; - int err; - - if (priv->tdc) { - err = teamdctl_config_actual_get_raw_direct (priv->tdc, (char **) &config); - if (err) - return FALSE; - if (!config) { - /* set "" to distinguish an empty result from no config at all. */ - config = ""; - } - } - - if (!nm_streq0 (config, priv->config)) { - g_free (priv->config); - priv->config = g_strdup (config); - _notify (self, PROP_CONFIG); - } - - return TRUE; + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + const char * config = NULL; + int err; + + if (priv->tdc) { + err = teamdctl_config_actual_get_raw_direct(priv->tdc, (char **) &config); + if (err) + return FALSE; + if (!config) { + /* set "" to distinguish an empty result from no config at all. */ + config = ""; + } + } + + if (!nm_streq0(config, priv->config)) { + g_free(priv->config); + priv->config = g_strdup(config); + _notify(self, PROP_CONFIG); + } + + return TRUE; } static gboolean -teamd_read_timeout_cb (gpointer user_data) +teamd_read_timeout_cb(gpointer user_data) { - NMDeviceTeam *self = user_data; - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDeviceTeam * self = user_data; + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); - priv->teamd_read_timeout = 0; - teamd_read_config (self); - return G_SOURCE_REMOVE; + priv->teamd_read_timeout = 0; + teamd_read_config(self); + return G_SOURCE_REMOVE; } static void -update_connection (NMDevice *device, NMConnection *connection) +update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMSettingTeam *s_team = nm_connection_get_setting_team (connection); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - struct teamdctl *tdc = priv->tdc; - - if (!s_team) { - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, (NMSetting *) s_team); - } - - /* Read the configuration only if not already set */ - if ( !priv->config - && ensure_teamd_connection (device)) - teamd_read_config (self); - - /* Restore previous tdc state */ - if (priv->tdc && !tdc) { - teamdctl_disconnect (priv->tdc); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } - - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, _get_config (self), NULL); + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMSettingTeam * s_team = nm_connection_get_setting_team(connection); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + struct teamdctl * tdc = priv->tdc; + + if (!s_team) { + s_team = (NMSettingTeam *) nm_setting_team_new(); + nm_connection_add_setting(connection, (NMSetting *) s_team); + } + + /* Read the configuration only if not already set */ + if (!priv->config && ensure_teamd_connection(device)) + teamd_read_config(self); + + /* Restore previous tdc state */ + if (priv->tdc && !tdc) { + teamdctl_disconnect(priv->tdc); + teamdctl_free(priv->tdc); + priv->tdc = NULL; + } + + g_object_set(G_OBJECT(s_team), NM_SETTING_TEAM_CONFIG, _get_config(self), NULL); } /*****************************************************************************/ static gboolean -master_update_slave_connection (NMDevice *self, - NMDevice *slave, - NMConnection *connection, - GError **error) +master_update_slave_connection(NMDevice * self, + NMDevice * slave, + NMConnection *connection, + GError ** error) { - NMSettingTeamPort *s_port; - char *port_config = NULL; - int err = 0; - struct teamdctl *tdc; - const char *team_port_config = NULL; - const char *iface = nm_device_get_iface (self); - const char *iface_slave = nm_device_get_iface (slave); - - tdc = teamdctl_alloc (); - if (!tdc) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "update slave connection for slave '%s' failed to connect to teamd for master %s (out of memory?)", - iface_slave, iface); - g_return_val_if_reached (FALSE); - } - - err = teamdctl_connect (tdc, iface, NULL, NULL); - if (err) { - teamdctl_free (tdc); - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "update slave connection for slave '%s' failed to connect to teamd for master %s (err=%d)", - iface_slave, iface, err); - return FALSE; - } - - err = teamdctl_port_config_get_raw_direct (tdc, iface_slave, (char **)&team_port_config); - port_config = g_strdup (team_port_config); - teamdctl_disconnect (tdc); - teamdctl_free (tdc); - if (err) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "update slave connection for slave '%s' failed to get configuration from teamd master %s (err=%d)", - iface_slave, iface, err); - g_free (port_config); - return FALSE; - } - - s_port = nm_connection_get_setting_team_port (connection); - if (!s_port) { - s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_port)); - } - - g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); - g_free (port_config); - - g_object_set (nm_connection_get_setting_connection (connection), - NM_SETTING_CONNECTION_MASTER, iface, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); - return TRUE; + NMSettingTeamPort *s_port; + char * port_config = NULL; + int err = 0; + struct teamdctl * tdc; + const char * team_port_config = NULL; + const char * iface = nm_device_get_iface(self); + const char * iface_slave = nm_device_get_iface(slave); + + tdc = teamdctl_alloc(); + if (!tdc) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master " + "%s (out of memory?)", + iface_slave, + iface); + g_return_val_if_reached(FALSE); + } + + err = teamdctl_connect(tdc, iface, NULL, NULL); + if (err) { + teamdctl_free(tdc); + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master " + "%s (err=%d)", + iface_slave, + iface, + err); + return FALSE; + } + + err = teamdctl_port_config_get_raw_direct(tdc, iface_slave, (char **) &team_port_config); + port_config = g_strdup(team_port_config); + teamdctl_disconnect(tdc); + teamdctl_free(tdc); + if (err) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to get configuration from teamd " + "master %s (err=%d)", + iface_slave, + iface, + err); + g_free(port_config); + return FALSE; + } + + s_port = nm_connection_get_setting_team_port(connection); + if (!s_port) { + s_port = (NMSettingTeamPort *) nm_setting_team_port_new(); + nm_connection_add_setting(connection, NM_SETTING(s_port)); + } + + g_object_set(G_OBJECT(s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); + g_free(port_config); + + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, + iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NULL); + return TRUE; } /*****************************************************************************/ static void -teamd_kill_cb (pid_t pid, gboolean success, int child_status, void *user_data) +teamd_kill_cb(pid_t pid, gboolean success, int child_status, void *user_data) { - gs_unref_object NMDeviceTeam *self = user_data; - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - - priv->kill_in_progress = FALSE; - - if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_PREPARE) { - _LOGT (LOGD_TEAM, "kill terminated"); - return; - } - - _LOGT (LOGD_TEAM, "kill terminated, starting teamd..."); - if (!teamd_start (self)) { - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } + gs_unref_object NMDeviceTeam *self = user_data; + NMDeviceTeamPrivate * priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + + priv->kill_in_progress = FALSE; + + if (nm_device_get_state(NM_DEVICE(self)) != NM_DEVICE_STATE_PREPARE) { + _LOGT(LOGD_TEAM, "kill terminated"); + return; + } + + _LOGT(LOGD_TEAM, "kill terminated, starting teamd..."); + if (!teamd_start(self)) { + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } static void -teamd_cleanup (NMDeviceTeam *self, gboolean free_tdc) +teamd_cleanup(NMDeviceTeam *self, gboolean free_tdc) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - - nm_clear_g_source (&priv->teamd_process_watch); - nm_clear_g_source (&priv->teamd_timeout); - nm_clear_g_source (&priv->teamd_read_timeout); - - if (priv->teamd_pid > 0) { - priv->kill_in_progress = TRUE; - nm_utils_kill_child_async (priv->teamd_pid, - SIGTERM, - LOGD_TEAM, - "teamd", - 2000, - teamd_kill_cb, - g_object_ref (self)); - priv->teamd_pid = 0; - } - - if ( priv->tdc - && free_tdc) { - teamdctl_disconnect (priv->tdc); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + + nm_clear_g_source(&priv->teamd_process_watch); + nm_clear_g_source(&priv->teamd_timeout); + nm_clear_g_source(&priv->teamd_read_timeout); + + if (priv->teamd_pid > 0) { + priv->kill_in_progress = TRUE; + nm_utils_kill_child_async(priv->teamd_pid, + SIGTERM, + LOGD_TEAM, + "teamd", + 2000, + teamd_kill_cb, + g_object_ref(self)); + priv->teamd_pid = 0; + } + + if (priv->tdc && free_tdc) { + teamdctl_disconnect(priv->tdc); + teamdctl_free(priv->tdc); + priv->tdc = NULL; + } } static gboolean -teamd_timeout_cb (gpointer user_data) +teamd_timeout_cb(gpointer user_data) { - NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); - NMDevice *device = NM_DEVICE (self); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - - g_return_val_if_fail (priv->teamd_timeout, FALSE); - priv->teamd_timeout = 0; - - if (priv->teamd_pid && !priv->tdc) { - /* Timed out launching our own teamd process */ - _LOGW (LOGD_TEAM, "teamd timed out"); - teamd_cleanup (self, TRUE); - - g_warn_if_fail (nm_device_is_activating (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } else { - /* Read again the configuration after the timeout since it might - * have changed. - */ - if (!teamd_read_config (self)) { - _LOGW (LOGD_TEAM, "failed to read teamd configuration"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } - } - - return G_SOURCE_REMOVE; + NMDeviceTeam * self = NM_DEVICE_TEAM(user_data); + NMDevice * device = NM_DEVICE(self); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + + g_return_val_if_fail(priv->teamd_timeout, FALSE); + priv->teamd_timeout = 0; + + if (priv->teamd_pid && !priv->tdc) { + /* Timed out launching our own teamd process */ + _LOGW(LOGD_TEAM, "teamd timed out"); + teamd_cleanup(self, TRUE); + + g_warn_if_fail(nm_device_is_activating(device)); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } else { + /* Read again the configuration after the timeout since it might + * have changed. + */ + if (!teamd_read_config(self)) { + _LOGW(LOGD_TEAM, "failed to read teamd configuration"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } + } + + return G_SOURCE_REMOVE; } static void -teamd_ready (NMDeviceTeam *self) +teamd_ready(NMDeviceTeam *self) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - gboolean success; - - if (priv->kill_in_progress) { - /* If we are currently killing teamd, we are not - * interested in knowing when it becomes ready. */ - return; - } - - nm_device_queue_recheck_assume (device); - - /* Grab a teamd control handle even if we aren't going to use it - * immediately. But if we are, and grabbing it failed, fail the - * device activation. - */ - success = ensure_teamd_connection (device); - - if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE - || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) - return; - - if (success) - success = teamd_read_config (self); - - if (!success) { - teamd_cleanup (self, TRUE); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - return; - } - - priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + gboolean success; + + if (priv->kill_in_progress) { + /* If we are currently killing teamd, we are not + * interested in knowing when it becomes ready. */ + return; + } + + nm_device_queue_recheck_assume(device); + + /* Grab a teamd control handle even if we aren't going to use it + * immediately. But if we are, and grabbing it failed, fail the + * device activation. + */ + success = ensure_teamd_connection(device); + + if (nm_device_get_state(device) != NM_DEVICE_STATE_PREPARE + || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) + return; + + if (success) + success = teamd_read_config(self); + + if (!success) { + teamd_cleanup(self, TRUE); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + return; + } + + priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -teamd_gone (NMDeviceTeam *self) +teamd_gone(NMDeviceTeam *self) { - NMDevice *device = NM_DEVICE (self); - NMDeviceState state; - - teamd_cleanup (self, TRUE); - state = nm_device_get_state (device); - - /* Attempt to respawn teamd */ - if ( state >= NM_DEVICE_STATE_PREPARE - && state <= NM_DEVICE_STATE_ACTIVATED) { - if (!teamd_start (self)) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } - } + NMDevice * device = NM_DEVICE(self); + NMDeviceState state; + + teamd_cleanup(self, TRUE); + state = nm_device_get_state(device); + + /* Attempt to respawn teamd */ + if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) { + if (!teamd_start(self)) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } + } } static void -teamd_dbus_appeared (GDBusConnection *connection, - const char *name, - const char *name_owner, - gpointer user_data) +teamd_dbus_appeared(GDBusConnection *connection, + const char * name, + const char * name_owner, + gpointer user_data) { - NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - - g_return_if_fail (priv->teamd_dbus_watch); - - _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); - - /* If another teamd grabbed the bus name while our teamd was starting, - * just ignore the death of our teamd and run with the existing one. - */ - if (priv->teamd_process_watch) { - gs_unref_variant GVariant *ret = NULL; - guint32 pid; - - ret = g_dbus_connection_call_sync (connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetConnectionUnixProcessID", - g_variant_new ("(s)", name_owner), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 2000, - NULL, - NULL); - - if (ret) { - g_variant_get (ret, "(u)", &pid); - if (pid != priv->teamd_pid) - teamd_cleanup (self, FALSE); - } else { - /* The process that registered on the bus died. If it's - * the teamd instance we just started, ignore the event - * as we already detect the failure through the process - * watch. If it's a previous instance that got killed, - * also ignore that as our new instance will register - * again. */ - _LOGD (LOGD_TEAM, "failed to determine D-Bus name owner, ignoring"); - return; - } - } - - teamd_ready (self); + NMDeviceTeam * self = NM_DEVICE_TEAM(user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + + g_return_if_fail(priv->teamd_dbus_watch); + + _LOGI(LOGD_TEAM, "teamd appeared on D-Bus"); + + /* If another teamd grabbed the bus name while our teamd was starting, + * just ignore the death of our teamd and run with the existing one. + */ + if (priv->teamd_process_watch) { + gs_unref_variant GVariant *ret = NULL; + guint32 pid; + + ret = g_dbus_connection_call_sync(connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID", + g_variant_new("(s)", name_owner), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 2000, + NULL, + NULL); + + if (ret) { + g_variant_get(ret, "(u)", &pid); + if (pid != priv->teamd_pid) + teamd_cleanup(self, FALSE); + } else { + /* The process that registered on the bus died. If it's + * the teamd instance we just started, ignore the event + * as we already detect the failure through the process + * watch. If it's a previous instance that got killed, + * also ignore that as our new instance will register + * again. */ + _LOGD(LOGD_TEAM, "failed to determine D-Bus name owner, ignoring"); + return; + } + } + + teamd_ready(self); } static void -teamd_dbus_vanished (GDBusConnection *dbus_connection, - const char *name, - gpointer user_data) +teamd_dbus_vanished(GDBusConnection *dbus_connection, const char *name, gpointer user_data) { - NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDeviceTeam * self = NM_DEVICE_TEAM(user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); - g_return_if_fail (priv->teamd_dbus_watch); + g_return_if_fail(priv->teamd_dbus_watch); - if (!priv->tdc) { - /* g_bus_watch_name will always raise an initial signal, to indicate whether the - * name exists/not exists initially. Do not take this as a failure if it hadn't - * previously appeared. - */ - _LOGD (LOGD_TEAM, "teamd not on D-Bus (ignored)"); - return; - } + if (!priv->tdc) { + /* g_bus_watch_name will always raise an initial signal, to indicate whether the + * name exists/not exists initially. Do not take this as a failure if it hadn't + * previously appeared. + */ + _LOGD(LOGD_TEAM, "teamd not on D-Bus (ignored)"); + return; + } - _LOGI (LOGD_TEAM, "teamd vanished from D-Bus"); + _LOGI(LOGD_TEAM, "teamd vanished from D-Bus"); - teamd_gone (self); + teamd_gone(self); } - static void -monitor_changed_cb (GFileMonitor *monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - gpointer user_data) +monitor_changed_cb(GFileMonitor * monitor, + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, + gpointer user_data) { - NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); - - switch (event_type) { - case G_FILE_MONITOR_EVENT_CREATED: - _LOGI (LOGD_TEAM, "file %s was created", g_file_get_path (file)); - teamd_ready (self); - break; - case G_FILE_MONITOR_EVENT_DELETED: - _LOGI (LOGD_TEAM, "file %s was deleted", g_file_get_path (file)); - teamd_gone (self); - break; - default: - ; - } + NMDeviceTeam *self = NM_DEVICE_TEAM(user_data); + + switch (event_type) { + case G_FILE_MONITOR_EVENT_CREATED: + _LOGI(LOGD_TEAM, "file %s was created", g_file_get_path(file)); + teamd_ready(self); + break; + case G_FILE_MONITOR_EVENT_DELETED: + _LOGI(LOGD_TEAM, "file %s was deleted", g_file_get_path(file)); + teamd_gone(self); + break; + default:; + } } static void -teamd_process_watch_cb (GPid pid, int status, gpointer user_data) +teamd_process_watch_cb(GPid pid, int status, gpointer user_data) { - NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMDeviceState state = nm_device_get_state (device); - - g_return_if_fail (priv->teamd_process_watch); - - _LOGD (LOGD_TEAM, "teamd %lld died with status %d", (long long) pid, status); - priv->teamd_pid = 0; - priv->teamd_process_watch = 0; - - /* If teamd quit within 5 seconds of starting, it's probably hosed - * and will just die again, so fail the activation. - */ - if (priv->teamd_timeout && - (state >= NM_DEVICE_STATE_PREPARE) && - (state <= NM_DEVICE_STATE_ACTIVATED)) { - _LOGW (LOGD_TEAM, "teamd process %lld quit unexpectedly; failing activation", (long long) pid); - teamd_cleanup (self, TRUE); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } + NMDeviceTeam * self = NM_DEVICE_TEAM(user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMDeviceState state = nm_device_get_state(device); + + g_return_if_fail(priv->teamd_process_watch); + + _LOGD(LOGD_TEAM, "teamd %lld died with status %d", (long long) pid, status); + priv->teamd_pid = 0; + priv->teamd_process_watch = 0; + + /* If teamd quit within 5 seconds of starting, it's probably hosed + * and will just die again, so fail the activation. + */ + if (priv->teamd_timeout && (state >= NM_DEVICE_STATE_PREPARE) + && (state <= NM_DEVICE_STATE_ACTIVATED)) { + _LOGW(LOGD_TEAM, + "teamd process %lld quit unexpectedly; failing activation", + (long long) pid); + teamd_cleanup(self, TRUE); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } static void -teamd_child_setup (gpointer user_data) +teamd_child_setup(gpointer user_data) { - nm_utils_setpgid (NULL); - signal (SIGPIPE, SIG_IGN); + nm_utils_setpgid(NULL); + signal(SIGPIPE, SIG_IGN); } static const char ** -teamd_env (void) +teamd_env(void) { - const char **env = g_new0 (const char *, 2); + const char **env = g_new0(const char *, 2); - if (nm_config_get_is_debug (nm_config_get ())) - env[0] = "TEAM_LOG_OUTPUT=stderr"; - else - env[0] = "TEAM_LOG_OUTPUT=syslog"; + if (nm_config_get_is_debug(nm_config_get())) + env[0] = "TEAM_LOG_OUTPUT=stderr"; + else + env[0] = "TEAM_LOG_OUTPUT=syslog"; - return env; + return env; } static gboolean -teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error) +teamd_kill(NMDeviceTeam *self, const char *teamd_binary, GError **error) { - gs_unref_ptrarray GPtrArray *argv = NULL; - gs_free char *tmp_str = NULL; - gs_free const char **envp = NULL; - - if (!teamd_binary) { - teamd_binary = nm_utils_find_helper ("teamd", NULL, error); - if (!teamd_binary) { - _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); - return FALSE; - } - } - - argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) teamd_binary); - g_ptr_array_add (argv, (gpointer) "-k"); - g_ptr_array_add (argv, (gpointer) "-t"); - g_ptr_array_add (argv, (gpointer) nm_device_get_iface (NM_DEVICE (self))); - g_ptr_array_add (argv, NULL); - - envp = teamd_env (); - - _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (char **) argv->pdata))); - return g_spawn_sync ("/", (char **) argv->pdata, (char **) envp, 0, - teamd_child_setup, NULL, NULL, NULL, NULL, error); + gs_unref_ptrarray GPtrArray *argv = NULL; + gs_free char * tmp_str = NULL; + gs_free const char ** envp = NULL; + + if (!teamd_binary) { + teamd_binary = nm_utils_find_helper("teamd", NULL, error); + if (!teamd_binary) { + _LOGW(LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); + return FALSE; + } + } + + argv = g_ptr_array_new(); + g_ptr_array_add(argv, (gpointer) teamd_binary); + g_ptr_array_add(argv, (gpointer) "-k"); + g_ptr_array_add(argv, (gpointer) "-t"); + g_ptr_array_add(argv, (gpointer) nm_device_get_iface(NM_DEVICE(self))); + g_ptr_array_add(argv, NULL); + + envp = teamd_env(); + + _LOGD(LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv(" ", (char **) argv->pdata))); + return g_spawn_sync("/", + (char **) argv->pdata, + (char **) envp, + 0, + teamd_child_setup, + NULL, + NULL, + NULL, + NULL, + error); } static gboolean -teamd_start (NMDeviceTeam *self) +teamd_start(NMDeviceTeam *self) { - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - const char *iface = nm_device_get_ip_iface (NM_DEVICE (self)); - NMConnection *connection; - gs_unref_ptrarray GPtrArray *argv = NULL; - gs_free_error GError *error = NULL; - gs_free char *tmp_str = NULL; - const char *teamd_binary; - const char *config; - nm_auto_free const char *config_free = NULL; - NMSettingTeam *s_team; - gs_free char *cloned_mac = NULL; - gs_free const char **envp = NULL; - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - - s_team = nm_connection_get_setting_team (connection); - if (!s_team) - g_return_val_if_reached (FALSE); - - nm_assert (iface); - - teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); - if (!teamd_binary) { - _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); - return FALSE; - } - - if (priv->teamd_process_watch || priv->teamd_pid > 0 || priv->tdc) { - g_warn_if_reached (); - if (!priv->teamd_pid) - teamd_kill (self, teamd_binary, NULL); - teamd_cleanup (self, TRUE); - } - - /* Start teamd now */ - argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) teamd_binary); - g_ptr_array_add (argv, (gpointer) "-o"); - g_ptr_array_add (argv, (gpointer) "-n"); - g_ptr_array_add (argv, (gpointer) "-U"); - if (priv->teamd_dbus_watch) - g_ptr_array_add (argv, (gpointer) "-D"); - g_ptr_array_add (argv, (gpointer) "-N"); - g_ptr_array_add (argv, (gpointer) "-t"); - g_ptr_array_add (argv, (gpointer) iface); - - config = nm_setting_team_get_config (s_team); - if (!nm_device_hw_addr_get_cloned (NM_DEVICE (self), connection, FALSE, &cloned_mac, NULL, &error)) { - _LOGW (LOGD_DEVICE, "set-hw-addr: %s", error->message); - return FALSE; - } - - if (cloned_mac) { - json_t *json, *hwaddr; - json_error_t jerror; - - /* Inject the hwaddr property into the JSON configuration. - * While doing so, detect potential conflicts */ - - json = json_loads (config ?: "{}", JSON_REJECT_DUPLICATES, &jerror); - g_return_val_if_fail (json, FALSE); - - hwaddr = json_object_get (json, "hwaddr"); - if (hwaddr) { - if ( !json_is_string (hwaddr) - || !nm_streq0 (json_string_value (hwaddr), cloned_mac)) - _LOGW (LOGD_TEAM, "set-hw-addr: can't set team cloned-mac-address as the JSON configuration already contains \"hwaddr\""); - } else { - hwaddr = json_string (cloned_mac); - json_object_set (json, "hwaddr", hwaddr); - config = config_free = json_dumps (json, JSON_INDENT(0) | - JSON_ENSURE_ASCII | - JSON_SORT_KEYS); - _LOGD (LOGD_TEAM, "set-hw-addr: injected \"hwaddr\" \"%s\" into team configuration", cloned_mac); - json_decref (hwaddr); - } - json_decref (json); - } - - if (config) { - g_ptr_array_add (argv, (gpointer) "-c"); - g_ptr_array_add (argv, (gpointer) config); - } - - if (nm_logging_enabled (LOGL_DEBUG, LOGD_TEAM)) - g_ptr_array_add (argv, (gpointer) "-gg"); - g_ptr_array_add (argv, NULL); - - envp = teamd_env (); - - _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (char **) argv->pdata))); - if (!g_spawn_async ("/", (char **) argv->pdata, (char **) envp, G_SPAWN_DO_NOT_REAP_CHILD, - teamd_child_setup, NULL, &priv->teamd_pid, &error)) { - _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); - teamd_cleanup (self, TRUE); - return FALSE; - } - - /* Start a timeout for teamd to appear at D-Bus */ - if (!priv->teamd_timeout) - priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, self); - - /* Monitor the child process so we know when it dies */ - priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid, - teamd_process_watch_cb, - self); - - _LOGI (LOGD_TEAM, "Activation: (team) started teamd [pid %u]...", (guint) priv->teamd_pid); - return TRUE; + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + const char * iface = nm_device_get_ip_iface(NM_DEVICE(self)); + NMConnection * connection; + gs_unref_ptrarray GPtrArray *argv = NULL; + gs_free_error GError * error = NULL; + gs_free char * tmp_str = NULL; + const char * teamd_binary; + const char * config; + nm_auto_free const char *config_free = NULL; + NMSettingTeam * s_team; + gs_free char * cloned_mac = NULL; + gs_free const char ** envp = NULL; + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + + s_team = nm_connection_get_setting_team(connection); + if (!s_team) + g_return_val_if_reached(FALSE); + + nm_assert(iface); + + teamd_binary = nm_utils_find_helper("teamd", NULL, NULL); + if (!teamd_binary) { + _LOGW(LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); + return FALSE; + } + + if (priv->teamd_process_watch || priv->teamd_pid > 0 || priv->tdc) { + g_warn_if_reached(); + if (!priv->teamd_pid) + teamd_kill(self, teamd_binary, NULL); + teamd_cleanup(self, TRUE); + } + + /* Start teamd now */ + argv = g_ptr_array_new(); + g_ptr_array_add(argv, (gpointer) teamd_binary); + g_ptr_array_add(argv, (gpointer) "-o"); + g_ptr_array_add(argv, (gpointer) "-n"); + g_ptr_array_add(argv, (gpointer) "-U"); + if (priv->teamd_dbus_watch) + g_ptr_array_add(argv, (gpointer) "-D"); + g_ptr_array_add(argv, (gpointer) "-N"); + g_ptr_array_add(argv, (gpointer) "-t"); + g_ptr_array_add(argv, (gpointer) iface); + + config = nm_setting_team_get_config(s_team); + if (!nm_device_hw_addr_get_cloned(NM_DEVICE(self), + connection, + FALSE, + &cloned_mac, + NULL, + &error)) { + _LOGW(LOGD_DEVICE, "set-hw-addr: %s", error->message); + return FALSE; + } + + if (cloned_mac) { + json_t * json, *hwaddr; + json_error_t jerror; + + /* Inject the hwaddr property into the JSON configuration. + * While doing so, detect potential conflicts */ + + json = json_loads(config ?: "{}", JSON_REJECT_DUPLICATES, &jerror); + g_return_val_if_fail(json, FALSE); + + hwaddr = json_object_get(json, "hwaddr"); + if (hwaddr) { + if (!json_is_string(hwaddr) || !nm_streq0(json_string_value(hwaddr), cloned_mac)) + _LOGW(LOGD_TEAM, + "set-hw-addr: can't set team cloned-mac-address as the JSON configuration " + "already contains \"hwaddr\""); + } else { + hwaddr = json_string(cloned_mac); + json_object_set(json, "hwaddr", hwaddr); + config = config_free = + json_dumps(json, JSON_INDENT(0) | JSON_ENSURE_ASCII | JSON_SORT_KEYS); + _LOGD(LOGD_TEAM, + "set-hw-addr: injected \"hwaddr\" \"%s\" into team configuration", + cloned_mac); + json_decref(hwaddr); + } + json_decref(json); + } + + if (config) { + g_ptr_array_add(argv, (gpointer) "-c"); + g_ptr_array_add(argv, (gpointer) config); + } + + if (nm_logging_enabled(LOGL_DEBUG, LOGD_TEAM)) + g_ptr_array_add(argv, (gpointer) "-gg"); + g_ptr_array_add(argv, NULL); + + envp = teamd_env(); + + _LOGD(LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv(" ", (char **) argv->pdata))); + if (!g_spawn_async("/", + (char **) argv->pdata, + (char **) envp, + G_SPAWN_DO_NOT_REAP_CHILD, + teamd_child_setup, + NULL, + &priv->teamd_pid, + &error)) { + _LOGW(LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); + teamd_cleanup(self, TRUE); + return FALSE; + } + + /* Start a timeout for teamd to appear at D-Bus */ + if (!priv->teamd_timeout) + priv->teamd_timeout = g_timeout_add_seconds(5, teamd_timeout_cb, self); + + /* Monitor the child process so we know when it dies */ + priv->teamd_process_watch = g_child_watch_add(priv->teamd_pid, teamd_process_watch_cb, self); + + _LOGI(LOGD_TEAM, "Activation: (team) started teamd [pid %u]...", (guint) priv->teamd_pid); + return TRUE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - gs_free_error GError *error = NULL; - NMSettingTeam *s_team; - const char *cfg; - - if (nm_device_sys_iface_state_is_external (device)) - return NM_ACT_STAGE_RETURN_SUCCESS; - - if (nm_device_sys_iface_state_is_external_or_assume (device)) { - if (ensure_teamd_connection (device)) - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - s_team = nm_device_get_applied_setting (device, NM_TYPE_SETTING_TEAM); - if (!s_team) - g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - - if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) - return NM_ACT_STAGE_RETURN_POSTPONE; - - if (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED) - return NM_ACT_STAGE_RETURN_SUCCESS; - - priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; - - if (priv->tdc) { - /* If the existing teamd config is the same as we're about to use, - * then we can proceed. If it's not the same, and we have a PID, - * kill it so we can respawn it with the right config. If we don't - * have a PID, then we must fail. - */ - cfg = teamdctl_config_get_raw (priv->tdc); - if ( cfg - && nm_streq0 (cfg, nm_setting_team_get_config (s_team))) { - _LOGD (LOGD_TEAM, "using existing matching teamd config"); - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - if (!priv->teamd_pid) { - _LOGD (LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl"); - if (!teamd_kill (self, NULL, &error)) { - _LOGW (LOGD_TEAM, "existing teamd config mismatch; failed to kill existing teamd: %s", error->message); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - - _LOGD (LOGD_TEAM, "existing teamd config mismatch; respawning..."); - teamd_cleanup (self, TRUE); - } - - if (priv->kill_in_progress) { - _LOGT (LOGD_TEAM, "kill in progress, wait before starting teamd"); - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (!teamd_start (self)) - return NM_ACT_STAGE_RETURN_FAILURE; - - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + NMSettingTeam * s_team; + const char * cfg; + + if (nm_device_sys_iface_state_is_external(device)) + return NM_ACT_STAGE_RETURN_SUCCESS; + + if (nm_device_sys_iface_state_is_external_or_assume(device)) { + if (ensure_teamd_connection(device)) + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + s_team = nm_device_get_applied_setting(device, NM_TYPE_SETTING_TEAM); + if (!s_team) + g_return_val_if_reached(NM_ACT_STAGE_RETURN_FAILURE); + + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; + + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED) + return NM_ACT_STAGE_RETURN_SUCCESS; + + priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; + + if (priv->tdc) { + /* If the existing teamd config is the same as we're about to use, + * then we can proceed. If it's not the same, and we have a PID, + * kill it so we can respawn it with the right config. If we don't + * have a PID, then we must fail. + */ + cfg = teamdctl_config_get_raw(priv->tdc); + if (cfg && nm_streq0(cfg, nm_setting_team_get_config(s_team))) { + _LOGD(LOGD_TEAM, "using existing matching teamd config"); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + if (!priv->teamd_pid) { + _LOGD(LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl"); + if (!teamd_kill(self, NULL, &error)) { + _LOGW(LOGD_TEAM, + "existing teamd config mismatch; failed to kill existing teamd: %s", + error->message); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + _LOGD(LOGD_TEAM, "existing teamd config mismatch; respawning..."); + teamd_cleanup(self, TRUE); + } + + if (priv->kill_in_progress) { + _LOGT(LOGD_TEAM, "kill in progress, wait before starting teamd"); + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (!teamd_start(self)) + return NM_ACT_STAGE_RETURN_FAILURE; + + return NM_ACT_STAGE_RETURN_POSTPONE; } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); - priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; - if (nm_device_sys_iface_state_is_external (device)) - return; + if (nm_device_sys_iface_state_is_external(device)) + return; - if ( priv->teamd_pid - || priv->tdc) - _LOGI (LOGD_TEAM, "deactivation: stopping teamd..."); + if (priv->teamd_pid || priv->tdc) + _LOGI(LOGD_TEAM, "deactivation: stopping teamd..."); - if (!priv->teamd_pid) - teamd_kill (self, NULL, NULL); + if (!priv->teamd_pid) + teamd_kill(self, NULL, NULL); - teamd_cleanup (self, TRUE); + teamd_cleanup(self, TRUE); } static gboolean -enslave_slave (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - gboolean configure) +enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - gboolean success = TRUE; - const char *slave_iface = nm_device_get_ip_iface (slave); - NMSettingTeamPort *s_team_port; - - nm_device_master_check_slave_physical_port (device, slave, LOGD_TEAM); - - if (configure) { - nm_device_take_down (slave, TRUE); - - s_team_port = nm_connection_get_setting_team_port (connection); - if (s_team_port) { - const char *config = nm_setting_team_port_get_config (s_team_port); - - if (config) { - if (!priv->tdc) { - _LOGW (LOGD_TEAM, "enslaved team port %s config not changed, not connected to teamd", - slave_iface); - } else { - int err; - char *sanitized_config; - - sanitized_config = g_strdelimit (g_strdup (config), "\r\n", ' '); - err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); - g_free (sanitized_config); - if (err != 0) { - _LOGE (LOGD_TEAM, "failed to update config for port %s (err=%d)", - slave_iface, err); - return FALSE; - } - } - } - } - success = nm_platform_link_enslave (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - nm_device_get_ip_ifindex (slave)); - nm_device_bring_up (slave, TRUE, NULL); - - if (!success) - return FALSE; - - nm_clear_g_source (&priv->teamd_read_timeout); - priv->teamd_read_timeout = g_timeout_add_seconds (5, - teamd_read_timeout_cb, - self); - - _LOGI (LOGD_TEAM, "enslaved team port %s", slave_iface); - } else - _LOGI (LOGD_TEAM, "team port %s was enslaved", slave_iface); - - return TRUE; + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + gboolean success = TRUE; + const char * slave_iface = nm_device_get_ip_iface(slave); + NMSettingTeamPort * s_team_port; + + nm_device_master_check_slave_physical_port(device, slave, LOGD_TEAM); + + if (configure) { + nm_device_take_down(slave, TRUE); + + s_team_port = nm_connection_get_setting_team_port(connection); + if (s_team_port) { + const char *config = nm_setting_team_port_get_config(s_team_port); + + if (config) { + if (!priv->tdc) { + _LOGW(LOGD_TEAM, + "enslaved team port %s config not changed, not connected to teamd", + slave_iface); + } else { + int err; + char *sanitized_config; + + sanitized_config = g_strdelimit(g_strdup(config), "\r\n", ' '); + err = teamdctl_port_config_update_raw(priv->tdc, slave_iface, sanitized_config); + g_free(sanitized_config); + if (err != 0) { + _LOGE(LOGD_TEAM, + "failed to update config for port %s (err=%d)", + slave_iface, + err); + return FALSE; + } + } + } + } + success = nm_platform_link_enslave(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + nm_device_get_ip_ifindex(slave)); + nm_device_bring_up(slave, TRUE, NULL); + + if (!success) + return FALSE; + + nm_clear_g_source(&priv->teamd_read_timeout); + priv->teamd_read_timeout = g_timeout_add_seconds(5, teamd_read_timeout_cb, self); + + _LOGI(LOGD_TEAM, "enslaved team port %s", slave_iface); + } else + _LOGI(LOGD_TEAM, "team port %s was enslaved", slave_iface); + + return TRUE; } static void -release_slave (NMDevice *device, - NMDevice *slave, - gboolean configure) +release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - NMDeviceTeam *self = NM_DEVICE_TEAM (device); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - gboolean do_release, success; - NMSettingTeamPort *s_port; - int ifindex_slave; - int ifindex; - - do_release = configure; - if (do_release) { - ifindex = nm_device_get_ifindex (device); - if ( ifindex <= 0 - || !nm_platform_link_get (nm_device_get_platform (device), ifindex)) - do_release = FALSE; - } - - ifindex_slave = nm_device_get_ip_ifindex (slave); - - if (ifindex_slave <= 0) { - _LOGD (LOGD_TEAM, "team port %s is already released", nm_device_get_ip_iface (slave)); - } else if (do_release) { - success = nm_platform_link_release (nm_device_get_platform (device), - nm_device_get_ip_ifindex (device), - ifindex_slave); - if (success) - _LOGI (LOGD_TEAM, "released team port %s", nm_device_get_ip_iface (slave)); - else - _LOGW (LOGD_TEAM, "failed to release team port %s", nm_device_get_ip_iface (slave)); - - /* Kernel team code "closes" the port when releasing it, (which clears - * IFF_UP), so we must bring it back up here to ensure carrier changes and - * other state is noticed by the now-released port. - */ - if (!nm_device_bring_up (slave, TRUE, NULL)) { - _LOGW (LOGD_TEAM, "released team port %s could not be brought up", - nm_device_get_ip_iface (slave)); - } - - nm_clear_g_source (&priv->teamd_read_timeout); - priv->teamd_read_timeout = g_timeout_add_seconds (5, - teamd_read_timeout_cb, - self); - } else - _LOGI (LOGD_TEAM, "team port %s was released", nm_device_get_ip_iface (slave)); - - /* Delete any port configuration we previously set */ - if ( configure - && priv->tdc - && (s_port = nm_device_get_applied_setting (slave, NM_TYPE_SETTING_TEAM_PORT)) - && (nm_setting_team_port_get_config (s_port))) - teamdctl_port_config_update_raw (priv->tdc, nm_device_get_ip_iface (slave), "{}"); + NMDeviceTeam * self = NM_DEVICE_TEAM(device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); + gboolean do_release, success; + NMSettingTeamPort * s_port; + int ifindex_slave; + int ifindex; + + do_release = configure; + if (do_release) { + ifindex = nm_device_get_ifindex(device); + if (ifindex <= 0 || !nm_platform_link_get(nm_device_get_platform(device), ifindex)) + do_release = FALSE; + } + + ifindex_slave = nm_device_get_ip_ifindex(slave); + + if (ifindex_slave <= 0) { + _LOGD(LOGD_TEAM, "team port %s is already released", nm_device_get_ip_iface(slave)); + } else if (do_release) { + success = nm_platform_link_release(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + ifindex_slave); + if (success) + _LOGI(LOGD_TEAM, "released team port %s", nm_device_get_ip_iface(slave)); + else + _LOGW(LOGD_TEAM, "failed to release team port %s", nm_device_get_ip_iface(slave)); + + /* Kernel team code "closes" the port when releasing it, (which clears + * IFF_UP), so we must bring it back up here to ensure carrier changes and + * other state is noticed by the now-released port. + */ + if (!nm_device_bring_up(slave, TRUE, NULL)) { + _LOGW(LOGD_TEAM, + "released team port %s could not be brought up", + nm_device_get_ip_iface(slave)); + } + + nm_clear_g_source(&priv->teamd_read_timeout); + priv->teamd_read_timeout = g_timeout_add_seconds(5, teamd_read_timeout_cb, self); + } else + _LOGI(LOGD_TEAM, "team port %s was released", nm_device_get_ip_iface(slave)); + + /* Delete any port configuration we previously set */ + if (configure && priv->tdc + && (s_port = nm_device_get_applied_setting(slave, NM_TYPE_SETTING_TEAM_PORT)) + && (nm_setting_team_port_get_config(s_port))) + teamdctl_port_config_update_raw(priv->tdc, nm_device_get_ip_iface(slave), "{}"); } static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) { - const char *iface = nm_device_get_iface (device); - int r; - - r = nm_platform_link_team_add (nm_device_get_platform (device), iface, out_plink); - if (r < 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create team master interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_strerror (r)); - return FALSE; - } - - return TRUE; + const char *iface = nm_device_get_iface(device); + int r; + + r = nm_platform_link_team_add(nm_device_get_platform(device), iface, out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create team master interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceTeam *self = NM_DEVICE_TEAM (object); - - switch (prop_id) { - case PROP_CONFIG: - g_value_set_string (value, _get_config (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceTeam *self = NM_DEVICE_TEAM(object); + + switch (prop_id) { + case PROP_CONFIG: + g_value_set_string(value, _get_config(self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_team_init (NMDeviceTeam * self) +nm_device_team_init(NMDeviceTeam *self) { - nm_assert (nm_device_is_master (NM_DEVICE (self))); + nm_assert(nm_device_is_master(NM_DEVICE(self))); } static void -constructed (GObject *object) +constructed(GObject *object) { - NMDevice *device = NM_DEVICE (object); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); - gs_free char *tmp_str = NULL; - gs_unref_object GFile *file = NULL; - GError *error; - - G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object); - - if (nm_dbus_manager_get_dbus_connection (nm_dbus_manager_get ())) { - /* Register D-Bus name watcher */ - tmp_str = g_strdup_printf ("org.libteam.teamd.%s", nm_device_get_ip_iface (device)); - priv->teamd_dbus_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - tmp_str, - G_BUS_NAME_WATCHER_FLAGS_NONE, - teamd_dbus_appeared, - teamd_dbus_vanished, - NM_DEVICE (device), - NULL); - return; - } - - /* No D-Bus, watch unix socket */ - tmp_str = g_strdup_printf ("/run/teamd/%s.sock", - nm_device_get_ip_iface (device)); - file = g_file_new_for_path (tmp_str); - priv->usock_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); - if (!priv->usock_monitor) { - nm_log_warn (LOGD_TEAM, "error monitoring %s: %s", tmp_str, error->message); - } else { - g_signal_connect (priv->usock_monitor, - "changed", - G_CALLBACK (monitor_changed_cb), - object); - } + NMDevice * device = NM_DEVICE(object); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(device); + gs_free char * tmp_str = NULL; + gs_unref_object GFile *file = NULL; + GError * error; + + G_OBJECT_CLASS(nm_device_team_parent_class)->constructed(object); + + if (nm_dbus_manager_get_dbus_connection(nm_dbus_manager_get())) { + /* Register D-Bus name watcher */ + tmp_str = g_strdup_printf("org.libteam.teamd.%s", nm_device_get_ip_iface(device)); + priv->teamd_dbus_watch = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + tmp_str, + G_BUS_NAME_WATCHER_FLAGS_NONE, + teamd_dbus_appeared, + teamd_dbus_vanished, + NM_DEVICE(device), + NULL); + return; + } + + /* No D-Bus, watch unix socket */ + tmp_str = g_strdup_printf("/run/teamd/%s.sock", nm_device_get_ip_iface(device)); + file = g_file_new_for_path(tmp_str); + priv->usock_monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, &error); + if (!priv->usock_monitor) { + nm_log_warn(LOGD_TEAM, "error monitoring %s: %s", tmp_str, error->message); + } else { + g_signal_connect(priv->usock_monitor, "changed", G_CALLBACK(monitor_changed_cb), object); + } } NMDevice * -nm_device_team_new (const char *iface) +nm_device_team_new(const char *iface) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "team", - NM_DEVICE_TYPE_DESC, "Team", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_TEAM, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_TEAM, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_DRIVER, + "team", + NM_DEVICE_TYPE_DESC, + "Team", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_TEAM, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_TEAM, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceTeam *self = NM_DEVICE_TEAM (object); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDeviceTeam * self = NM_DEVICE_TEAM(object); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); - if (priv->teamd_dbus_watch) { - g_bus_unwatch_name (priv->teamd_dbus_watch); - priv->teamd_dbus_watch = 0; - } + if (priv->teamd_dbus_watch) { + g_bus_unwatch_name(priv->teamd_dbus_watch); + priv->teamd_dbus_watch = 0; + } - if (priv->usock_monitor) { - g_signal_handlers_disconnect_by_data (priv->usock_monitor, object); - g_clear_object (&priv->usock_monitor); - } + if (priv->usock_monitor) { + g_signal_handlers_disconnect_by_data(priv->usock_monitor, object); + g_clear_object(&priv->usock_monitor); + } - teamd_cleanup (self, TRUE); - nm_clear_g_free (&priv->config); + teamd_cleanup(self, TRUE); + nm_clear_g_free(&priv->config); - G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_team_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_team = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_TEAM, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Config", "s", NM_DEVICE_TEAM_CONFIG), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_TEAM, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", "ao", NM_DEVICE_SLAVES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Config", + "s", + NM_DEVICE_TEAM_CONFIG), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_team_class_init (NMDeviceTeamClass *klass) +nm_device_team_class_init(NMDeviceTeamClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructed = constructed; - object_class->dispose = dispose; - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_team); - - device_class->connection_type_supported = NM_SETTING_TEAM_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_TEAM_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_TEAM); - - device_class->is_master = TRUE; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; - - device_class->act_stage1_prepare_also_for_external_or_assume = TRUE; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->deactivate = deactivate; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - - obj_properties[PROP_CONFIG] = - g_param_spec_string (NM_DEVICE_TEAM_CONFIG, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_team); + + device_class->connection_type_supported = NM_SETTING_TEAM_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_TEAM_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_TEAM); + + device_class->is_master = TRUE; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->complete_connection = complete_connection; + device_class->update_connection = update_connection; + device_class->master_update_slave_connection = master_update_slave_connection; + + device_class->act_stage1_prepare_also_for_external_or_assume = TRUE; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->deactivate = deactivate; + device_class->enslave_slave = enslave_slave; + device_class->release_slave = release_slave; + + obj_properties[PROP_CONFIG] = g_param_spec_string(NM_DEVICE_TEAM_CONFIG, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/team/nm-device-team.h b/src/devices/team/nm-device-team.h index 71312c07..eabc63e6 100644 --- a/src/devices/team/nm-device-team.h +++ b/src/devices/team/nm-device-team.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 Jiri Pirko */ @@ -8,21 +8,23 @@ #include "devices/nm-device.h" -#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) -#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) -#define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) -#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TEAM)) -#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM)) -#define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type()) +#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) +#define NM_DEVICE_TEAM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_TEAM)) +#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_TEAM)) +#define NM_DEVICE_TEAM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) /* Properties */ -#define NM_DEVICE_TEAM_CONFIG "config" +#define NM_DEVICE_TEAM_CONFIG "config" -typedef struct _NMDeviceTeam NMDeviceTeam; +typedef struct _NMDeviceTeam NMDeviceTeam; typedef struct _NMDeviceTeamClass NMDeviceTeamClass; -GType nm_device_team_get_type (void); +GType nm_device_team_get_type(void); -NMDevice *nm_device_team_new (const char *iface); +NMDevice *nm_device_team_new(const char *iface); #endif /* __NETWORKMANAGER_DEVICE_TEAM_H__ */ diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c index 3768217b..644bef1c 100644 --- a/src/devices/team/nm-team-factory.c +++ b/src/devices/team/nm-team-factory.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -15,63 +15,63 @@ /*****************************************************************************/ -#define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type ()) -#define NM_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) -#define NM_TEAM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEAM_FACTORY, NMTeamFactoryClass)) -#define NM_IS_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_TEAM_FACTORY)) -#define NM_IS_TEAM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_TEAM_FACTORY)) -#define NM_TEAM_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactoryClass)) +#define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type()) +#define NM_TEAM_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) +#define NM_TEAM_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_TEAM_FACTORY, NMTeamFactoryClass)) +#define NM_IS_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_TEAM_FACTORY)) +#define NM_IS_TEAM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_TEAM_FACTORY)) +#define NM_TEAM_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactoryClass)) typedef struct { - NMDeviceFactory parent; + NMDeviceFactory parent; } NMTeamFactory; typedef struct { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; } NMTeamFactoryClass; -static GType nm_team_factory_get_type (void); +static GType nm_team_factory_get_type(void); -G_DEFINE_TYPE (NMTeamFactory, nm_team_factory, NM_TYPE_DEVICE_FACTORY) +G_DEFINE_TYPE(NMTeamFactory, nm_team_factory, NM_TYPE_DEVICE_FACTORY) /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_TEAM) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_TEAM_SETTING_NAME) -) +NM_DEVICE_FACTORY_DECLARE_TYPES(NM_DEVICE_FACTORY_DECLARE_LINK_TYPES( + NM_LINK_TYPE_TEAM) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_TEAM_SETTING_NAME)) G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - nm_manager_set_capability (NM_MANAGER_GET, NM_CAPABILITY_TEAM); - return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL); + nm_manager_set_capability(NM_MANAGER_GET, NM_CAPABILITY_TEAM); + return (NMDeviceFactory *) g_object_new(NM_TYPE_TEAM_FACTORY, NULL); } /*****************************************************************************/ static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - return nm_device_team_new (iface); + return nm_device_team_new(iface); } /*****************************************************************************/ static void -nm_team_factory_init (NMTeamFactory *self) -{ -} +nm_team_factory_init(NMTeamFactory *self) +{} static void -nm_team_factory_class_init (NMTeamFactoryClass *klass) +nm_team_factory_class_init(NMTeamFactoryClass *klass) { - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - factory_class->create_device = create_device; - factory_class->get_supported_types = get_supported_types; + factory_class->create_device = create_device; + factory_class->get_supported_types = get_supported_types; } diff --git a/src/devices/tests/test-acd.c b/src/devices/tests/test-acd.c index 32d6f669..da7b3c3d 100644 --- a/src/devices/tests/test-acd.c +++ b/src/devices/tests/test-acd.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -21,212 +21,237 @@ /*****************************************************************************/ static gboolean -_skip_acd_test_check (void) +_skip_acd_test_check(void) { - NAcd *acd; - NAcdConfig *config; - const guint8 hwaddr[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; - int r; - static int skip = -1; - - if (skip == -1) { - r = n_acd_config_new (&config); - g_assert (r == 0); - - n_acd_config_set_ifindex (config, 1); - n_acd_config_set_transport (config, N_ACD_TRANSPORT_ETHERNET); - n_acd_config_set_mac (config, hwaddr, sizeof (hwaddr)); - - r = n_acd_new (&acd, config); - n_acd_config_free (config); - if (r == 0) - n_acd_unref (acd); - - skip = (r != 0); - } - return skip; + NAcd * acd; + NAcdConfig * config; + const guint8 hwaddr[ETH_ALEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + int r; + static int skip = -1; + + if (skip == -1) { + r = n_acd_config_new(&config); + g_assert(r == 0); + + n_acd_config_set_ifindex(config, 1); + n_acd_config_set_transport(config, N_ACD_TRANSPORT_ETHERNET); + n_acd_config_set_mac(config, hwaddr, sizeof(hwaddr)); + + r = n_acd_new(&acd, config); + n_acd_config_free(config); + if (r == 0) + n_acd_unref(acd); + + skip = (r != 0); + } + return skip; } -#define _skip_acd_test() \ - ({ \ - gboolean _skip = _skip_acd_test_check (); \ - \ - if (_skip) \ - g_test_skip ("Cannot create NAcd. Running under valgind?"); \ - _skip; \ - }) +#define _skip_acd_test() \ + ({ \ + gboolean _skip = _skip_acd_test_check(); \ + \ + if (_skip) \ + g_test_skip("Cannot create NAcd. Running under valgind?"); \ + _skip; \ + }) /*****************************************************************************/ typedef struct { - int ifindex0; - int ifindex1; - const guint8 *hwaddr0; - const guint8 *hwaddr1; - size_t hwaddr0_len; - size_t hwaddr1_len; + int ifindex0; + int ifindex1; + const guint8 *hwaddr0; + const guint8 *hwaddr1; + size_t hwaddr0_len; + size_t hwaddr1_len; } test_fixture; static void -fixture_setup (test_fixture *fixture, gconstpointer user_data) +fixture_setup(test_fixture *fixture, gconstpointer user_data) { - /* create veth pair. */ - fixture->ifindex0 = nmtstp_link_veth_add (NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; - fixture->ifindex1 = nmtstp_link_get_typed (NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; - - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, fixture->ifindex0, NULL)); - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, fixture->ifindex1, NULL)); - - fixture->hwaddr0 = nm_platform_link_get_address (NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len); - fixture->hwaddr1 = nm_platform_link_get_address (NM_PLATFORM_GET, fixture->ifindex1, &fixture->hwaddr1_len); + /* create veth pair. */ + fixture->ifindex0 = + nmtstp_link_veth_add(NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; + fixture->ifindex1 = + nmtstp_link_get_typed(NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; + + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex0, NULL)); + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex1, NULL)); + + fixture->hwaddr0 = + nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len); + fixture->hwaddr1 = + nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex1, &fixture->hwaddr1_len); } typedef struct { - in_addr_t addresses[8]; - in_addr_t peer_addresses[8]; - gboolean expected_result[8]; + in_addr_t addresses[8]; + in_addr_t peer_addresses[8]; + gboolean expected_result[8]; } TestInfo; static void -acd_manager_probe_terminated (NMAcdManager *acd_manager, gpointer user_data) +acd_manager_probe_terminated(NMAcdManager *acd_manager, gpointer user_data) { - g_main_loop_quit (user_data); + g_main_loop_quit(user_data); } static void -test_acd_common (test_fixture *fixture, TestInfo *info) +test_acd_common(test_fixture *fixture, TestInfo *info) { - nm_auto_free_acdmgr NMAcdManager *manager = NULL; - nm_auto_unref_gmainloop GMainLoop *loop = NULL; - int i; - const guint WAIT_TIME_OPTIMISTIC = 50; - guint wait_time; - static const NMAcdCallbacks callbacks = { - .probe_terminated_callback = acd_manager_probe_terminated, - .user_data_destroy = (GDestroyNotify) g_main_loop_unref, - }; - int r; - - if (_skip_acd_test ()) - return; - - /* first, try with a short waittime. We hope that this is long enough - * to successfully complete the test. Only if that's not the case, we - * assume the computer is currently busy (high load) and we retry with - * a longer timeout. */ - wait_time = WAIT_TIME_OPTIMISTIC; + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + int i; + const guint WAIT_TIME_OPTIMISTIC = 50; + guint wait_time; + static const NMAcdCallbacks callbacks = { + .probe_terminated_callback = acd_manager_probe_terminated, + .user_data_destroy = (GDestroyNotify) g_main_loop_unref, + }; + int r; + + if (_skip_acd_test()) + return; + + /* first, try with a short waittime. We hope that this is long enough + * to successfully complete the test. Only if that's not the case, we + * assume the computer is currently busy (high load) and we retry with + * a longer timeout. */ + wait_time = WAIT_TIME_OPTIMISTIC; again: - nm_clear_pointer (&loop, g_main_loop_unref); - loop = g_main_loop_new (NULL, FALSE); - - nm_clear_pointer (&manager, nm_acd_manager_free); - manager = nm_acd_manager_new (fixture->ifindex0, - fixture->hwaddr0, - fixture->hwaddr0_len, - &callbacks, - g_main_loop_ref (loop)); - g_assert (manager != NULL); - - for (i = 0; info->addresses[i]; i++) - g_assert (nm_acd_manager_add_address (manager, info->addresses[i])); - - for (i = 0; info->peer_addresses[i]; i++) { - nmtstp_ip4_address_add (NULL, FALSE, fixture->ifindex1, info->peer_addresses[i], - 24, 0, 3600, 1800, 0, NULL); - } - - r = nm_acd_manager_start_probe (manager, wait_time); - g_assert_cmpint (r, ==, 0); - - g_assert (nmtst_main_loop_run (loop, 2000)); - - for (i = 0; info->addresses[i]; i++) { - gboolean val; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - val = nm_acd_manager_check_address (manager, info->addresses[i]); - if (val == info->expected_result[i]) - continue; - - if (wait_time == WAIT_TIME_OPTIMISTIC) { - /* probably we just had a glitch and the system took longer than - * expected. Re-verify with a large timeout this time. */ - wait_time = 1000; - goto again; - } - - g_error ("expected check for address #%d (%s) to %s, but it didn't", - i, _nm_utils_inet4_ntop (info->addresses[i], sbuf), - info->expected_result[i] ? "detect no duplicated" : "detect a duplicate"); - } + nm_clear_pointer(&loop, g_main_loop_unref); + loop = g_main_loop_new(NULL, FALSE); + + nm_clear_pointer(&manager, nm_acd_manager_free); + manager = nm_acd_manager_new(fixture->ifindex0, + fixture->hwaddr0, + fixture->hwaddr0_len, + &callbacks, + g_main_loop_ref(loop)); + g_assert(manager != NULL); + + for (i = 0; info->addresses[i]; i++) + g_assert(nm_acd_manager_add_address(manager, info->addresses[i])); + + for (i = 0; info->peer_addresses[i]; i++) { + nmtstp_ip4_address_add(NULL, + FALSE, + fixture->ifindex1, + info->peer_addresses[i], + 24, + 0, + 3600, + 1800, + 0, + NULL); + } + + r = nm_acd_manager_start_probe(manager, wait_time); + g_assert_cmpint(r, ==, 0); + + g_assert(nmtst_main_loop_run(loop, 2000)); + + for (i = 0; info->addresses[i]; i++) { + gboolean val; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + val = nm_acd_manager_check_address(manager, info->addresses[i]); + if (val == info->expected_result[i]) + continue; + + if (wait_time == WAIT_TIME_OPTIMISTIC) { + /* probably we just had a glitch and the system took longer than + * expected. Re-verify with a large timeout this time. */ + wait_time = 1000; + goto again; + } + + g_error("expected check for address #%d (%s) to %s, but it didn't", + i, + _nm_utils_inet4_ntop(info->addresses[i], sbuf), + info->expected_result[i] ? "detect no duplicated" : "detect a duplicate"); + } } static void -test_acd_probe_1 (test_fixture *fixture, gconstpointer user_data) +test_acd_probe_1(test_fixture *fixture, gconstpointer user_data) { - TestInfo info = { .addresses = { ADDR1, ADDR2, ADDR3 }, - .peer_addresses = { ADDR4 }, - .expected_result = { TRUE, TRUE, TRUE } }; + TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3}, + .peer_addresses = {ADDR4}, + .expected_result = {TRUE, TRUE, TRUE}}; - test_acd_common (fixture, &info); + test_acd_common(fixture, &info); } static void -test_acd_probe_2 (test_fixture *fixture, gconstpointer user_data) +test_acd_probe_2(test_fixture *fixture, gconstpointer user_data) { - TestInfo info = { .addresses = { ADDR1, ADDR2, ADDR3, ADDR4 }, - .peer_addresses = { ADDR3, ADDR2 }, - .expected_result = { TRUE, FALSE, FALSE, TRUE } }; + TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3, ADDR4}, + .peer_addresses = {ADDR3, ADDR2}, + .expected_result = {TRUE, FALSE, FALSE, TRUE}}; - test_acd_common (fixture, &info); + test_acd_common(fixture, &info); } static void -test_acd_announce (test_fixture *fixture, gconstpointer user_data) +test_acd_announce(test_fixture *fixture, gconstpointer user_data) { - nm_auto_free_acdmgr NMAcdManager *manager = NULL; - nm_auto_unref_gmainloop GMainLoop *loop = NULL; - int r; - - if (_skip_acd_test ()) - return; - - manager = nm_acd_manager_new (fixture->ifindex0, - fixture->hwaddr0, - fixture->hwaddr0_len, - NULL, - NULL); - g_assert (manager != NULL); - - g_assert (nm_acd_manager_add_address (manager, ADDR1)); - g_assert (nm_acd_manager_add_address (manager, ADDR2)); - - loop = g_main_loop_new (NULL, FALSE); - r = nm_acd_manager_announce_addresses (manager); - g_assert_cmpint (r, ==, 0); - g_assert (!nmtst_main_loop_run (loop, 200)); + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + int r; + + if (_skip_acd_test()) + return; + + manager = + nm_acd_manager_new(fixture->ifindex0, fixture->hwaddr0, fixture->hwaddr0_len, NULL, NULL); + g_assert(manager != NULL); + + g_assert(nm_acd_manager_add_address(manager, ADDR1)); + g_assert(nm_acd_manager_add_address(manager, ADDR2)); + + loop = g_main_loop_new(NULL, FALSE); + r = nm_acd_manager_announce_addresses(manager); + g_assert_cmpint(r, ==, 0); + g_assert(!nmtst_main_loop_run(loop, 200)); } static void -fixture_teardown (test_fixture *fixture, gconstpointer user_data) +fixture_teardown(test_fixture *fixture, gconstpointer user_data) { - nm_platform_link_delete (NM_PLATFORM_GET, fixture->ifindex0); - nm_platform_link_delete (NM_PLATFORM_GET, fixture->ifindex1); + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex0); + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex1); } NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { - g_test_add ("/acd/probe/1", test_fixture, NULL, fixture_setup, test_acd_probe_1, fixture_teardown); - g_test_add ("/acd/probe/2", test_fixture, NULL, fixture_setup, test_acd_probe_2, fixture_teardown); - g_test_add ("/acd/announce", test_fixture, NULL, fixture_setup, test_acd_announce, fixture_teardown); + g_test_add("/acd/probe/1", + test_fixture, + NULL, + fixture_setup, + test_acd_probe_1, + fixture_teardown); + g_test_add("/acd/probe/2", + test_fixture, + NULL, + fixture_setup, + test_acd_probe_2, + fixture_teardown); + g_test_add("/acd/announce", + test_fixture, + NULL, + fixture_setup, + test_acd_announce, + fixture_teardown); } diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c index d710327a..5c912b7d 100644 --- a/src/devices/tests/test-lldp.c +++ b/src/devices/tests/test-lldp.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -21,568 +21,1247 @@ /*****************************************************************************/ static GVariant * -get_lldp_neighbor (GVariant *neighbors, - int chassis_id_type, - const char *chassis_id, - int port_id_type, - const char *port_id) +get_lldp_neighbor(GVariant * neighbors, + int chassis_id_type, + const char *chassis_id, + int port_id_type, + const char *port_id) { - GVariantIter iter; - GVariant *variant; - GVariant *result = NULL; - - nmtst_assert_variant_is_of_type (neighbors, G_VARIANT_TYPE ("aa{sv}")); - - g_assert (chassis_id_type >= -1 && chassis_id_type <= G_MAXUINT8); - g_assert (port_id_type >= -1 && port_id_type <= G_MAXUINT8); - - g_variant_iter_init (&iter, neighbors); - while (g_variant_iter_next (&iter, "@a{sv}", &variant)) { - gs_unref_variant GVariant *v_chassis_id_type = NULL; - gs_unref_variant GVariant *v_chassis_id = NULL; - gs_unref_variant GVariant *v_port_id_type = NULL; - gs_unref_variant GVariant *v_port_id = NULL; - - v_chassis_id_type = g_variant_lookup_value (variant, NM_LLDP_ATTR_CHASSIS_ID_TYPE, G_VARIANT_TYPE_UINT32); - g_assert (v_chassis_id_type); - - v_chassis_id = g_variant_lookup_value (variant, NM_LLDP_ATTR_CHASSIS_ID, G_VARIANT_TYPE_STRING); - g_assert (v_chassis_id); - - v_port_id_type = g_variant_lookup_value (variant, NM_LLDP_ATTR_PORT_ID_TYPE, G_VARIANT_TYPE_UINT32); - g_assert (v_port_id_type); - - v_port_id = g_variant_lookup_value (variant, NM_LLDP_ATTR_PORT_ID, G_VARIANT_TYPE_STRING); - g_assert (v_port_id); - - if ( nm_streq (g_variant_get_string (v_chassis_id, NULL), chassis_id) - && nm_streq (g_variant_get_string (v_port_id, NULL), port_id) - && NM_IN_SET (chassis_id_type, -1, g_variant_get_uint32 (v_chassis_id_type)) - && NM_IN_SET (port_id_type, -1, g_variant_get_uint32 (v_port_id_type))) { - g_assert (!result); - result = variant; - } else - g_variant_unref (variant); - } - - return result; + GVariantIter iter; + GVariant * variant; + GVariant * result = NULL; + + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + + g_assert(chassis_id_type >= -1 && chassis_id_type <= G_MAXUINT8); + g_assert(port_id_type >= -1 && port_id_type <= G_MAXUINT8); + + g_variant_iter_init(&iter, neighbors); + while (g_variant_iter_next(&iter, "@a{sv}", &variant)) { + gs_unref_variant GVariant *v_chassis_id_type = NULL; + gs_unref_variant GVariant *v_chassis_id = NULL; + gs_unref_variant GVariant *v_port_id_type = NULL; + gs_unref_variant GVariant *v_port_id = NULL; + + v_chassis_id_type = + g_variant_lookup_value(variant, NM_LLDP_ATTR_CHASSIS_ID_TYPE, G_VARIANT_TYPE_UINT32); + g_assert(v_chassis_id_type); + + v_chassis_id = + g_variant_lookup_value(variant, NM_LLDP_ATTR_CHASSIS_ID, G_VARIANT_TYPE_STRING); + g_assert(v_chassis_id); + + v_port_id_type = + g_variant_lookup_value(variant, NM_LLDP_ATTR_PORT_ID_TYPE, G_VARIANT_TYPE_UINT32); + g_assert(v_port_id_type); + + v_port_id = g_variant_lookup_value(variant, NM_LLDP_ATTR_PORT_ID, G_VARIANT_TYPE_STRING); + g_assert(v_port_id); + + if (nm_streq(g_variant_get_string(v_chassis_id, NULL), chassis_id) + && nm_streq(g_variant_get_string(v_port_id, NULL), port_id) + && NM_IN_SET(chassis_id_type, -1, g_variant_get_uint32(v_chassis_id_type)) + && NM_IN_SET(port_id_type, -1, g_variant_get_uint32(v_port_id_type))) { + g_assert(!result); + result = variant; + } else + g_variant_unref(variant); + } + + return result; } typedef struct { - int ifindex; - int fd; - guint8 mac[ETH_ALEN]; + int ifindex; + int fd; + guint8 mac[ETH_ALEN]; } TestRecvFixture; typedef struct { - gsize frame_len; - const uint8_t *frame; - const char *as_variant; + gsize frame_len; + const uint8_t *frame; + const char * as_variant; } TestRecvFrame; -#define TEST_RECV_FRAME_DEFINE(name, _as_variant, ...) \ - static const guint8 _##name##_v[] = { __VA_ARGS__ }; \ - static const TestRecvFrame name = { \ - .as_variant = _as_variant, \ - .frame_len = sizeof (_##name##_v), \ - .frame = _##name##_v, \ - } +#define TEST_RECV_FRAME_DEFINE(name, _as_variant, ...) \ + static const guint8 _##name##_v[] = {__VA_ARGS__}; \ + static const TestRecvFrame name = { \ + .as_variant = _as_variant, \ + .frame_len = sizeof(_##name##_v), \ + .frame = _##name##_v, \ + } typedef struct { - guint expected_num_called; - gsize frames_len; - const TestRecvFrame *frames[10]; - void (*check) (GMainLoop *loop, NMLldpListener *listener); + guint expected_num_called; + gsize frames_len; + const TestRecvFrame *frames[10]; + void (*check)(GMainLoop *loop, NMLldpListener *listener); } TestRecvData; #define TEST_RECV_DATA_DEFINE(name, _expected_num_called, _check, ...) \ - static const TestRecvData name = { \ - .expected_num_called = _expected_num_called, \ - .check = _check, \ - .frames_len = NM_NARG (__VA_ARGS__), \ - .frames = { __VA_ARGS__ }, \ - } + static const TestRecvData name = { \ + .expected_num_called = _expected_num_called, \ + .check = _check, \ + .frames_len = NM_NARG(__VA_ARGS__), \ + .frames = {__VA_ARGS__}, \ + } #define TEST_IFNAME "nm-tap-test0" -TEST_RECV_FRAME_DEFINE (_test_recv_data0_frame0, - "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, 0x06, 0x02, 0x00, 0x78, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, 0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': , 'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': , 'port-id': <'1/3'>, 'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': <'SYS'>, 'system-description': <'foo'>}", - /* Ethernet header */ - 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC */ - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */ - 0x88, 0xcc, /* Ethertype */ - /* LLDP mandatory TLVs */ - 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ - 0x03, 0x04, 0x05, - 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port: interface name, "1/3" */ - 0x06, 0x02, 0x00, 0x78, /* TTL: 120 seconds */ - /* LLDP optional TLVs */ - 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, /* Port Description: "Port" */ - 0x0a, 0x03, 0x53, 0x59, 0x53, /* System Name: "SYS" */ - 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, /* System Description: "foo" (NULL-terminated) */ - 0x00, 0x00 /* End Of LLDPDU */ +TEST_RECV_FRAME_DEFINE( + _test_recv_data0_frame0, + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x33, 0x06, 0x02, 0x00, 0x78, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, " + "0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': , " + "'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': , 'port-id': <'1/3'>, " + "'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': " + "<'SYS'>, 'system-description': <'foo'>}", + /* Ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x03, /* Destination MAC */ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, /* Source MAC */ + 0x88, + 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, + 0x04, + 0x05, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x33, /* Port: interface name, "1/3" */ + 0x06, + 0x02, + 0x00, + 0x78, /* TTL: 120 seconds */ + /* LLDP optional TLVs */ + 0x08, + 0x04, + 0x50, + 0x6f, + 0x72, + 0x74, /* Port Description: "Port" */ + 0x0a, + 0x03, + 0x53, + 0x59, + 0x53, /* System Name: "SYS" */ + 0x0c, + 0x04, + 0x66, + 0x6f, + 0x6f, + 0x00, /* System Description: "foo" (NULL-terminated) */ + 0x00, + 0x00 /* End Of LLDPDU */ ); static void -_test_recv_data0_check_do (GMainLoop *loop, NMLldpListener *listener, const TestRecvFrame *frame) +_test_recv_data0_check_do(GMainLoop *loop, NMLldpListener *listener, const TestRecvFrame *frame) { - GVariant *neighbors, *attr; - gs_unref_variant GVariant *neighbor = NULL; - - neighbors = nm_lldp_listener_get_neighbors (listener); - nmtst_assert_variant_is_of_type (neighbors, G_VARIANT_TYPE ("aa{sv}")); - g_assert_cmpint (g_variant_n_children (neighbors), ==, 1); - - neighbor = get_lldp_neighbor (neighbors, - SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:02:03:04:05", - SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/3"); - g_assert (neighbor); - g_assert_cmpint (g_variant_n_children (neighbor), ==, 1 + 4 + 4); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); - nmtst_assert_variant_bytestring (attr, frame->frame, frame->frame_len); - nm_clear_g_variant (&attr); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "Port"); - nm_clear_g_variant (&attr); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "SYS"); - nm_clear_g_variant (&attr); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE); - nm_clear_g_variant (&attr); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "foo"); - nm_clear_g_variant (&attr); + GVariant * neighbors, *attr; + gs_unref_variant GVariant *neighbor = NULL; + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 1); + + neighbor = get_lldp_neighbor(neighbors, + SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, + "00:01:02:03:04:05", + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, + "1/3"); + g_assert(neighbor); + g_assert_cmpint(g_variant_n_children(neighbor), ==, 1 + 4 + 4); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, frame->frame, frame->frame_len); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Port"); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "SYS"); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "foo"); + nm_clear_g_variant(&attr); } static void -_test_recv_data0_check (GMainLoop *loop, NMLldpListener *listener) +_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener) { - _test_recv_data0_check_do (loop, listener, &_test_recv_data0_frame0); + _test_recv_data0_check_do(loop, listener, &_test_recv_data0_frame0); } -TEST_RECV_DATA_DEFINE (_test_recv_data0, 1, _test_recv_data0_check, &_test_recv_data0_frame0); -TEST_RECV_DATA_DEFINE (_test_recv_data0_twice, 1, _test_recv_data0_check, &_test_recv_data0_frame0, &_test_recv_data0_frame0); - -TEST_RECV_FRAME_DEFINE (_test_recv_data1_frame0, - /* lldp.detailed.pcap from - * https://wiki.wireshark.org/SampleCaptures#Link_Layer_Discovery_Protocol_.28LLDP.29 */ - "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x04, 0x04, 0x05, 0x31, 0x2f, 0x31, 0x06, 0x02, 0x00, 0x78, 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, 0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x00, 0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x20, 0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, 0x31, 0x20, 0x28, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, 0x35, 0x33, 0x3a, 0x31, 0x31, 0x00, 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00, 0xfe, 0x07, 0x00, 0x12, 0x0f, 0x02, 0x07, 0x01, 0x00, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x00, 0x00, 0x10, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x12, 0x0f, 0x04, 0x05, 0xf2, 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, 0x01, 0xe8, 0xfe, 0x07, 0x00, 0x80, 0xc2, 0x02, 0x01, 0x00, 0x00, 0xfe, 0x16, 0x00, 0x80, 0xc2, 0x03, 0x01, 0xe8, 0x0f, 0x76, 0x32, 0x2d, 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x35, 0x30, 0x35, 0xfe, 0x05, 0x00, 0x80, 0xc2, 0x04, 0x00, 0x00, 0x00]>, 'chassis-id-type': , 'chassis-id': <'00:01:30:F9:AD:A0'>, 'port-id-type': , 'port-id': <'1/1'>, 'destination': <'nearest-bridge'>, 'port-description': <'Summit300-48-Port 1001'>, 'system-name': <'Summit300-48'>, 'system-description': <'Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11'>, 'system-capabilities': , 'management-addresses': <[{'address-subtype': , 'address': <[byte 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0]>, 'interface-number-subtype': , 'interface-number': }]>, 'ieee-802-1-pvid': , 'ieee-802-1-ppvid': , 'ieee-802-1-ppvid-flags': , 'ieee-802-1-ppvids': <[{'ppvid': , 'flags': }]>, 'ieee-802-1-vid': , 'ieee-802-1-vlan-name': <'v2-0488-03-0505'>, 'ieee-802-1-vlans': <[{'vid': , 'name': <'v2-0488-03-0505'>}]>, 'ieee-802-3-mac-phy-conf': <{'autoneg': , 'pmd-autoneg-cap': , 'operational-mau-type': }>, 'ieee-802-3-power-via-mdi': <{'mdi-power-support': , 'pse-power-pair': , 'power-class': }>, 'ieee-802-3-max-frame-size': }", - /* ethernet header */ - 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, /* destination mac */ - 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, /* source mac */ - 0x88, 0xcc, /* ethernet type */ - - 0x02, 0x07, 0x04, 0x00, 0x01, 0x30, /* Chassis Subtype */ - 0xf9, 0xad, 0xa0, - 0x04, 0x04, 0x05, 0x31, 0x2f, 0x31, /* Port Subtype */ - 0x06, 0x02, 0x00, 0x78, /* Time To Live */ - 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, /* Port Description */ - 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, - 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, - 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, - 0x00, - 0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, /* System Name */ - 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, - 0x34, 0x38, 0x00, - 0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, /* System Description */ - 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, - 0x34, 0x38, 0x20, 0x2d, 0x20, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, - 0x31, 0x20, 0x28, 0x42, 0x75, 0x69, - 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, - 0x62, 0x79, 0x20, 0x52, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, - 0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, - 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, - 0x35, 0x33, 0x3a, 0x31, 0x31, 0x00, - 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, /* Capabilities */ - 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, /* Management Address */ - 0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, - 0x00, 0x03, 0xe9, 0x00, - 0xfe, 0x07, 0x00, 0x12, 0x0f, 0x02, /* IEEE 802.3 - Power Via MDI */ - 0x07, 0x01, 0x00, - 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, /* IEEE 802.3 - MAC/PHY Configuration/Status */ - 0x03, 0x6c, 0x00, 0x00, 0x10, - 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, /* IEEE 802.3 - Link Aggregation */ - 0x01, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x06, 0x00, 0x12, 0x0f, 0x04, /* IEEE 802.3 - Maximum Frame Size */ - 0x05, 0xf2, - 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, /* IEEE 802.1 - Port VLAN ID */ - 0x01, 0xe8, - 0xfe, 0x07, 0x00, 0x80, 0xc2, 0x02, /* IEEE 802.1 - Port and Protocol VLAN ID */ - 0x01, 0x00, 0x00, - 0xfe, 0x16, 0x00, 0x80, 0xc2, 0x03, /* IEEE 802.1 - VLAN Name */ - 0x01, 0xe8, 0x0f, 0x76, 0x32, 0x2d, - 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, - 0x33, 0x2d, 0x30, 0x35, 0x30, 0x35, - 0xfe, 0x05, 0x00, 0x80, 0xc2, 0x04, /* IEEE 802.1 - Protocol Identity */ - 0x00, - 0x00, 0x00 /* End of LLDPDU */ +TEST_RECV_DATA_DEFINE(_test_recv_data0, 1, _test_recv_data0_check, &_test_recv_data0_frame0); +TEST_RECV_DATA_DEFINE(_test_recv_data0_twice, + 1, + _test_recv_data0_check, + &_test_recv_data0_frame0, + &_test_recv_data0_frame0); + +TEST_RECV_FRAME_DEFINE( + _test_recv_data1_frame0, + /* lldp.detailed.pcap from + * https://wiki.wireshark.org/SampleCaptures#Link_Layer_Discovery_Protocol_.28LLDP.29 */ + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x31, 0x06, 0x02, 0x00, 0x78, 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, " + "0x30, 0x2d, 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, " + "0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x00, " + "0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x20, " + "0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, " + "0x31, 0x20, 0x28, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, " + "0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, " + "0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, 0x35, 0x33, 0x3a, " + "0x31, 0x31, 0x00, 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, " + "0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00, 0xfe, 0x07, 0x00, 0x12, 0x0f, " + "0x02, 0x07, 0x01, 0x00, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x00, 0x00, 0x10, " + "0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x12, " + "0x0f, 0x04, 0x05, 0xf2, 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, 0x01, 0xe8, 0xfe, 0x07, 0x00, " + "0x80, 0xc2, 0x02, 0x01, 0x00, 0x00, 0xfe, 0x16, 0x00, 0x80, 0xc2, 0x03, 0x01, 0xe8, 0x0f, " + "0x76, 0x32, 0x2d, 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x35, 0x30, 0x35, " + "0xfe, 0x05, 0x00, 0x80, 0xc2, 0x04, 0x00, 0x00, 0x00]>, 'chassis-id-type': , " + "'chassis-id': <'00:01:30:F9:AD:A0'>, 'port-id-type': , 'port-id': <'1/1'>, " + "'destination': <'nearest-bridge'>, 'port-description': <'Summit300-48-Port 1001'>, " + "'system-name': <'Summit300-48'>, 'system-description': <'Summit300-48 - Version 7.4e.1 (Build " + "5) by Release_Master 05/27/05 04:53:11'>, 'system-capabilities': , " + "'management-addresses': <[{'address-subtype': , 'address': <[byte 0x00, 0x01, 0x30, " + "0xf9, 0xad, 0xa0]>, 'interface-number-subtype': , 'interface-number': }]>, 'ieee-802-1-pvid': , 'ieee-802-1-ppvid': , " + "'ieee-802-1-ppvid-flags': , 'ieee-802-1-ppvids': <[{'ppvid': , 'flags': " + "}]>, 'ieee-802-1-vid': , 'ieee-802-1-vlan-name': <'v2-0488-03-0505'>, " + "'ieee-802-1-vlans': <[{'vid': , 'name': <'v2-0488-03-0505'>}]>, " + "'ieee-802-3-mac-phy-conf': <{'autoneg': , 'pmd-autoneg-cap': , " + "'operational-mau-type': }>, 'ieee-802-3-power-via-mdi': <{'mdi-power-support': " + ", 'pse-power-pair': , 'power-class': }>, " + "'ieee-802-3-max-frame-size': }", + /* ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x0e, /* destination mac */ + 0x00, + 0x01, + 0x30, + 0xf9, + 0xad, + 0xa0, /* source mac */ + 0x88, + 0xcc, /* ethernet type */ + + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x30, /* Chassis Subtype */ + 0xf9, + 0xad, + 0xa0, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x31, /* Port Subtype */ + 0x06, + 0x02, + 0x00, + 0x78, /* Time To Live */ + 0x08, + 0x17, + 0x53, + 0x75, + 0x6d, + 0x6d, /* Port Description */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x2d, + 0x50, + 0x6f, + 0x72, + 0x74, + 0x20, + 0x31, + 0x30, + 0x30, + 0x31, + 0x00, + 0x0a, + 0x0d, + 0x53, + 0x75, + 0x6d, + 0x6d, /* System Name */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x00, + 0x0c, + 0x4c, + 0x53, + 0x75, + 0x6d, + 0x6d, /* System Description */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x20, + 0x2d, + 0x20, + 0x56, + 0x65, + 0x72, + 0x73, + 0x69, + 0x6f, + 0x6e, + 0x20, + 0x37, + 0x2e, + 0x34, + 0x65, + 0x2e, + 0x31, + 0x20, + 0x28, + 0x42, + 0x75, + 0x69, + 0x6c, + 0x64, + 0x20, + 0x35, + 0x29, + 0x20, + 0x62, + 0x79, + 0x20, + 0x52, + 0x65, + 0x6c, + 0x65, + 0x61, + 0x73, + 0x65, + 0x5f, + 0x4d, + 0x61, + 0x73, + 0x74, + 0x65, + 0x72, + 0x20, + 0x30, + 0x35, + 0x2f, + 0x32, + 0x37, + 0x2f, + 0x30, + 0x35, + 0x20, + 0x30, + 0x34, + 0x3a, + 0x35, + 0x33, + 0x3a, + 0x31, + 0x31, + 0x00, + 0x0e, + 0x04, + 0x00, + 0x14, + 0x00, + 0x14, /* Capabilities */ + 0x10, + 0x0e, + 0x07, + 0x06, + 0x00, + 0x01, /* Management Address */ + 0x30, + 0xf9, + 0xad, + 0xa0, + 0x02, + 0x00, + 0x00, + 0x03, + 0xe9, + 0x00, + 0xfe, + 0x07, + 0x00, + 0x12, + 0x0f, + 0x02, /* IEEE 802.3 - Power Via MDI */ + 0x07, + 0x01, + 0x00, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x01, /* IEEE 802.3 - MAC/PHY Configuration/Status */ + 0x03, + 0x6c, + 0x00, + 0x00, + 0x10, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x03, /* IEEE 802.3 - Link Aggregation */ + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfe, + 0x06, + 0x00, + 0x12, + 0x0f, + 0x04, /* IEEE 802.3 - Maximum Frame Size */ + 0x05, + 0xf2, + 0xfe, + 0x06, + 0x00, + 0x80, + 0xc2, + 0x01, /* IEEE 802.1 - Port VLAN ID */ + 0x01, + 0xe8, + 0xfe, + 0x07, + 0x00, + 0x80, + 0xc2, + 0x02, /* IEEE 802.1 - Port and Protocol VLAN ID */ + 0x01, + 0x00, + 0x00, + 0xfe, + 0x16, + 0x00, + 0x80, + 0xc2, + 0x03, /* IEEE 802.1 - VLAN Name */ + 0x01, + 0xe8, + 0x0f, + 0x76, + 0x32, + 0x2d, + 0x30, + 0x34, + 0x38, + 0x38, + 0x2d, + 0x30, + 0x33, + 0x2d, + 0x30, + 0x35, + 0x30, + 0x35, + 0xfe, + 0x05, + 0x00, + 0x80, + 0xc2, + 0x04, /* IEEE 802.1 - Protocol Identity */ + 0x00, + 0x00, + 0x00 /* End of LLDPDU */ ); static void -_test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) +_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener) { - GVariant *neighbors, *attr, *child; - gs_unref_variant GVariant *neighbor = NULL; - guint v_uint = 0; - const char *v_str = NULL; - - neighbors = nm_lldp_listener_get_neighbors (listener); - nmtst_assert_variant_is_of_type (neighbors, G_VARIANT_TYPE ("aa{sv}")); - g_assert_cmpint (g_variant_n_children (neighbors), ==, 1); - - neighbor = get_lldp_neighbor (neighbors, - SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:30:F9:AD:A0", - SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/1"); - g_assert (neighbor); - g_assert_cmpint (g_variant_n_children (neighbor), ==, 1 + 4 + 16); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); - nmtst_assert_variant_bytestring (attr, _test_recv_data1_frame0.frame, _test_recv_data1_frame0.frame_len); - nm_clear_g_variant (&attr); - - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, NM_LLDP_DEST_NEAREST_BRIDGE); - nm_clear_g_variant (&attr); - - /* unsupported: Time To Live */ - - /* Port Description */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "Summit300-48-Port 1001"); - nm_clear_g_variant (&attr); - - /* System Name */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "Summit300-48"); - nm_clear_g_variant (&attr); - - /* System Description */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11"); - nm_clear_g_variant (&attr); - - /* Capabilities */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 20); - nm_clear_g_variant (&attr); - - /* Management Address */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, G_VARIANT_TYPE ("aa{sv}")); - g_assert (attr); - g_assert_cmpuint (g_variant_n_children (attr), ==, 1); - child = g_variant_get_child_value (attr, 0); - g_assert (child); - g_assert (g_variant_lookup (child, "interface-number", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 1001); - g_assert (g_variant_lookup (child, "interface-number-subtype", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 2); - g_assert (g_variant_lookup (child, "address-subtype", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 6); - nm_clear_g_variant (&child); - nm_clear_g_variant (&attr); - - /* IEEE 802.3 - Power Via MDI */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, G_VARIANT_TYPE_VARDICT); - g_assert (attr); - g_assert (g_variant_lookup (attr, "mdi-power-support", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 7); - g_assert (g_variant_lookup (attr, "pse-power-pair", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 1); - g_assert (g_variant_lookup (attr, "power-class", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 0); - nm_clear_g_variant (&attr); - - /* IEEE 802.3 - MAC/PHY Configuration/Status */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, G_VARIANT_TYPE_VARDICT); - g_assert (attr); - g_assert (g_variant_lookup (attr, "autoneg", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 3); - g_assert (g_variant_lookup (attr, "pmd-autoneg-cap", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 0x6c00); - g_assert (g_variant_lookup (attr, "operational-mau-type", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 16); - nm_clear_g_variant (&attr); - - /* unsupported: IEEE 802.3 - Link Aggregation */ - - /* Maximum Frame Size */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 1522); - nm_clear_g_variant (&attr); - - /* IEEE 802.1 - Port VLAN ID */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PVID, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 488); - nm_clear_g_variant (&attr); - - /* IEEE 802.1 - Port and Protocol VLAN ID */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVID, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 0); - nm_clear_g_variant (&attr); - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 1); - nm_clear_g_variant (&attr); - - /* new PPVID attributes */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVIDS, G_VARIANT_TYPE ("aa{sv}")); - g_assert_cmpuint (g_variant_n_children (attr), ==, 1); - child = g_variant_get_child_value (attr, 0); - g_assert (child); - g_assert (g_variant_lookup (child, "ppvid", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 0); - g_assert (g_variant_lookup (child, "flags", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 1); - nm_clear_g_variant (&child); - nm_clear_g_variant (&attr); - - /* IEEE 802.1 - VLAN Name */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, G_VARIANT_TYPE_STRING); - nmtst_assert_variant_string (attr, "v2-0488-03-0505"); - nm_clear_g_variant (&attr); - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VID, G_VARIANT_TYPE_UINT32); - nmtst_assert_variant_uint32 (attr, 488); - nm_clear_g_variant (&attr); - - /* new VLAN attributes */ - attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLANS, G_VARIANT_TYPE ("aa{sv}")); - g_assert_cmpuint (g_variant_n_children (attr), ==, 1); - child = g_variant_get_child_value (attr, 0); - g_assert (child); - g_assert (g_variant_lookup (child, "vid", "u", &v_uint)); - g_assert_cmpint (v_uint, ==, 488); - g_assert (g_variant_lookup (child, "name", "&s", &v_str)); - g_assert_cmpstr (v_str, ==, "v2-0488-03-0505"); - nm_clear_g_variant (&child); - nm_clear_g_variant (&attr); - - /* unsupported: IEEE 802.1 - Protocol Identity */ + GVariant * neighbors, *attr, *child; + gs_unref_variant GVariant *neighbor = NULL; + guint v_uint = 0; + const char * v_str = NULL; + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 1); + + neighbor = get_lldp_neighbor(neighbors, + SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, + "00:01:30:F9:AD:A0", + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, + "1/1"); + g_assert(neighbor); + g_assert_cmpint(g_variant_n_children(neighbor), ==, 1 + 4 + 16); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, + _test_recv_data1_frame0.frame, + _test_recv_data1_frame0.frame_len); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, NM_LLDP_DEST_NEAREST_BRIDGE); + nm_clear_g_variant(&attr); + + /* unsupported: Time To Live */ + + /* Port Description */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Summit300-48-Port 1001"); + nm_clear_g_variant(&attr); + + /* System Name */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Summit300-48"); + nm_clear_g_variant(&attr); + + /* System Description */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string( + attr, + "Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11"); + nm_clear_g_variant(&attr); + + /* Capabilities */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 20); + nm_clear_g_variant(&attr); + + /* Management Address */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, + G_VARIANT_TYPE("aa{sv}")); + g_assert(attr); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "interface-number", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1001); + g_assert(g_variant_lookup(child, "interface-number-subtype", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 2); + g_assert(g_variant_lookup(child, "address-subtype", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 6); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* IEEE 802.3 - Power Via MDI */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, + G_VARIANT_TYPE_VARDICT); + g_assert(attr); + g_assert(g_variant_lookup(attr, "mdi-power-support", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 7); + g_assert(g_variant_lookup(attr, "pse-power-pair", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1); + g_assert(g_variant_lookup(attr, "power-class", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0); + nm_clear_g_variant(&attr); + + /* IEEE 802.3 - MAC/PHY Configuration/Status */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, + G_VARIANT_TYPE_VARDICT); + g_assert(attr); + g_assert(g_variant_lookup(attr, "autoneg", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 3); + g_assert(g_variant_lookup(attr, "pmd-autoneg-cap", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0x6c00); + g_assert(g_variant_lookup(attr, "operational-mau-type", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 16); + nm_clear_g_variant(&attr); + + /* unsupported: IEEE 802.3 - Link Aggregation */ + + /* Maximum Frame Size */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, + G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 1522); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - Port VLAN ID */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PVID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 488); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - Port and Protocol VLAN ID */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 0); + nm_clear_g_variant(&attr); + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, + G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 1); + nm_clear_g_variant(&attr); + + /* new PPVID attributes */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVIDS, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "ppvid", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0); + g_assert(g_variant_lookup(child, "flags", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - VLAN Name */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "v2-0488-03-0505"); + nm_clear_g_variant(&attr); + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 488); + nm_clear_g_variant(&attr); + + /* new VLAN attributes */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VLANS, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "vid", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 488); + g_assert(g_variant_lookup(child, "name", "&s", &v_str)); + g_assert_cmpstr(v_str, ==, "v2-0488-03-0505"); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* unsupported: IEEE 802.1 - Protocol Identity */ } -TEST_RECV_DATA_DEFINE (_test_recv_data1, 1, _test_recv_data1_check, &_test_recv_data1_frame0); - -TEST_RECV_FRAME_DEFINE (_test_recv_data2_frame0_ttl1, - "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, 0x06, 0x02, 0x00, 0x01, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, 0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': , 'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': , 'port-id': <'1/3'>, 'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': <'SYS'>, 'system-description': <'foo'>}", - /* Ethernet header */ - 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, /* Destination MAC */ - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* Source MAC */ - 0x88, 0xcc, /* Ethertype */ - /* LLDP mandatory TLVs */ - 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ - 0x03, 0x04, 0x05, - 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33, /* Port: interface name, "1/3" */ - 0x06, 0x02, 0x00, 0x01, /* TTL: 1 seconds */ - /* LLDP optional TLVs */ - 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, /* Port Description: "Port" */ - 0x0a, 0x03, 0x53, 0x59, 0x53, /* System Name: "SYS" */ - 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, /* System Description: "foo" (NULL-terminated) */ - 0x00, 0x00 /* End Of LLDPDU */ +TEST_RECV_DATA_DEFINE(_test_recv_data1, 1, _test_recv_data1_check, &_test_recv_data1_frame0); + +TEST_RECV_FRAME_DEFINE( + _test_recv_data2_frame0_ttl1, + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x33, 0x06, 0x02, 0x00, 0x01, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, " + "0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': , " + "'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': , 'port-id': <'1/3'>, " + "'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': " + "<'SYS'>, 'system-description': <'foo'>}", + /* Ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x03, /* Destination MAC */ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, /* Source MAC */ + 0x88, + 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, + 0x04, + 0x05, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x33, /* Port: interface name, "1/3" */ + 0x06, + 0x02, + 0x00, + 0x01, /* TTL: 1 seconds */ + /* LLDP optional TLVs */ + 0x08, + 0x04, + 0x50, + 0x6f, + 0x72, + 0x74, /* Port Description: "Port" */ + 0x0a, + 0x03, + 0x53, + 0x59, + 0x53, /* System Name: "SYS" */ + 0x0c, + 0x04, + 0x66, + 0x6f, + 0x6f, + 0x00, /* System Description: "foo" (NULL-terminated) */ + 0x00, + 0x00 /* End Of LLDPDU */ ); static void -_test_recv_data2_ttl1_check (GMainLoop *loop, NMLldpListener *listener) +_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener) { - gulong notify_id; - GVariant *neighbors; - - _test_recv_data0_check_do (loop, listener, &_test_recv_data2_frame0_ttl1); - - /* wait for signal. */ - notify_id = g_signal_connect (listener, "notify::" NM_LLDP_LISTENER_NEIGHBORS, - nmtst_main_loop_quit_on_notify, loop); - if (!nmtst_main_loop_run (loop, 5000)) - g_assert_not_reached (); - nm_clear_g_signal_handler (listener, ¬ify_id); - - neighbors = nm_lldp_listener_get_neighbors (listener); - nmtst_assert_variant_is_of_type (neighbors, G_VARIANT_TYPE ("aa{sv}")); - g_assert_cmpint (g_variant_n_children (neighbors), ==, 0); + gulong notify_id; + GVariant *neighbors; + + _test_recv_data0_check_do(loop, listener, &_test_recv_data2_frame0_ttl1); + + /* wait for signal. */ + notify_id = g_signal_connect(listener, + "notify::" NM_LLDP_LISTENER_NEIGHBORS, + nmtst_main_loop_quit_on_notify, + loop); + if (!nmtst_main_loop_run(loop, 5000)) + g_assert_not_reached(); + nm_clear_g_signal_handler(listener, ¬ify_id); + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 0); } -TEST_RECV_DATA_DEFINE (_test_recv_data2_ttl1, 1, _test_recv_data2_ttl1_check, &_test_recv_data2_frame0_ttl1); +TEST_RECV_DATA_DEFINE(_test_recv_data2_ttl1, + 1, + _test_recv_data2_ttl1_check, + &_test_recv_data2_frame0_ttl1); static void -_test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data) +_test_recv_fixture_setup(TestRecvFixture *fixture, gconstpointer user_data) { - const NMPlatformLink *link; - nm_auto_close int fd = -1; - - fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC); - if (fd == -1) { - g_test_skip ("Unable to open /dev/net/tun"); - fixture->ifindex = 0; - return; - } - - if (nmtst_get_rand_bool ()) { - const NMPlatformLnkTun lnk = { - .type = IFF_TAP, - .pi = FALSE, - .vnet_hdr = FALSE, - .multi_queue = FALSE, - .persist = FALSE, - }; - - nm_close (nm_steal_fd (&fd)); - - link = nmtstp_link_tun_add (NM_PLATFORM_GET, - FALSE, - TEST_IFNAME, - &lnk, - &fd); - g_assert (link); - nmtstp_link_set_updown (NM_PLATFORM_GET, -1, link->ifindex, TRUE); - link = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 0); - } else { - int s; - struct ifreq ifr = { }; - - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - nm_utils_ifname_cpy (ifr.ifr_name, TEST_IFNAME); - g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0); - - /* Bring the interface up */ - s = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - g_assert (s >= 0); - ifr.ifr_flags |= IFF_UP; - g_assert (ioctl (s, SIOCSIFFLAGS, &ifr) >= 0); - nm_close (s); - - link = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 100); - } - - fixture->ifindex = link->ifindex; - fixture->fd = nm_steal_fd (&fd); - memcpy (fixture->mac, link->l_address.data, ETH_ALEN); + const NMPlatformLink *link; + nm_auto_close int fd = -1; + + fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC); + if (fd == -1) { + g_test_skip("Unable to open /dev/net/tun"); + fixture->ifindex = 0; + return; + } + + if (nmtst_get_rand_bool()) { + const NMPlatformLnkTun lnk = { + .type = IFF_TAP, + .pi = FALSE, + .vnet_hdr = FALSE, + .multi_queue = FALSE, + .persist = FALSE, + }; + + nm_close(nm_steal_fd(&fd)); + + link = nmtstp_link_tun_add(NM_PLATFORM_GET, FALSE, TEST_IFNAME, &lnk, &fd); + g_assert(link); + nmtstp_link_set_updown(NM_PLATFORM_GET, -1, link->ifindex, TRUE); + link = nmtstp_assert_wait_for_link(NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 0); + } else { + int s; + struct ifreq ifr = {}; + + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + nm_utils_ifname_cpy(ifr.ifr_name, TEST_IFNAME); + g_assert(ioctl(fd, TUNSETIFF, &ifr) >= 0); + + /* Bring the interface up */ + s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + g_assert(s >= 0); + ifr.ifr_flags |= IFF_UP; + g_assert(ioctl(s, SIOCSIFFLAGS, &ifr) >= 0); + nm_close(s); + + link = nmtstp_assert_wait_for_link(NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 100); + } + + fixture->ifindex = link->ifindex; + fixture->fd = nm_steal_fd(&fd); + memcpy(fixture->mac, link->l_address.data, ETH_ALEN); } typedef struct { - int num_called; + int num_called; } TestRecvCallbackInfo; static void -lldp_neighbors_changed (NMLldpListener *lldp_listener, GParamSpec *pspec, - gpointer user_data) +lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) { - TestRecvCallbackInfo *info = user_data; + TestRecvCallbackInfo *info = user_data; - info->num_called++; + info->num_called++; } static void -test_recv (TestRecvFixture *fixture, gconstpointer user_data) +test_recv(TestRecvFixture *fixture, gconstpointer user_data) { - const TestRecvData *data = user_data; - gs_unref_object NMLldpListener *listener = NULL; - GMainLoop *loop; - TestRecvCallbackInfo info = { }; - gsize i_frames; - gulong notify_id; - GError *error = NULL; - guint sd_id; + const TestRecvData *data = user_data; + gs_unref_object NMLldpListener *listener = NULL; + GMainLoop * loop; + TestRecvCallbackInfo info = {}; + gsize i_frames; + gulong notify_id; + GError * error = NULL; + guint sd_id; - if (fixture->ifindex == 0) { - g_test_skip ("Tun device not available"); - return; - } + if (fixture->ifindex == 0) { + g_test_skip("Tun device not available"); + return; + } - listener = nm_lldp_listener_new (); - g_assert (listener != NULL); - g_assert (nm_lldp_listener_start (listener, fixture->ifindex, &error)); - g_assert_no_error (error); + listener = nm_lldp_listener_new(); + g_assert(listener != NULL); + g_assert(nm_lldp_listener_start(listener, fixture->ifindex, &error)); + g_assert_no_error(error); - notify_id = g_signal_connect (listener, "notify::" NM_LLDP_LISTENER_NEIGHBORS, - (GCallback) lldp_neighbors_changed, &info); - loop = g_main_loop_new (NULL, FALSE); - sd_id = nm_sd_event_attach_default (); + notify_id = g_signal_connect(listener, + "notify::" NM_LLDP_LISTENER_NEIGHBORS, + (GCallback) lldp_neighbors_changed, + &info); + loop = g_main_loop_new(NULL, FALSE); + sd_id = nm_sd_event_attach_default(); - for (i_frames = 0; i_frames < data->frames_len; i_frames++) { - const TestRecvFrame *f = data->frames[i_frames]; + for (i_frames = 0; i_frames < data->frames_len; i_frames++) { + const TestRecvFrame *f = data->frames[i_frames]; - g_assert (write (fixture->fd, f->frame, f->frame_len) == f->frame_len); - } + g_assert(write(fixture->fd, f->frame, f->frame_len) == f->frame_len); + } - if (nmtst_main_loop_run (loop, 500)) - g_assert_not_reached (); + if (nmtst_main_loop_run(loop, 500)) + g_assert_not_reached(); - g_assert_cmpint (info.num_called, ==, data->expected_num_called); + g_assert_cmpint(info.num_called, ==, data->expected_num_called); - nm_clear_g_signal_handler (listener, ¬ify_id); + nm_clear_g_signal_handler(listener, ¬ify_id); - data->check (loop, listener); + data->check(loop, listener); - nm_clear_g_source (&sd_id); - nm_clear_pointer (&loop, g_main_loop_unref); + nm_clear_g_source(&sd_id); + nm_clear_pointer(&loop, g_main_loop_unref); } static void -_test_recv_fixture_teardown (TestRecvFixture *fixture, gconstpointer user_data) +_test_recv_fixture_teardown(TestRecvFixture *fixture, gconstpointer user_data) { - if (fixture->ifindex) - nm_platform_link_delete (NM_PLATFORM_GET, fixture->ifindex); + if (fixture->ifindex) + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex); } /*****************************************************************************/ static void -test_parse_frames (gconstpointer test_data) +test_parse_frames(gconstpointer test_data) { - const TestRecvFrame *frame = test_data; - gs_unref_variant GVariant *v_neighbor = NULL; - gs_unref_variant GVariant *attr = NULL; - gs_free char *as_variant = NULL; + const TestRecvFrame *frame = test_data; + gs_unref_variant GVariant *v_neighbor = NULL; + gs_unref_variant GVariant *attr = NULL; + gs_free char * as_variant = NULL; - v_neighbor = nmtst_lldp_parse_from_raw (frame->frame, frame->frame_len); - g_assert (v_neighbor); + v_neighbor = nmtst_lldp_parse_from_raw(frame->frame, frame->frame_len); + g_assert(v_neighbor); - attr = g_variant_lookup_value (v_neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); - nmtst_assert_variant_bytestring (attr, frame->frame, frame->frame_len); - nm_clear_g_variant (&attr); + attr = g_variant_lookup_value(v_neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, frame->frame, frame->frame_len); + nm_clear_g_variant(&attr); - as_variant = g_variant_print (v_neighbor, TRUE); - g_assert (as_variant); - g_assert_cmpstr (frame->as_variant, ==, as_variant); + as_variant = g_variant_print(v_neighbor, TRUE); + g_assert(as_variant); + g_assert_cmpstr(frame->as_variant, ==, as_variant); } /*****************************************************************************/ -TEST_RECV_FRAME_DEFINE (_test_parse_frames_3, - /* https://github.com/the-tcpdump-group/tcpdump/blob/c4f8796bf8bec740621a360eded236d8991ea00f/tests/lldp_mudurl.pcap */ - "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x88, 0xcc, 0x02, 0x07, 0x04, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x04, 0x07, 0x03, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x06, 0x02, 0x00, 0x78, 0x0a, 0x1c, 0x75, 0x70, 0x73, 0x74, 0x61, 0x69, 0x72, 0x73, 0x2e, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x69, 0x6d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x5c, 0x55, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x31, 0x34, 0x2e, 0x30, 0x34, 0x2e, 0x35, 0x20, 0x4c, 0x54, 0x53, 0x20, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x33, 0x2e, 0x31, 0x33, 0x2e, 0x30, 0x2d, 0x31, 0x30, 0x36, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x23, 0x31, 0x35, 0x33, 0x2d, 0x55, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x54, 0x75, 0x65, 0x20, 0x44, 0x65, 0x63, 0x20, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x35, 0x3a, 0x31, 0x33, 0x20, 0x55, 0x54, 0x43, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x69, 0x36, 0x38, 0x36, 0x0e, 0x04, 0x00, 0x9c, 0x00, 0x08, 0x10, 0x0c, 0x05, 0x01, 0x3e, 0x0c, 0xad, 0x72, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x18, 0x11, 0x02, 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, 0x00, 0x04, 0x02, 0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x04, 0x65, 0x74, 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0xec, 0xc3, 0x00, 0x10, 0xfe, 0x40, 0x00, 0x00, 0x5e, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2e, 0x6d, 0x75, 0x64, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x6d, 0x75, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x6f, 0x6d, 0x69, 0x74, 0x76, 0x32, 0x2e, 0x30, 0x00, 0x00]>, 'chassis-id-type': , 'chassis-id': <'00:23:54:C2:57:02'>, 'port-id-type': , 'port-id': <'00:23:54:C2:57:02'>, 'destination': <'nearest-bridge'>, 'port-description': <'eth0'>, 'system-name': <'upstairs.ofcourseimright.com'>, 'system-description': <'Ubuntu 14.04.5 LTS Linux 3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686'>, 'system-capabilities': , 'management-addresses': <[{'address-subtype': , 'address': <[byte 0x3e, 0x0c, 0xad, 0x72]>, 'interface-number-subtype': , 'interface-number': }, {'address-subtype': , 'address': <[byte 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, 0x00, 0x04, 0x02, 0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02]>, 'interface-number-subtype': , 'interface-number': }]>, 'ieee-802-3-mac-phy-conf': <{'autoneg': , 'pmd-autoneg-cap': , 'operational-mau-type': }>, 'mud-url': <'https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0'>}", - 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, /* ethernet destination */ - 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, /* ethernet source */ - 0x88, 0xcc, /* ethernet type */ - - 0x02, 0x07, 0x04, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x04, 0x07, 0x03, 0x00, 0x23, - 0x54, 0xc2, 0x57, 0x02, 0x06, 0x02, 0x00, 0x78, 0x0a, 0x1c, 0x75, 0x70, 0x73, 0x74, - 0x61, 0x69, 0x72, 0x73, 0x2e, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x69, - 0x6d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x5c, 0x55, 0x62, - 0x75, 0x6e, 0x74, 0x75, 0x20, 0x31, 0x34, 0x2e, 0x30, 0x34, 0x2e, 0x35, 0x20, 0x4c, - 0x54, 0x53, 0x20, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x33, 0x2e, 0x31, 0x33, 0x2e, - 0x30, 0x2d, 0x31, 0x30, 0x36, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x23, 0x31, 0x35, 0x33, 0x2d, 0x55, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x53, 0x4d, - 0x50, 0x20, 0x54, 0x75, 0x65, 0x20, 0x44, 0x65, 0x63, 0x20, 0x36, 0x20, 0x31, 0x35, - 0x3a, 0x34, 0x35, 0x3a, 0x31, 0x33, 0x20, 0x55, 0x54, 0x43, 0x20, 0x32, 0x30, 0x31, - 0x36, 0x20, 0x69, 0x36, 0x38, 0x36, 0x0e, 0x04, 0x00, 0x9c, 0x00, 0x08, 0x10, 0x0c, - 0x05, 0x01, 0x3e, 0x0c, 0xad, 0x72, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x18, - 0x11, 0x02, 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, 0x00, 0x04, 0x02, 0x23, 0x54, 0xff, - 0xfe, 0xc2, 0x57, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x04, 0x65, 0x74, - 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0xec, 0xc3, 0x00, 0x10, 0xfe, 0x40, 0x00, 0x00, - 0x5e, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x72, 0x69, - 0x67, 0x68, 0x74, 0x2e, 0x6d, 0x75, 0x64, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x2f, 0x6d, 0x75, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x6f, 0x6d, - 0x69, 0x74, 0x76, 0x32, 0x2e, - - 0x30, 0x00, 0x00, /* ethernet trailer */ +TEST_RECV_FRAME_DEFINE( + _test_parse_frames_3, + /* https://github.com/the-tcpdump-group/tcpdump/blob/c4f8796bf8bec740621a360eded236d8991ea00f/tests/lldp_mudurl.pcap */ + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x04, 0x07, 0x03, 0x00, 0x23, " + "0x54, 0xc2, 0x57, 0x02, 0x06, 0x02, 0x00, 0x78, 0x0a, 0x1c, 0x75, 0x70, 0x73, 0x74, 0x61, " + "0x69, 0x72, 0x73, 0x2e, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x69, 0x6d, 0x72, " + "0x69, 0x67, 0x68, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x5c, 0x55, 0x62, 0x75, 0x6e, 0x74, " + "0x75, 0x20, 0x31, 0x34, 0x2e, 0x30, 0x34, 0x2e, 0x35, 0x20, 0x4c, 0x54, 0x53, 0x20, 0x4c, " + "0x69, 0x6e, 0x75, 0x78, 0x20, 0x33, 0x2e, 0x31, 0x33, 0x2e, 0x30, 0x2d, 0x31, 0x30, 0x36, " + "0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x23, 0x31, 0x35, 0x33, 0x2d, 0x55, " + "0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x54, 0x75, 0x65, 0x20, 0x44, " + "0x65, 0x63, 0x20, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x35, 0x3a, 0x31, 0x33, 0x20, 0x55, " + "0x54, 0x43, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x69, 0x36, 0x38, 0x36, 0x0e, 0x04, 0x00, " + "0x9c, 0x00, 0x08, 0x10, 0x0c, 0x05, 0x01, 0x3e, 0x0c, 0xad, 0x72, 0x02, 0x00, 0x00, 0x00, " + "0x02, 0x00, 0x10, 0x18, 0x11, 0x02, 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, 0x00, 0x04, 0x02, " + "0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x04, " + "0x65, 0x74, 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, " + "0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0xec, 0xc3, 0x00, 0x10, 0xfe, 0x40, 0x00, 0x00, " + "0x5e, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x72, 0x69, 0x67, " + "0x68, 0x74, 0x2e, 0x6d, 0x75, 0x64, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, " + "0x63, 0x6f, 0x6d, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, " + "0x2f, 0x6d, 0x75, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x6f, 0x6d, 0x69, 0x74, 0x76, 0x32, " + "0x2e, 0x30, 0x00, 0x00]>, 'chassis-id-type': , 'chassis-id': <'00:23:54:C2:57:02'>, " + "'port-id-type': , 'port-id': <'00:23:54:C2:57:02'>, 'destination': " + "<'nearest-bridge'>, 'port-description': <'eth0'>, 'system-name': " + "<'upstairs.ofcourseimright.com'>, 'system-description': <'Ubuntu 14.04.5 LTS Linux " + "3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686'>, 'system-capabilities': " + ", 'management-addresses': <[{'address-subtype': , 'address': <[byte " + "0x3e, 0x0c, 0xad, 0x72]>, 'interface-number-subtype': , 'interface-number': }, {'address-subtype': , 'address': <[byte 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, " + "0x00, 0x04, 0x02, 0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02]>, 'interface-number-subtype': " + ", 'interface-number': }]>, 'ieee-802-3-mac-phy-conf': <{'autoneg': " + ", 'pmd-autoneg-cap': , 'operational-mau-type': }>, " + "'mud-url': <'https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0'>}", + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x0e, /* ethernet destination */ + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, /* ethernet source */ + 0x88, + 0xcc, /* ethernet type */ + + 0x02, + 0x07, + 0x04, + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, + 0x04, + 0x07, + 0x03, + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, + 0x06, + 0x02, + 0x00, + 0x78, + 0x0a, + 0x1c, + 0x75, + 0x70, + 0x73, + 0x74, + 0x61, + 0x69, + 0x72, + 0x73, + 0x2e, + 0x6f, + 0x66, + 0x63, + 0x6f, + 0x75, + 0x72, + 0x73, + 0x65, + 0x69, + 0x6d, + 0x72, + 0x69, + 0x67, + 0x68, + 0x74, + 0x2e, + 0x63, + 0x6f, + 0x6d, + 0x0c, + 0x5c, + 0x55, + 0x62, + 0x75, + 0x6e, + 0x74, + 0x75, + 0x20, + 0x31, + 0x34, + 0x2e, + 0x30, + 0x34, + 0x2e, + 0x35, + 0x20, + 0x4c, + 0x54, + 0x53, + 0x20, + 0x4c, + 0x69, + 0x6e, + 0x75, + 0x78, + 0x20, + 0x33, + 0x2e, + 0x31, + 0x33, + 0x2e, + 0x30, + 0x2d, + 0x31, + 0x30, + 0x36, + 0x2d, + 0x67, + 0x65, + 0x6e, + 0x65, + 0x72, + 0x69, + 0x63, + 0x20, + 0x23, + 0x31, + 0x35, + 0x33, + 0x2d, + 0x55, + 0x62, + 0x75, + 0x6e, + 0x74, + 0x75, + 0x20, + 0x53, + 0x4d, + 0x50, + 0x20, + 0x54, + 0x75, + 0x65, + 0x20, + 0x44, + 0x65, + 0x63, + 0x20, + 0x36, + 0x20, + 0x31, + 0x35, + 0x3a, + 0x34, + 0x35, + 0x3a, + 0x31, + 0x33, + 0x20, + 0x55, + 0x54, + 0x43, + 0x20, + 0x32, + 0x30, + 0x31, + 0x36, + 0x20, + 0x69, + 0x36, + 0x38, + 0x36, + 0x0e, + 0x04, + 0x00, + 0x9c, + 0x00, + 0x08, + 0x10, + 0x0c, + 0x05, + 0x01, + 0x3e, + 0x0c, + 0xad, + 0x72, + 0x02, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x10, + 0x18, + 0x11, + 0x02, + 0x20, + 0x01, + 0x08, + 0xa8, + 0x10, + 0x06, + 0x00, + 0x04, + 0x02, + 0x23, + 0x54, + 0xff, + 0xfe, + 0xc2, + 0x57, + 0x02, + 0x02, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x08, + 0x04, + 0x65, + 0x74, + 0x68, + 0x30, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x03, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x01, + 0x03, + 0xec, + 0xc3, + 0x00, + 0x10, + 0xfe, + 0x40, + 0x00, + 0x00, + 0x5e, + 0x01, + 0x68, + 0x74, + 0x74, + 0x70, + 0x73, + 0x3a, + 0x2f, + 0x2f, + 0x69, + 0x6d, + 0x72, + 0x69, + 0x67, + 0x68, + 0x74, + 0x2e, + 0x6d, + 0x75, + 0x64, + 0x2e, + 0x65, + 0x78, + 0x61, + 0x6d, + 0x70, + 0x6c, + 0x65, + 0x2e, + 0x63, + 0x6f, + 0x6d, + 0x2f, + 0x2e, + 0x77, + 0x65, + 0x6c, + 0x6c, + 0x2d, + 0x6b, + 0x6e, + 0x6f, + 0x77, + 0x6e, + 0x2f, + 0x6d, + 0x75, + 0x64, + 0x2f, + 0x76, + 0x31, + 0x2f, + 0x76, + 0x6f, + 0x6d, + 0x69, + 0x74, + 0x76, + 0x32, + 0x2e, + + 0x30, + 0x00, + 0x00, /* ethernet trailer */ ); /*****************************************************************************/ @@ -590,23 +1269,28 @@ TEST_RECV_FRAME_DEFINE (_test_parse_frames_3, NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_assert_logging (argc, argv, "WARN", "ALL"); + nmtst_init_assert_logging(argc, argv, "WARN", "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { #define _TEST_ADD_RECV(testpath, testdata) \ - g_test_add (testpath, TestRecvFixture, testdata, _test_recv_fixture_setup, test_recv, _test_recv_fixture_teardown) - _TEST_ADD_RECV ("/lldp/recv/0", &_test_recv_data0); - _TEST_ADD_RECV ("/lldp/recv/0_twice", &_test_recv_data0_twice); - _TEST_ADD_RECV ("/lldp/recv/1", &_test_recv_data1); - _TEST_ADD_RECV ("/lldp/recv/2_ttl1", &_test_recv_data2_ttl1); - - g_test_add_data_func ("/lldp/parse-frames/0", &_test_recv_data0_frame0, test_parse_frames); - g_test_add_data_func ("/lldp/parse-frames/1", &_test_recv_data1_frame0, test_parse_frames); - g_test_add_data_func ("/lldp/parse-frames/2", &_test_recv_data2_frame0_ttl1, test_parse_frames); - g_test_add_data_func ("/lldp/parse-frames/3", &_test_parse_frames_3, test_parse_frames); + g_test_add(testpath, \ + TestRecvFixture, \ + testdata, \ + _test_recv_fixture_setup, \ + test_recv, \ + _test_recv_fixture_teardown) + _TEST_ADD_RECV("/lldp/recv/0", &_test_recv_data0); + _TEST_ADD_RECV("/lldp/recv/0_twice", &_test_recv_data0_twice); + _TEST_ADD_RECV("/lldp/recv/1", &_test_recv_data1); + _TEST_ADD_RECV("/lldp/recv/2_ttl1", &_test_recv_data2_ttl1); + + g_test_add_data_func("/lldp/parse-frames/0", &_test_recv_data0_frame0, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/1", &_test_recv_data1_frame0, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/2", &_test_recv_data2_frame0_ttl1, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/3", &_test_parse_frames_3, test_parse_frames); } diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 4b57fa38..fb113f83 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Intel Corporation */ @@ -33,1076 +33,1102 @@ _LOG_DECLARE_SELF(NMDeviceIwd); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceIwd, - PROP_MODE, - PROP_BITRATE, - PROP_ACCESS_POINTS, - PROP_ACTIVE_ACCESS_POINT, - PROP_CAPABILITIES, - PROP_SCANNING, - PROP_LAST_SCAN, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceIwd, + PROP_MODE, + PROP_BITRATE, + PROP_ACCESS_POINTS, + PROP_ACTIVE_ACCESS_POINT, + PROP_CAPABILITIES, + PROP_SCANNING, + PROP_LAST_SCAN, ); typedef struct { - GDBusObject * dbus_obj; - GDBusProxy * dbus_device_proxy; - GDBusProxy * dbus_station_proxy; - GDBusProxy * dbus_ap_proxy; - GDBusProxy * dbus_adhoc_proxy; - CList aps_lst_head; - NMWifiAP * current_ap; - GCancellable * cancellable; - NMDeviceWifiCapabilities capabilities; - NMActRequestGetSecretsCallId *wifi_secrets_id; - guint periodic_scan_id; - bool enabled:1; - bool can_scan:1; - bool can_connect:1; - bool scanning:1; - bool scan_requested:1; - bool act_mode_switch:1; - gint64 last_scan; + GDBusObject * dbus_obj; + GDBusProxy * dbus_device_proxy; + GDBusProxy * dbus_station_proxy; + GDBusProxy * dbus_ap_proxy; + GDBusProxy * dbus_adhoc_proxy; + CList aps_lst_head; + NMWifiAP * current_ap; + GCancellable * cancellable; + NMDeviceWifiCapabilities capabilities; + NMActRequestGetSecretsCallId *wifi_secrets_id; + guint periodic_scan_id; + bool enabled : 1; + bool can_scan : 1; + bool can_connect : 1; + bool scanning : 1; + bool scan_requested : 1; + bool act_mode_switch : 1; + gint64 last_scan; } NMDeviceIwdPrivate; struct _NMDeviceIwd { - NMDevice parent; - NMDeviceIwdPrivate _priv; + NMDevice parent; + NMDeviceIwdPrivate _priv; }; struct _NMDeviceIwdClass { - NMDeviceClass parent; + NMDeviceClass parent; }; /*****************************************************************************/ -G_DEFINE_TYPE (NMDeviceIwd, nm_device_iwd, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceIwd, nm_device_iwd, NM_TYPE_DEVICE) -#define NM_DEVICE_IWD_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceIwd, NM_IS_DEVICE_IWD, NMDevice) +#define NM_DEVICE_IWD_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceIwd, NM_IS_DEVICE_IWD, NMDevice) /*****************************************************************************/ -static void schedule_periodic_scan (NMDeviceIwd *self, - gboolean initial_scan); +static void schedule_periodic_scan(NMDeviceIwd *self, gboolean initial_scan); -static gboolean check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic); +static gboolean check_scanning_prohibited(NMDeviceIwd *self, gboolean periodic); /*****************************************************************************/ static void -_ap_dump (NMDeviceIwd *self, - NMLogLevel log_level, - const NMWifiAP *ap, - const char *prefix) +_ap_dump(NMDeviceIwd *self, NMLogLevel log_level, const NMWifiAP *ap, const char *prefix) { - char buf[1024]; + char buf[1024]; - buf[0] = '\0'; - _NMLOG (log_level, LOGD_WIFI_SCAN, "wifi-ap: %-7s %s", - prefix, - nm_wifi_ap_to_string (ap, buf, sizeof (buf), 0)); + buf[0] = '\0'; + _NMLOG(log_level, + LOGD_WIFI_SCAN, + "wifi-ap: %-7s %s", + prefix, + nm_wifi_ap_to_string(ap, buf, sizeof(buf), 0)); } /* Callers ensure we're not removing current_ap */ static void -ap_add_remove (NMDeviceIwd *self, - gboolean is_adding, /* or else is removing */ - NMWifiAP *ap, - gboolean recheck_available_connections) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - - if (is_adding) { - g_object_ref (ap); - ap->wifi_device = NM_DEVICE (self); - c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst); - nm_dbus_object_export (NM_DBUS_OBJECT (ap)); - _ap_dump (self, LOGL_DEBUG, ap, "added"); - nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE); - } else { - ap->wifi_device = NULL; - c_list_unlink (&ap->aps_lst); - _ap_dump (self, LOGL_DEBUG, ap, "removed"); - } - - _notify (self, PROP_ACCESS_POINTS); - - if (!is_adding) { - nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, FALSE); - nm_dbus_object_clear_and_unexport (&ap); - } - - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - if (recheck_available_connections) - nm_device_recheck_available_connections (NM_DEVICE (self)); +ap_add_remove(NMDeviceIwd *self, + gboolean is_adding, /* or else is removing */ + NMWifiAP * ap, + gboolean recheck_available_connections) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + + if (is_adding) { + g_object_ref(ap); + ap->wifi_device = NM_DEVICE(self); + c_list_link_tail(&priv->aps_lst_head, &ap->aps_lst); + nm_dbus_object_export(NM_DBUS_OBJECT(ap)); + _ap_dump(self, LOGL_DEBUG, ap, "added"); + nm_device_wifi_emit_signal_access_point(NM_DEVICE(self), ap, TRUE); + } else { + ap->wifi_device = NULL; + c_list_unlink(&ap->aps_lst); + _ap_dump(self, LOGL_DEBUG, ap, "removed"); + } + + _notify(self, PROP_ACCESS_POINTS); + + if (!is_adding) { + nm_device_wifi_emit_signal_access_point(NM_DEVICE(self), ap, FALSE); + nm_dbus_object_clear_and_unexport(&ap); + } + + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + if (recheck_available_connections) + nm_device_recheck_available_connections(NM_DEVICE(self)); } static void -set_current_ap (NMDeviceIwd *self, NMWifiAP *new_ap, gboolean recheck_available_connections) +set_current_ap(NMDeviceIwd *self, NMWifiAP *new_ap, gboolean recheck_available_connections) { - NMDeviceIwdPrivate *priv; - NMWifiAP *old_ap; + NMDeviceIwdPrivate *priv; + NMWifiAP * old_ap; - g_return_if_fail (NM_IS_DEVICE_IWD (self)); + g_return_if_fail(NM_IS_DEVICE_IWD(self)); - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - old_ap = priv->current_ap; + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + old_ap = priv->current_ap; - if (old_ap == new_ap) - return; + if (old_ap == new_ap) + return; - if (new_ap) - priv->current_ap = g_object_ref (new_ap); - else - priv->current_ap = NULL; + if (new_ap) + priv->current_ap = g_object_ref(new_ap); + else + priv->current_ap = NULL; - if (old_ap) { - if (nm_wifi_ap_get_fake (old_ap)) - ap_add_remove (self, FALSE, old_ap, recheck_available_connections); - g_object_unref (old_ap); - } + if (old_ap) { + if (nm_wifi_ap_get_fake(old_ap)) + ap_add_remove(self, FALSE, old_ap, recheck_available_connections); + g_object_unref(old_ap); + } - _notify (self, PROP_ACTIVE_ACCESS_POINT); - _notify (self, PROP_MODE); + _notify(self, PROP_ACTIVE_ACCESS_POINT); + _notify(self, PROP_MODE); } static void -remove_all_aps (NMDeviceIwd *self) +remove_all_aps(NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMWifiAP *ap, *ap_safe; + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMWifiAP * ap, *ap_safe; - if (c_list_is_empty (&priv->aps_lst_head)) - return; + if (c_list_is_empty(&priv->aps_lst_head)) + return; - set_current_ap (self, NULL, FALSE); + set_current_ap(self, NULL, FALSE); - c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst) - ap_add_remove (self, FALSE, ap, FALSE); + c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst) + ap_add_remove(self, FALSE, ap, FALSE); - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - nm_device_recheck_available_connections (NM_DEVICE (self)); + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_available_connections(NM_DEVICE(self)); } static NM80211ApSecurityFlags -ap_security_flags_from_network_type (const char *type) +ap_security_flags_from_network_type(const char *type) { - NM80211ApSecurityFlags flags; + NM80211ApSecurityFlags flags; - if (nm_streq (type, "psk")) - flags = NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (nm_streq (type, "8021x")) - flags = NM_802_11_AP_SEC_KEY_MGMT_802_1X; - else - return NM_802_11_AP_SEC_NONE; + if (nm_streq(type, "psk")) + flags = NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (nm_streq(type, "8021x")) + flags = NM_802_11_AP_SEC_KEY_MGMT_802_1X; + else + return NM_802_11_AP_SEC_NONE; - flags |= NM_802_11_AP_SEC_PAIR_CCMP; - flags |= NM_802_11_AP_SEC_GROUP_CCMP; - return flags; + flags |= NM_802_11_AP_SEC_PAIR_CCMP; + flags |= NM_802_11_AP_SEC_GROUP_CCMP; + return flags; } static void -insert_ap_from_network (NMDeviceIwd *self, - GHashTable *aps, - const char *path, - gint64 last_seen_msec, - int16_t signal, - uint32_t ap_id) -{ - gs_unref_object GDBusProxy *network_proxy = NULL; - gs_unref_variant GVariant *name_value = NULL; - gs_unref_variant GVariant *type_value = NULL; - nm_auto_ref_string NMRefString *bss_path = NULL; - const char *name; - const char *type; - NMSupplicantBssInfo bss_info; - uint8_t bssid[6]; - NMWifiAP *ap; - gs_unref_bytes GBytes *ssid = NULL; - - bss_path = nm_ref_string_new (path); - - if (g_hash_table_lookup (aps, path)) { - _LOGD (LOGD_WIFI, "Duplicate network at %s", path); - return; - } - - network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (), - path, - NM_IWD_NETWORK_INTERFACE); - if (!network_proxy) - return; - - name_value = g_dbus_proxy_get_cached_property (network_proxy, "Name"); - type_value = g_dbus_proxy_get_cached_property (network_proxy, "Type"); - if ( !name_value - || !g_variant_is_of_type (name_value, G_VARIANT_TYPE_STRING) - || !type_value - || !g_variant_is_of_type (type_value, G_VARIANT_TYPE_STRING)) - return; - - name = g_variant_get_string (name_value, NULL); - type = g_variant_get_string (type_value, NULL); - - if (nm_streq (type, "wep")) { - /* WEP not supported */ - return; - } - - /* What we get from IWD are networks, or ESSs, that may contain - * multiple APs, or BSSs, each. We don't get information about any - * specific BSSs within an ESS but we can safely present each ESS - * as an individual BSS to NM, which will be seen as ESSs comprising - * a single BSS each. NM won't be able to handle roaming but IWD - * already does that. We fake the BSSIDs as they don't play any - * role either. - */ - bssid[0] = 0x00; - bssid[1] = 0x01; - bssid[2] = 0x02; - bssid[3] = ap_id >> 16; - bssid[4] = ap_id >> 8; - bssid[5] = ap_id; - - ssid = g_bytes_new (name, NM_MIN (32u, strlen (name))); - - bss_info = (NMSupplicantBssInfo) { - .bss_path = bss_path, - .last_seen_msec = last_seen_msec, - .bssid_valid = TRUE, - .mode = NM_802_11_MODE_INFRA, - .rsn_flags = ap_security_flags_from_network_type (type), - .ssid = ssid, - .signal_percent = nm_wifi_utils_level_to_quality (signal / 100), - .frequency = 2417, - .max_rate = 65000, - }; - memcpy (bss_info.bssid, bssid, sizeof (bssid)); - - ap = nm_wifi_ap_new_from_properties (&bss_info); - - nm_assert (bss_path == nm_wifi_ap_get_supplicant_path (ap)); - - g_hash_table_insert (aps, bss_path, ap); +insert_ap_from_network(NMDeviceIwd *self, + GHashTable * aps, + const char * path, + gint64 last_seen_msec, + int16_t signal, + uint32_t ap_id) +{ + gs_unref_object GDBusProxy *network_proxy = NULL; + gs_unref_variant GVariant *name_value = NULL; + gs_unref_variant GVariant *type_value = NULL; + nm_auto_ref_string NMRefString *bss_path = NULL; + const char * name; + const char * type; + NMSupplicantBssInfo bss_info; + uint8_t bssid[6]; + NMWifiAP * ap; + gs_unref_bytes GBytes *ssid = NULL; + + bss_path = nm_ref_string_new(path); + + if (g_hash_table_lookup(aps, path)) { + _LOGD(LOGD_WIFI, "Duplicate network at %s", path); + return; + } + + network_proxy = + nm_iwd_manager_get_dbus_interface(nm_iwd_manager_get(), path, NM_IWD_NETWORK_INTERFACE); + if (!network_proxy) + return; + + name_value = g_dbus_proxy_get_cached_property(network_proxy, "Name"); + type_value = g_dbus_proxy_get_cached_property(network_proxy, "Type"); + if (!name_value || !g_variant_is_of_type(name_value, G_VARIANT_TYPE_STRING) || !type_value + || !g_variant_is_of_type(type_value, G_VARIANT_TYPE_STRING)) + return; + + name = g_variant_get_string(name_value, NULL); + type = g_variant_get_string(type_value, NULL); + + if (nm_streq(type, "wep")) { + /* WEP not supported */ + return; + } + + /* What we get from IWD are networks, or ESSs, that may contain + * multiple APs, or BSSs, each. We don't get information about any + * specific BSSs within an ESS but we can safely present each ESS + * as an individual BSS to NM, which will be seen as ESSs comprising + * a single BSS each. NM won't be able to handle roaming but IWD + * already does that. We fake the BSSIDs as they don't play any + * role either. + */ + bssid[0] = 0x00; + bssid[1] = 0x01; + bssid[2] = 0x02; + bssid[3] = ap_id >> 16; + bssid[4] = ap_id >> 8; + bssid[5] = ap_id; + + ssid = g_bytes_new(name, NM_MIN(32u, strlen(name))); + + bss_info = (NMSupplicantBssInfo){ + .bss_path = bss_path, + .last_seen_msec = last_seen_msec, + .bssid_valid = TRUE, + .mode = NM_802_11_MODE_INFRA, + .rsn_flags = ap_security_flags_from_network_type(type), + .ssid = ssid, + .signal_percent = nm_wifi_utils_level_to_quality(signal / 100), + .frequency = 2417, + .max_rate = 65000, + }; + memcpy(bss_info.bssid, bssid, sizeof(bssid)); + + ap = nm_wifi_ap_new_from_properties(&bss_info); + + nm_assert(bss_path == nm_wifi_ap_get_supplicant_path(ap)); + + g_hash_table_insert(aps, bss_path, ap); } static void -get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) -{ - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *variant = NULL; - GVariantIter *networks; - const char *path, *name, *type; - int16_t signal; - NMWifiAP *ap, *ap_safe, *new_ap; - gboolean changed = FALSE; - GHashTableIter ap_iter; - gs_unref_hashtable GHashTable *new_aps = NULL; - gboolean compat; - const char *return_sig; - static uint32_t ap_id = 0; - gint64 last_seen_msec; - - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant) { - _LOGE (LOGD_WIFI, "Station.GetOrderedNetworks failed: %s", - error->message); - return; - } - - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - - /* Depending on whether we're using the Station interface or the Device - * interface for compatibility with IWD <= 0.7, the return signature of - * GetOrderedNetworks will be different. - */ - compat = priv->dbus_station_proxy == priv->dbus_device_proxy; - return_sig = compat ? "(a(osns))" : "(a(on))"; - - if (!g_variant_is_of_type (variant, G_VARIANT_TYPE (return_sig))) { - _LOGE (LOGD_WIFI, "Station.GetOrderedNetworks returned type %s instead of %s", - g_variant_get_type_string (variant), return_sig); - return; - } - - new_aps = g_hash_table_new_full (nm_direct_hash, NULL, NULL, g_object_unref); - - g_variant_get (variant, return_sig, &networks); - - last_seen_msec = nm_utils_get_monotonic_timestamp_msec (); - if (compat) { - while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type)) - insert_ap_from_network (self, new_aps, path, last_seen_msec, signal, ap_id++); - } else { - while (g_variant_iter_next (networks, "(&on)", &path, &signal)) - insert_ap_from_network (self, new_aps, path, last_seen_msec, signal, ap_id++); - } - - g_variant_iter_free (networks); - - c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst) { - - new_ap = g_hash_table_lookup (new_aps, - nm_wifi_ap_get_supplicant_path (ap)); - if (new_ap) { - if (nm_wifi_ap_set_strength (ap, nm_wifi_ap_get_strength (new_ap))) { - _ap_dump (self, LOGL_TRACE, ap, "updated"); - changed = TRUE; - } - g_hash_table_remove (new_aps, - nm_wifi_ap_get_supplicant_path (ap)); - continue; - } - - if (ap == priv->current_ap) { - /* Normally IWD will prevent the current AP from being - * removed from the list and set a low signal strength, - * but just making sure. - */ - continue; - } - - ap_add_remove (self, FALSE, ap, FALSE); - changed = TRUE; - } - - g_hash_table_iter_init (&ap_iter, new_aps); - while (g_hash_table_iter_next (&ap_iter, NULL, (gpointer) &ap)) { - ap_add_remove (self, TRUE, ap, FALSE); - g_hash_table_iter_remove (&ap_iter); - changed = TRUE; - } - - if (changed) { - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - nm_device_recheck_available_connections (NM_DEVICE (self)); - } +get_ordered_networks_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *variant = NULL; + GVariantIter * networks; + const char * path, *name, *type; + int16_t signal; + NMWifiAP * ap, *ap_safe, *new_ap; + gboolean changed = FALSE; + GHashTableIter ap_iter; + gs_unref_hashtable GHashTable *new_aps = NULL; + gboolean compat; + const char * return_sig; + static uint32_t ap_id = 0; + gint64 last_seen_msec; + + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant) { + _LOGE(LOGD_WIFI, "Station.GetOrderedNetworks failed: %s", error->message); + return; + } + + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + + /* Depending on whether we're using the Station interface or the Device + * interface for compatibility with IWD <= 0.7, the return signature of + * GetOrderedNetworks will be different. + */ + compat = priv->dbus_station_proxy == priv->dbus_device_proxy; + return_sig = compat ? "(a(osns))" : "(a(on))"; + + if (!g_variant_is_of_type(variant, G_VARIANT_TYPE(return_sig))) { + _LOGE(LOGD_WIFI, + "Station.GetOrderedNetworks returned type %s instead of %s", + g_variant_get_type_string(variant), + return_sig); + return; + } + + new_aps = g_hash_table_new_full(nm_direct_hash, NULL, NULL, g_object_unref); + + g_variant_get(variant, return_sig, &networks); + + last_seen_msec = nm_utils_get_monotonic_timestamp_msec(); + if (compat) { + while (g_variant_iter_next(networks, "(&o&sn&s)", &path, &name, &signal, &type)) + insert_ap_from_network(self, new_aps, path, last_seen_msec, signal, ap_id++); + } else { + while (g_variant_iter_next(networks, "(&on)", &path, &signal)) + insert_ap_from_network(self, new_aps, path, last_seen_msec, signal, ap_id++); + } + + g_variant_iter_free(networks); + + c_list_for_each_entry_safe (ap, ap_safe, &priv->aps_lst_head, aps_lst) { + new_ap = g_hash_table_lookup(new_aps, nm_wifi_ap_get_supplicant_path(ap)); + if (new_ap) { + if (nm_wifi_ap_set_strength(ap, nm_wifi_ap_get_strength(new_ap))) { + _ap_dump(self, LOGL_TRACE, ap, "updated"); + changed = TRUE; + } + g_hash_table_remove(new_aps, nm_wifi_ap_get_supplicant_path(ap)); + continue; + } + + if (ap == priv->current_ap) { + /* Normally IWD will prevent the current AP from being + * removed from the list and set a low signal strength, + * but just making sure. + */ + continue; + } + + ap_add_remove(self, FALSE, ap, FALSE); + changed = TRUE; + } + + g_hash_table_iter_init(&ap_iter, new_aps); + while (g_hash_table_iter_next(&ap_iter, NULL, (gpointer) &ap)) { + ap_add_remove(self, TRUE, ap, FALSE); + g_hash_table_iter_remove(&ap_iter); + changed = TRUE; + } + + if (changed) { + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_available_connections(NM_DEVICE(self)); + } } static void -update_aps (NMDeviceIwd *self) +update_aps(NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - if (!priv->cancellable) - priv->cancellable = g_cancellable_new (); + if (!priv->cancellable) + priv->cancellable = g_cancellable_new(); - g_dbus_proxy_call (priv->dbus_station_proxy, "GetOrderedNetworks", - NULL, G_DBUS_CALL_FLAGS_NONE, - 2000, priv->cancellable, - get_ordered_networks_cb, self); + g_dbus_proxy_call(priv->dbus_station_proxy, + "GetOrderedNetworks", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 2000, + priv->cancellable, + get_ordered_networks_cb, + self); } static void -send_disconnect (NMDeviceIwd *self) +send_disconnect(NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - g_dbus_proxy_call (priv->dbus_station_proxy, "Disconnect", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + g_dbus_proxy_call(priv->dbus_station_proxy, + "Disconnect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); } static void -wifi_secrets_cancel (NMDeviceIwd *self) +wifi_secrets_cancel(NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - if (priv->wifi_secrets_id) - nm_act_request_cancel_secrets (NULL, priv->wifi_secrets_id); - nm_assert (!priv->wifi_secrets_id); + if (priv->wifi_secrets_id) + nm_act_request_cancel_secrets(NULL, priv->wifi_secrets_id); + nm_assert(!priv->wifi_secrets_id); } static void -cleanup_association_attempt (NMDeviceIwd *self, gboolean disconnect) +cleanup_association_attempt(NMDeviceIwd *self, gboolean disconnect) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - wifi_secrets_cancel (self); + wifi_secrets_cancel(self); - set_current_ap (self, NULL, TRUE); + set_current_ap(self, NULL, TRUE); - if (disconnect && priv->dbus_station_proxy) - send_disconnect (self); + if (disconnect && priv->dbus_station_proxy) + send_disconnect(self); } static void -reset_mode (NMDeviceIwd *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +reset_mode(NMDeviceIwd * self, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - g_dbus_proxy_call (priv->dbus_device_proxy, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new ("(ssv)", NM_IWD_DEVICE_INTERFACE, - "Mode", - g_variant_new_string ("station")), - G_DBUS_CALL_FLAGS_NONE, 2000, - cancellable, - callback, - user_data); + g_dbus_proxy_call( + priv->dbus_device_proxy, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", NM_IWD_DEVICE_INTERFACE, "Mode", g_variant_new_string("station")), + G_DBUS_CALL_FLAGS_NONE, + 2000, + cancellable, + callback, + user_data); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - if (!priv->dbus_obj) - return; + if (!priv->dbus_obj) + return; - cleanup_association_attempt (self, TRUE); - priv->act_mode_switch = FALSE; + cleanup_association_attempt(self, TRUE); + priv->act_mode_switch = FALSE; - if (!priv->dbus_station_proxy) - reset_mode (self, NULL, NULL, NULL); + if (!priv->dbus_station_proxy) + reset_mode(self, NULL, NULL, NULL); } static void -disconnect_cb (GObject *source, GAsyncResult *res, gpointer user_data) +disconnect_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - gs_unref_object NMDeviceIwd *self = NULL; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; + gs_unref_object NMDeviceIwd *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; - nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data); - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - callback (NM_DEVICE (self), error, callback_user_data); + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + callback(NM_DEVICE(self), error, callback_user_data); } static void -disconnect_cb_on_idle (gpointer user_data, - GCancellable *cancellable) +disconnect_cb_on_idle(gpointer user_data, GCancellable *cancellable) { - gs_unref_object NMDeviceIwd *self = NULL; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; - gs_free_error GError *cancelled_error = NULL; + gs_unref_object NMDeviceIwd *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gs_free_error GError *cancelled_error = NULL; - nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data); - g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error); - callback (NM_DEVICE (self), cancelled_error, callback_user_data); + g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); + callback(NM_DEVICE(self), cancelled_error, callback_user_data); } static void -deactivate_async (NMDevice *device, - GCancellable *cancellable, - NMDeviceDeactivateCallback callback, - gpointer callback_user_data) +deactivate_async(NMDevice * device, + GCancellable * cancellable, + NMDeviceDeactivateCallback callback, + gpointer callback_user_data) { - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - gpointer user_data; + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + gpointer user_data; - nm_assert (G_IS_CANCELLABLE (cancellable)); - nm_assert (callback); + nm_assert(G_IS_CANCELLABLE(cancellable)); + nm_assert(callback); - user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data); + user_data = nm_utils_user_data_pack(g_object_ref(self), callback, callback_user_data); - if (!priv->dbus_obj) { - nm_utils_invoke_on_idle (cancellable, disconnect_cb_on_idle, user_data); - return; - } + if (!priv->dbus_obj) { + nm_utils_invoke_on_idle(cancellable, disconnect_cb_on_idle, user_data); + return; + } - cleanup_association_attempt (self, FALSE); - priv->act_mode_switch = FALSE; + cleanup_association_attempt(self, FALSE); + priv->act_mode_switch = FALSE; - if (priv->dbus_station_proxy) { - g_dbus_proxy_call (priv->dbus_station_proxy, - "Disconnect", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - cancellable, - disconnect_cb, - user_data); - } else - reset_mode (self, cancellable, disconnect_cb, user_data); + if (priv->dbus_station_proxy) { + g_dbus_proxy_call(priv->dbus_station_proxy, + "Disconnect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + disconnect_cb, + user_data); + } else + reset_mode(self, cancellable, disconnect_cb, user_data); } static gboolean -is_connection_known_network (NMConnection *connection) +is_connection_known_network(NMConnection *connection) { - NMSettingWireless *s_wireless; - NMIwdNetworkSecurity security; - gboolean security_ok; - GBytes *ssid; - gs_free char *ssid_utf8 = NULL; + NMSettingWireless * s_wireless; + NMIwdNetworkSecurity security; + gboolean security_ok; + GBytes * ssid; + gs_free char * ssid_utf8 = NULL; - s_wireless = nm_connection_get_setting_wireless (connection); - if (!s_wireless) - return FALSE; + s_wireless = nm_connection_get_setting_wireless(connection); + if (!s_wireless) + return FALSE; - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid) - return FALSE; + ssid = nm_setting_wireless_get_ssid(s_wireless); + if (!ssid) + return FALSE; - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); - security = nm_wifi_connection_get_iwd_security (connection, &security_ok); - if (!security_ok) - return FALSE; + security = nm_wifi_connection_get_iwd_security(connection, &security_ok); + if (!security_ok) + return FALSE; - return nm_iwd_manager_is_known_network (nm_iwd_manager_get (), - ssid_utf8, security); + return nm_iwd_manager_is_known_network(nm_iwd_manager_get(), ssid_utf8, security); } static gboolean -is_ap_known_network (NMWifiAP *ap) +is_ap_known_network(NMWifiAP *ap) { - gs_unref_object GDBusProxy *network_proxy = NULL; - gs_unref_variant GVariant *known_network = NULL; + gs_unref_object GDBusProxy *network_proxy = NULL; + gs_unref_variant GVariant *known_network = NULL; - network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (), - nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)), - NM_IWD_NETWORK_INTERFACE); - if (!network_proxy) - return FALSE; + network_proxy = + nm_iwd_manager_get_dbus_interface(nm_iwd_manager_get(), + nm_ref_string_get_str(nm_wifi_ap_get_supplicant_path(ap)), + NM_IWD_NETWORK_INTERFACE); + if (!network_proxy) + return FALSE; - known_network = g_dbus_proxy_get_cached_property (network_proxy, "KnownNetwork"); - return nm_g_variant_is_of_type (known_network, G_VARIANT_TYPE_OBJECT_PATH); + known_network = g_dbus_proxy_get_cached_property(network_proxy, "KnownNetwork"); + return nm_g_variant_is_of_type(known_network, G_VARIANT_TYPE_OBJECT_PATH); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMSettingWireless *s_wireless; - const char *mac; - const char * const *mac_blacklist; - int i; - const char *perm_hw_addr; - const char *mode; - NMIwdNetworkSecurity security; - gboolean mapped; - - if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - s_wireless = nm_connection_get_setting_wireless (connection); - - perm_hw_addr = nm_device_get_permanent_hw_address (device); - mac = nm_setting_wireless_get_mac_address (s_wireless); - if (perm_hw_addr) { - if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device MAC address does not match the profile"); - return FALSE; - } - - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - for (i = 0; mac_blacklist[i]; i++) { - nm_assert (nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)); - - 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, - "MAC address blacklisted"); - return FALSE; - } - } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no valid MAC address as required by profile"); - return FALSE; - } - - security = nm_wifi_connection_get_iwd_security (connection, &mapped); - if (!mapped) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "connection authentication type not supported by IWD backend"); - return FALSE; - } - - mode = nm_setting_wireless_get_mode (s_wireless); - - /* Hidden SSIDs only supported in client mode */ - if ( nm_setting_wireless_get_hidden (s_wireless) - && !NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "non-infrastructure hidden networks not supported by the IWD backend"); - return FALSE; - } - - if (NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { - /* 8021x networks can only be used if they've been provisioned on the IWD side and - * thus are Known Networks. - */ - if (security == NM_IWD_NETWORK_SECURITY_8021X) { - if (!is_connection_known_network (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "802.1x connections must have IWD provisioning files"); - return FALSE; - } - } else if (!NM_IN_SET (security, NM_IWD_NETWORK_SECURITY_NONE, NM_IWD_NETWORK_SECURITY_PSK)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IWD backend only supports Open, PSK and 802.1x network " - "authentication in Infrastructure mode"); - return FALSE; - } - } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not support Access Point mode"); - return FALSE; - } - - if (!NM_IN_SET (security, NM_IWD_NETWORK_SECURITY_PSK)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IWD backend only supports PSK authentication in AP mode"); - return FALSE; - } - } else if (nm_streq (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not support Ad-Hoc mode"); - return FALSE; - } - - if (!NM_IN_SET (security, NM_IWD_NETWORK_SECURITY_NONE, NM_IWD_NETWORK_SECURITY_PSK)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IWD backend only supports Open and PSK authentication in Ad-Hoc mode"); - return FALSE; - } - } else { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "%s type profiles not supported by IWD backend"); - return FALSE; - } - - return TRUE; +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate * priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMSettingWireless * s_wireless; + const char * mac; + const char *const * mac_blacklist; + int i; + const char * perm_hw_addr; + const char * mode; + NMIwdNetworkSecurity security; + gboolean mapped; + + if (!NM_DEVICE_CLASS(nm_device_iwd_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + s_wireless = nm_connection_get_setting_wireless(connection); + + perm_hw_addr = nm_device_get_permanent_hw_address(device); + mac = nm_setting_wireless_get_mac_address(s_wireless); + if (perm_hw_addr) { + if (mac && !nm_utils_hwaddr_matches(mac, -1, perm_hw_addr, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device MAC address does not match the profile"); + return FALSE; + } + + /* Check for MAC address blacklist */ + mac_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless); + for (i = 0; mac_blacklist[i]; i++) { + nm_assert(nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)); + + 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, + "MAC address blacklisted"); + return FALSE; + } + } + } else if (mac) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has no valid MAC address as required by profile"); + return FALSE; + } + + security = nm_wifi_connection_get_iwd_security(connection, &mapped); + if (!mapped) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "connection authentication type not supported by IWD backend"); + return FALSE; + } + + mode = nm_setting_wireless_get_mode(s_wireless); + + /* Hidden SSIDs only supported in client mode */ + if (nm_setting_wireless_get_hidden(s_wireless) + && !NM_IN_STRSET(mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + nm_utils_error_set_literal( + error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "non-infrastructure hidden networks not supported by the IWD backend"); + return FALSE; + } + + if (NM_IN_STRSET(mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + /* 8021x networks can only be used if they've been provisioned on the IWD side and + * thus are Known Networks. + */ + if (security == NM_IWD_NETWORK_SECURITY_8021X) { + if (!is_connection_known_network(connection)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "802.1x connections must have IWD provisioning files"); + return FALSE; + } + } else if (!NM_IN_SET(security, + NM_IWD_NETWORK_SECURITY_NONE, + NM_IWD_NETWORK_SECURITY_PSK)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IWD backend only supports Open, PSK and 802.1x network " + "authentication in Infrastructure mode"); + return FALSE; + } + } else if (nm_streq(mode, NM_SETTING_WIRELESS_MODE_AP)) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not support Access Point mode"); + return FALSE; + } + + if (!NM_IN_SET(security, NM_IWD_NETWORK_SECURITY_PSK)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IWD backend only supports PSK authentication in AP mode"); + return FALSE; + } + } else if (nm_streq(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not support Ad-Hoc mode"); + return FALSE; + } + + if (!NM_IN_SET(security, NM_IWD_NETWORK_SECURITY_NONE, NM_IWD_NETWORK_SECURITY_PSK)) { + nm_utils_error_set_literal( + error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IWD backend only supports Open and PSK authentication in Ad-Hoc mode"); + return FALSE; + } + } else { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "%s type profiles not supported by IWD backend"); + return FALSE; + } + + return TRUE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMSettingWireless *s_wifi; - const char *mode; - NMWifiAP *ap = NULL; - - s_wifi = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wifi, FALSE); - - /* a connection that is available for a certain @specific_object, MUST - * also be available in general (without @specific_object). */ - - if (specific_object) { - ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point not found"); - return FALSE; - } - if (!nm_wifi_ap_check_compatible (ap, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point is not compatible with profile"); - return FALSE; - } - } - - /* AP and Ad-Hoc connections can be activated independent of the scan list */ - mode = nm_setting_wireless_get_mode (s_wifi); - if (NM_IN_STRSET (mode, NM_SETTING_WIRELESS_MODE_AP, NM_SETTING_WIRELESS_MODE_ADHOC)) - return TRUE; - - if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) - return TRUE; - - if (!ap) - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - - if (!ap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no compatible access point found"); - return FALSE; - } - - /* 8021x networks can only be used if they've been provisioned on the IWD side and - * thus are Known Networks. - */ - if (nm_wifi_connection_get_iwd_security (connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { - if (!is_ap_known_network (ap)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "802.1x network is not an IWD Known Network (missing provisioning file?)"); - return FALSE; - } - } - - return TRUE; +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMSettingWireless * s_wifi; + const char * mode; + NMWifiAP * ap = NULL; + + s_wifi = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wifi, FALSE); + + /* a connection that is available for a certain @specific_object, MUST + * also be available in general (without @specific_object). */ + + if (specific_object) { + ap = nm_wifi_ap_lookup_for_device(NM_DEVICE(self), specific_object); + if (!ap) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "requested access point not found"); + return FALSE; + } + if (!nm_wifi_ap_check_compatible(ap, connection)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "requested access point is not compatible with profile"); + return FALSE; + } + } + + /* AP and Ad-Hoc connections can be activated independent of the scan list */ + mode = nm_setting_wireless_get_mode(s_wifi); + if (NM_IN_STRSET(mode, NM_SETTING_WIRELESS_MODE_AP, NM_SETTING_WIRELESS_MODE_ADHOC)) + return TRUE; + + if (NM_FLAGS_HAS(flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) + return TRUE; + + if (!ap) + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + + if (!ap) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "no compatible access point found"); + return FALSE; + } + + /* 8021x networks can only be used if they've been provisioned on the IWD side and + * thus are Known Networks. + */ + if (nm_wifi_connection_get_iwd_security(connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { + if (!is_ap_known_network(ap)) { + nm_utils_error_set_literal( + error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "802.1x network is not an IWD Known Network (missing provisioning file?)"); + return FALSE; + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMSettingWireless *s_wifi; - gs_free char *ssid_utf8 = NULL; - NMWifiAP *ap; - GBytes *ssid; - GBytes *setting_ssid = NULL; - gboolean hidden = FALSE; - const char *mode; - - s_wifi = nm_connection_get_setting_wireless (connection); - - mode = s_wifi ? nm_setting_wireless_get_mode (s_wifi) : NULL; - - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) - return FALSE; - ap = NULL; - } else if (!specific_object) { - /* If not given a specific object, we need at minimum an SSID */ - if (!s_wifi) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting is required if no AP path was given."); - return FALSE; - } - - setting_ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!setting_ssid || g_bytes_get_size (setting_ssid) == 0) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting with a valid SSID is required if no AP path was given."); - return FALSE; - } - - /* Find a compatible AP in the scan list */ - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - if (!ap) { - /* If we still don't have an AP, then the WiFI settings needs to be - * fully specified by the client. Might not be able to find an AP - * if the network isn't broadcasting the SSID for example. - */ - if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) - return FALSE; - - hidden = TRUE; - } - } else { - ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, - "The access point %s was not in the scan list.", - specific_object); - return FALSE; - } - } - - /* Add a wifi setting if one doesn't exist yet */ - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - } - - ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!ssid && ap) - ssid = nm_wifi_ap_get_ssid (ap); - - if (!ssid) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting with a valid SSID is required."); - return FALSE; - } - - if (ap) { - if (!nm_wifi_ap_complete_connection (ap, - connection, - nm_wifi_utils_is_manf_default_ssid (ssid), - error)) - return FALSE; - } - - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_WIRELESS_SETTING_NAME, - existing_connections, - ssid_utf8, - ssid_utf8, - NULL, - nm_setting_wireless_get_mac_address (s_wifi) ? NULL : nm_device_get_iface (device), - TRUE); - - if (hidden) - g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - - return TRUE; +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMSettingWireless * s_wifi; + gs_free char * ssid_utf8 = NULL; + NMWifiAP * ap; + GBytes * ssid; + GBytes * setting_ssid = NULL; + gboolean hidden = FALSE; + const char * mode; + + s_wifi = nm_connection_get_setting_wireless(connection); + + mode = s_wifi ? nm_setting_wireless_get_mode(s_wifi) : NULL; + + if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) { + if (!nm_setting_verify(NM_SETTING(s_wifi), connection, error)) + return FALSE; + ap = NULL; + } else if (!specific_object) { + /* If not given a specific object, we need at minimum an SSID */ + if (!s_wifi) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wireless' setting is required if no AP path was given."); + return FALSE; + } + + setting_ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!setting_ssid || g_bytes_get_size(setting_ssid) == 0) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wireless' setting with a valid SSID is required if no AP path was given."); + return FALSE; + } + + /* Find a compatible AP in the scan list */ + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + if (!ap) { + /* If we still don't have an AP, then the WiFI settings needs to be + * fully specified by the client. Might not be able to find an AP + * if the network isn't broadcasting the SSID for example. + */ + if (!nm_setting_verify(NM_SETTING(s_wifi), connection, error)) + return FALSE; + + hidden = TRUE; + } + } else { + ap = nm_wifi_ap_lookup_for_device(NM_DEVICE(self), specific_object); + if (!ap) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, + "The access point %s was not in the scan list.", + specific_object); + return FALSE; + } + } + + /* Add a wifi setting if one doesn't exist yet */ + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + } + + ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!ssid && ap) + ssid = nm_wifi_ap_get_ssid(ap); + + if (!ssid) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wireless' setting with a valid SSID is required."); + return FALSE; + } + + if (ap) { + if (!nm_wifi_ap_complete_connection(ap, + connection, + nm_wifi_utils_is_manf_default_ssid(ssid), + error)) + return FALSE; + } + + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); + nm_utils_complete_generic( + nm_device_get_platform(device), + connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + ssid_utf8, + ssid_utf8, + NULL, + nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device), + TRUE); + + if (hidden) + g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); + + return TRUE; } static gboolean -get_variant_boolean (GVariant *v, const char *property) +get_variant_boolean(GVariant *v, const char *property) { - if (!v || !g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Property %s not cached or not boolean type", property); + if (!v || !g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) { + nm_log_warn(LOGD_DEVICE | LOGD_WIFI, + "Property %s not cached or not boolean type", + property); - return FALSE; - } + return FALSE; + } - return g_variant_get_boolean (v); + return g_variant_get_boolean(v); } static const char * -get_variant_state (GVariant *v) +get_variant_state(GVariant *v) { - if (!v || !g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "State property not cached or not a string"); + if (!v || !g_variant_is_of_type(v, G_VARIANT_TYPE_STRING)) { + nm_log_warn(LOGD_DEVICE | LOGD_WIFI, "State property not cached or not a string"); - return "unknown"; - } + return "unknown"; + } - return g_variant_get_string (v, NULL); + return g_variant_get_string(v, NULL); } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDeviceState state = nm_device_get_state (device); - - /* Available if either the device is UP and in station mode - * or in AP/Ad-Hoc modes while activating or activated. Device - * may be temporarily DOWN while activating or deactivating and - * we don't want it to be marked unavailable because of this. - * - * For reference: - * We call nm_device_queue_recheck_available whenever - * priv->enabled changes or priv->dbus_station_proxy changes. - */ - return priv->dbus_obj - && priv->enabled - && ( priv->dbus_station_proxy - || (state >= NM_DEVICE_STATE_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING)); +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDeviceState state = nm_device_get_state(device); + + /* Available if either the device is UP and in station mode + * or in AP/Ad-Hoc modes while activating or activated. Device + * may be temporarily DOWN while activating or deactivating and + * we don't want it to be marked unavailable because of this. + * + * For reference: + * We call nm_device_queue_recheck_available whenever + * priv->enabled changes or priv->dbus_station_proxy changes. + */ + return priv->dbus_obj && priv->enabled + && (priv->dbus_station_proxy + || (state >= NM_DEVICE_STATE_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING)); } static gboolean -get_autoconnect_allowed (NMDevice *device) +get_autoconnect_allowed(NMDevice *device) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (NM_DEVICE_IWD (device)); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(NM_DEVICE_IWD(device)); - return priv->can_connect; + return priv->can_connect; } static gboolean -can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, - char **specific_object) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMConnection *connection; - NMSettingWireless *s_wifi; - NMWifiAP *ap; - const char *mode; - guint64 timestamp = 0; - - nm_assert (!specific_object || !*specific_object); - - if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->can_auto_connect (device, sett_conn, NULL)) - return FALSE; - - connection = nm_settings_connection_get_connection (sett_conn); - - s_wifi = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wifi, FALSE); - - /* Don't auto-activate AP or Ad-Hoc connections. - * Note the wpa_supplicant backend has the opposite policy. - */ - mode = nm_setting_wireless_get_mode (s_wifi); - if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) - return FALSE; - - /* Don't autoconnect to networks that have been tried at least once - * but haven't been successful, since these are often accidental choices - * from the menu and the user may not know the password. - */ - if (nm_settings_connection_get_timestamp (sett_conn, ×tamp)) { - if (timestamp == 0) - return FALSE; - } - - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - if (ap) { - /* All good; connection is usable */ - NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)))); - return TRUE; - } - - return FALSE; +can_auto_connect(NMDevice *device, NMSettingsConnection *sett_conn, char **specific_object) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMConnection * connection; + NMSettingWireless * s_wifi; + NMWifiAP * ap; + const char * mode; + guint64 timestamp = 0; + + nm_assert(!specific_object || !*specific_object); + + if (!NM_DEVICE_CLASS(nm_device_iwd_parent_class)->can_auto_connect(device, sett_conn, NULL)) + return FALSE; + + connection = nm_settings_connection_get_connection(sett_conn); + + s_wifi = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wifi, FALSE); + + /* Don't auto-activate AP or Ad-Hoc connections. + * Note the wpa_supplicant backend has the opposite policy. + */ + mode = nm_setting_wireless_get_mode(s_wifi); + if (mode && g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) + return FALSE; + + /* Don't autoconnect to networks that have been tried at least once + * but haven't been successful, since these are often accidental choices + * from the menu and the user may not know the password. + */ + if (nm_settings_connection_get_timestamp(sett_conn, ×tamp)) { + if (timestamp == 0) + return FALSE; + } + + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + if (ap) { + /* All good; connection is usable */ + NM_SET_OUT(specific_object, g_strdup(nm_dbus_object_get_path(NM_DBUS_OBJECT(ap)))); + return TRUE; + } + + return FALSE; } const CList * -_nm_device_iwd_get_aps (NMDeviceIwd *self) +_nm_device_iwd_get_aps(NMDeviceIwd *self) { - return &NM_DEVICE_IWD_GET_PRIVATE (self)->aps_lst_head; + return &NM_DEVICE_IWD_GET_PRIVATE(self)->aps_lst_head; } static void -scan_cb (GObject *source, GAsyncResult *res, gpointer user_data) +scan_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv; - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant && nm_utils_error_is_cancelled (error)) - return; + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant && nm_utils_error_is_cancelled(error)) + return; - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - priv->scan_requested = FALSE; - priv->last_scan = nm_utils_get_monotonic_timestamp_msec (); - _notify (self, PROP_LAST_SCAN); + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + priv->scan_requested = FALSE; + priv->last_scan = nm_utils_get_monotonic_timestamp_msec(); + _notify(self, PROP_LAST_SCAN); - /* On success, priv->scanning becomes true right before or right - * after this callback, so the next automatic scan will be - * scheduled when priv->scanning goes back to false. On error, - * schedule a retry now. - */ - if (error && !priv->scanning) - schedule_periodic_scan (self, FALSE); + /* On success, priv->scanning becomes true right before or right + * after this callback, so the next automatic scan will be + * scheduled when priv->scanning goes back to false. On error, + * schedule a retry now. + */ + if (error && !priv->scanning) + schedule_periodic_scan(self, FALSE); } static void -dbus_request_scan_cb (NMDevice *device, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv; - gs_unref_variant GVariant *scan_options = user_data; - - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - return; - } - - if (check_scanning_prohibited (self, FALSE)) { - g_dbus_method_invocation_return_error_literal (context, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "Scanning not allowed at this time"); - return; - } - - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - - if (!priv->can_scan) { - g_dbus_method_invocation_return_error_literal (context, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "Scanning not allowed while unavailable"); - return; - } - - if (scan_options) { - gs_unref_variant GVariant *val = g_variant_lookup_value (scan_options, "ssids", NULL); - - if (val) { - g_dbus_method_invocation_return_error_literal (context, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "'ssid' scan option not supported"); - return; - } - } - - if (!priv->scanning && !priv->scan_requested) { - g_dbus_proxy_call (priv->dbus_station_proxy, "Scan", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, - priv->cancellable, scan_cb, self); - priv->scan_requested = TRUE; - } - - g_dbus_method_invocation_return_value (context, NULL); +dbus_request_scan_cb(NMDevice * device, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv; + gs_unref_variant GVariant *scan_options = user_data; + + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + return; + } + + if (check_scanning_prohibited(self, FALSE)) { + g_dbus_method_invocation_return_error_literal(context, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "Scanning not allowed at this time"); + return; + } + + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + + if (!priv->can_scan) { + g_dbus_method_invocation_return_error_literal(context, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "Scanning not allowed while unavailable"); + return; + } + + if (scan_options) { + gs_unref_variant GVariant *val = g_variant_lookup_value(scan_options, "ssids", NULL); + + if (val) { + g_dbus_method_invocation_return_error_literal(context, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "'ssid' scan option not supported"); + return; + } + } + + if (!priv->scanning && !priv->scan_requested) { + g_dbus_proxy_call(priv->dbus_station_proxy, + "Scan", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + scan_cb, + self); + priv->scan_requested = TRUE; + } + + g_dbus_method_invocation_return_value(context, NULL); } void -_nm_device_iwd_request_scan (NMDeviceIwd *self, - GVariant *options, - GDBusMethodInvocation *invocation) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - - if (!priv->can_scan) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "Scanning not allowed while unavailable"); - return; - } - - nm_device_auth_request (device, - invocation, - NULL, - NM_AUTH_PERMISSION_WIFI_SCAN, - TRUE, - NULL, - dbus_request_scan_cb, - nm_g_variant_ref (options)); +_nm_device_iwd_request_scan(NMDeviceIwd *self, GVariant *options, GDBusMethodInvocation *invocation) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + + if (!priv->can_scan) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "Scanning not allowed while unavailable"); + return; + } + + nm_device_auth_request(device, + invocation, + NULL, + NM_AUTH_PERMISSION_WIFI_SCAN, + TRUE, + NULL, + dbus_request_scan_cb, + nm_g_variant_ref(options)); } static gboolean -check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - - g_return_val_if_fail (priv->dbus_obj != NULL, TRUE); - - switch (nm_device_get_state (NM_DEVICE (self))) { - case NM_DEVICE_STATE_UNKNOWN: - case NM_DEVICE_STATE_UNMANAGED: - case NM_DEVICE_STATE_UNAVAILABLE: - case NM_DEVICE_STATE_PREPARE: - case NM_DEVICE_STATE_CONFIG: - case NM_DEVICE_STATE_NEED_AUTH: - case NM_DEVICE_STATE_IP_CONFIG: - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_DEACTIVATING: - /* Prohibit scans when unusable or activating */ - return TRUE; - case NM_DEVICE_STATE_DISCONNECTED: - case NM_DEVICE_STATE_FAILED: - case NM_DEVICE_STATE_ACTIVATED: - break; - } - - /* Prohibit scans if IWD is busy */ - return !priv->can_scan; +check_scanning_prohibited(NMDeviceIwd *self, gboolean periodic) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + + g_return_val_if_fail(priv->dbus_obj != NULL, TRUE); + + switch (nm_device_get_state(NM_DEVICE(self))) { + case NM_DEVICE_STATE_UNKNOWN: + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_DEACTIVATING: + /* Prohibit scans when unusable or activating */ + return TRUE; + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_FAILED: + case NM_DEVICE_STATE_ACTIVATED: + break; + } + + /* Prohibit scans if IWD is busy */ + return !priv->can_scan; } /* @@ -1110,376 +1136,376 @@ check_scanning_prohibited (NMDeviceIwd *self, gboolean periodic) * * Check if the connection settings already have the secrets corresponding * to the IWD agent method that was invoked. If they do, send the method reply - * with the appropriate secrets. Otherwise return the missing secret's setting + * with the appropriate secrets. Otherwise, return the missing secret's setting * name and key so the caller can send a NM secrets request with this data. * Return TRUE in either case, return FALSE if an error is detected. */ static gboolean -try_reply_agent_request (NMDeviceIwd *self, - NMConnection *connection, - GDBusMethodInvocation *invocation, - const char **setting_name, - const char **setting_key, - gboolean *replied) -{ - const char *method_name = g_dbus_method_invocation_get_method_name (invocation); - NMSettingWirelessSecurity *s_wireless_sec; - NMSetting8021x *s_8021x; - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - s_8021x = nm_connection_get_setting_802_1x (connection); - - *replied = FALSE; - - if (nm_streq (method_name, "RequestPassphrase")) { - const char *psk; - - if (!s_wireless_sec) - return FALSE; - - psk = nm_setting_wireless_security_get_psk (s_wireless_sec); - if (psk) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning the PSK to the IWD Agent"); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", psk)); - *replied = TRUE; - return TRUE; - } - - *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; - return TRUE; - } else if (nm_streq (method_name, "RequestPrivateKeyPassphrase")) { - const char *password; - - if (!s_8021x) - return FALSE; - - password = nm_setting_802_1x_get_private_key_password (s_8021x); - if (password) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning the private key password to the IWD Agent"); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", password)); - *replied = TRUE; - return TRUE; - } - - *setting_name = NM_SETTING_802_1X_SETTING_NAME; - *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; - return TRUE; - } else if (nm_streq (method_name, "RequestUserNameAndPassword")) { - const char *identity, *password; - - if (!s_8021x) - return FALSE; - - identity = nm_setting_802_1x_get_identity (s_8021x); - password = nm_setting_802_1x_get_password (s_8021x); - if (identity && password) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning the username and password to the IWD Agent"); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(ss)", identity, password)); - *replied = TRUE; - return TRUE; - } - - *setting_name = NM_SETTING_802_1X_SETTING_NAME; - if (!identity) - *setting_key = NM_SETTING_802_1X_IDENTITY; - else - *setting_key = NM_SETTING_802_1X_PASSWORD; - return TRUE; - } else if (nm_streq (method_name, "RequestUserPassword")) { - const char *password; - - if (!s_8021x) - return FALSE; - - password = nm_setting_802_1x_get_password (s_8021x); - if (password) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Returning the user password to the IWD Agent"); - - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", password)); - *replied = TRUE; - return TRUE; - } - - *setting_name = NM_SETTING_802_1X_SETTING_NAME; - *setting_key = NM_SETTING_802_1X_PASSWORD; - return TRUE; - } else - return FALSE; -} - -static void -wifi_secrets_get_one (NMDeviceIwd *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *setting_key, - GDBusMethodInvocation *invocation); +try_reply_agent_request(NMDeviceIwd * self, + NMConnection * connection, + GDBusMethodInvocation *invocation, + const char ** setting_name, + const char ** setting_key, + gboolean * replied) +{ + const char * method_name = g_dbus_method_invocation_get_method_name(invocation); + NMSettingWirelessSecurity *s_wireless_sec; + NMSetting8021x * s_8021x; + + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + s_8021x = nm_connection_get_setting_802_1x(connection); + + *replied = FALSE; + + if (nm_streq(method_name, "RequestPassphrase")) { + const char *psk; + + if (!s_wireless_sec) + return FALSE; + + psk = nm_setting_wireless_security_get_psk(s_wireless_sec); + if (psk) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; + return TRUE; + } else if (nm_streq(method_name, "RequestPrivateKeyPassphrase")) { + const char *password; + + if (!s_8021x) + return FALSE; + + password = nm_setting_802_1x_get_private_key_password(s_8021x); + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the private key password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; + return TRUE; + } else if (nm_streq(method_name, "RequestUserNameAndPassword")) { + const char *identity, *password; + + if (!s_8021x) + return FALSE; + + identity = nm_setting_802_1x_get_identity(s_8021x); + password = nm_setting_802_1x_get_password(s_8021x); + if (identity && password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the username and password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(ss)", identity, password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + if (!identity) + *setting_key = NM_SETTING_802_1X_IDENTITY; + else + *setting_key = NM_SETTING_802_1X_PASSWORD; + return TRUE; + } else if (nm_streq(method_name, "RequestUserPassword")) { + const char *password; + + if (!s_8021x) + return FALSE; + + password = nm_setting_802_1x_get_password(s_8021x); + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } + + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + *setting_key = NM_SETTING_802_1X_PASSWORD; + return TRUE; + } else + return FALSE; +} + +static void wifi_secrets_get_one(NMDeviceIwd * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char * setting_key, + GDBusMethodInvocation * invocation); static void -wifi_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *s_connection, - GError *error, - gpointer user_data) -{ - NMDeviceIwd *self; - NMDeviceIwdPrivate *priv; - NMDevice *device; - GDBusMethodInvocation *invocation; - const char *setting_name; - const char *setting_key; - gboolean replied; - NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - - nm_utils_user_data_unpack (user_data, &self, &invocation); - - g_return_if_fail (NM_IS_DEVICE_IWD (self)); - - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - device = NM_DEVICE (self); - - g_return_if_fail (priv->wifi_secrets_id == call_id); - - priv->wifi_secrets_id = NULL; - - if (nm_utils_error_is_cancelled (error)) { - g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "NM secrets request cancelled"); - return; - } - - g_return_if_fail (req == nm_device_get_act_request (device)); - g_return_if_fail (nm_act_request_get_settings_connection (req) == s_connection); - - if (nm_device_get_state (device) != NM_DEVICE_STATE_NEED_AUTH) - goto secrets_error; - - if (error) { - _LOGW (LOGD_WIFI, "%s", error->message); - goto secrets_error; - } - - if (!try_reply_agent_request (self, nm_act_request_get_applied_connection (req), - invocation, &setting_name, &setting_key, - &replied)) - goto secrets_error; - - if (replied) { - /* Change state back to what it was before NEED_AUTH */ - nm_device_state_changed (device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); - return; - } - - if (nm_settings_connection_get_timestamp (nm_act_request_get_settings_connection (req), - NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - /* Request further secrets if we still need something */ - wifi_secrets_get_one (self, setting_name, get_secret_flags, - setting_key, invocation); - return; +wifi_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * s_connection, + GError * error, + gpointer user_data) +{ + NMDeviceIwd * self; + NMDeviceIwdPrivate * priv; + NMDevice * device; + GDBusMethodInvocation * invocation; + const char * setting_name; + const char * setting_key; + gboolean replied; + NMSecretAgentGetSecretsFlags get_secret_flags = + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + + nm_utils_user_data_unpack(user_data, &self, &invocation); + + g_return_if_fail(NM_IS_DEVICE_IWD(self)); + + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + device = NM_DEVICE(self); + + g_return_if_fail(priv->wifi_secrets_id == call_id); + + priv->wifi_secrets_id = NULL; + + if (nm_utils_error_is_cancelled(error)) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "NM secrets request cancelled"); + return; + } + + g_return_if_fail(req == nm_device_get_act_request(device)); + g_return_if_fail(nm_act_request_get_settings_connection(req) == s_connection); + + if (nm_device_get_state(device) != NM_DEVICE_STATE_NEED_AUTH) + goto secrets_error; + + if (error) { + _LOGW(LOGD_WIFI, "%s", error->message); + goto secrets_error; + } + + if (!try_reply_agent_request(self, + nm_act_request_get_applied_connection(req), + invocation, + &setting_name, + &setting_key, + &replied)) + goto secrets_error; + + if (replied) { + /* Change state back to what it was before NEED_AUTH */ + nm_device_state_changed(device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); + return; + } + + if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + + /* Request further secrets if we still need something */ + wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); + return; secrets_error: - g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "NM secrets request failed"); - /* Now wait for the Connect callback to update device state */ + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "NM secrets request failed"); + /* Now wait for the Connect callback to update device state */ } static void -wifi_secrets_get_one (NMDeviceIwd *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - const char *setting_key, - GDBusMethodInvocation *invocation) +wifi_secrets_get_one(NMDeviceIwd * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags, + const char * setting_key, + GDBusMethodInvocation * invocation) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMActRequest *req; + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMActRequest * req; - wifi_secrets_cancel (self); + wifi_secrets_cancel(self); - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); - priv->wifi_secrets_id = nm_act_request_get_secrets (req, - TRUE, - setting_name, - flags, - NM_MAKE_STRV (setting_key), - wifi_secrets_cb, - nm_utils_user_data_pack (self, invocation)); + priv->wifi_secrets_id = nm_act_request_get_secrets(req, + TRUE, + setting_name, + flags, + NM_MAKE_STRV(setting_key), + wifi_secrets_cb, + nm_utils_user_data_pack(self, invocation)); } static void -network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data) +network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDevice *device = NM_DEVICE (self); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; - NMConnection *connection; - NMSettingWireless *s_wifi; - GBytes *ssid; - gs_free char *ssid_utf8 = NULL; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED; - GVariant *value; + NMDeviceIwd * self = user_data; + NMDevice * device = NM_DEVICE(self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + NMConnection * connection; + NMSettingWireless * s_wifi; + GBytes * ssid; + gs_free char * ssid_utf8 = NULL; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED; + GVariant * value; - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant) { - gs_free char *dbus_error = NULL; + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant) { + gs_free char *dbus_error = NULL; - /* Connection failed; radio problems or if the network wasn't - * open, the passwords or certificates may be wrong. - */ + /* Connection failed; radio problems or if the network wasn't + * open, the passwords or certificates may be wrong. + */ - _LOGE (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Network.Connect failed: %s", - error->message); + _LOGE(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Network.Connect failed: %s", + error->message); - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - if (!NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH)) - return; + if (!NM_IN_SET(nm_device_get_state(device), + NM_DEVICE_STATE_CONFIG, + NM_DEVICE_STATE_NEED_AUTH)) + return; - connection = nm_device_get_applied_connection (device); - if (!connection) - goto failed; + connection = nm_device_get_applied_connection(device); + if (!connection) + goto failed; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) - dbus_error = g_dbus_error_get_remote_error (error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) + dbus_error = g_dbus_error_get_remote_error(error); - if (nm_streq0 (dbus_error, "net.connman.iwd.Failed")) { - nm_connection_clear_secrets (connection); + if (nm_streq0(dbus_error, "net.connman.iwd.Failed")) { + nm_connection_clear_secrets(connection); - /* If secrets were wrong, we'd be getting a net.connman.iwd.Failed */ - reason = NM_DEVICE_STATE_REASON_NO_SECRETS; - } else if (nm_streq0 (dbus_error, "net.connman.iwd.Aborted")) { - /* If agent call was cancelled we'd be getting a net.connman.iwd.Aborted */ - reason = NM_DEVICE_STATE_REASON_NO_SECRETS; - } + /* If secrets were wrong, we'd be getting a net.connman.iwd.Failed */ + reason = NM_DEVICE_STATE_REASON_NO_SECRETS; + } else if (nm_streq0(dbus_error, "net.connman.iwd.Aborted")) { + /* If agent call was cancelled we'd be getting a net.connman.iwd.Aborted */ + reason = NM_DEVICE_STATE_REASON_NO_SECRETS; + } - goto failed; - } + goto failed; + } - nm_assert (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); + nm_assert(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG); - connection = nm_device_get_applied_connection (device); - if (!connection) - goto failed; + connection = nm_device_get_applied_connection(device); + if (!connection) + goto failed; - s_wifi = nm_connection_get_setting_wireless (connection); - if (!s_wifi) - goto failed; + s_wifi = nm_connection_get_setting_wireless(connection); + if (!s_wifi) + goto failed; - ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!ssid) - goto failed; + ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!ssid) + goto failed; - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Connected to '%s'.", - ssid_utf8); - nm_device_activate_schedule_stage3_ip_config_start (device); + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Connected to '%s'.", + ssid_utf8); + nm_device_activate_schedule_stage3_ip_config_start(device); - return; + return; failed: - /* Call Disconnect to make sure IWD's autoconnect is disabled */ - cleanup_association_attempt (self, TRUE); + /* Call Disconnect to make sure IWD's autoconnect is disabled */ + cleanup_association_attempt(self, TRUE); - nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, reason); + nm_device_queue_state(device, NM_DEVICE_STATE_FAILED, reason); - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); - if (!priv->can_connect && nm_streq0 (get_variant_state (value), "disconnected")) { - priv->can_connect = true; - nm_device_emit_recheck_auto_activate (device); - } - g_variant_unref (value); + value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State"); + if (!priv->can_connect && nm_streq0(get_variant_state(value), "disconnected")) { + priv->can_connect = true; + nm_device_emit_recheck_auto_activate(device); + } + g_variant_unref(value); } static void -act_failed_cb (GObject *source, GAsyncResult *res, gpointer user_data) +act_failed_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDevice *device = NM_DEVICE (self); - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; + NMDeviceIwd * self = user_data; + NMDevice * device = NM_DEVICE(self); + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant && nm_utils_error_is_cancelled (error)) - return; + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant && nm_utils_error_is_cancelled(error)) + return; - /* Change state to FAILED unless already done by state_changed - * which may have been triggered by the station interface - * appearing on DBus. - */ - if (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG) - nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + /* Change state to FAILED unless already done by state_changed + * which may have been triggered by the station interface + * appearing on DBus. + */ + if (nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG) + nm_device_queue_state(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); } static void -act_start_cb (GObject *source, GAsyncResult *res, gpointer user_data) +act_start_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; - NMSettingWireless *s_wireless; - GBytes *ssid; - gs_free char *ssid_utf8 = NULL; + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + NMSettingWireless * s_wireless; + GBytes * ssid; + gs_free char * ssid_utf8 = NULL; - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant) { - _LOGE (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Network.Connect failed: %s", - error->message); + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant) { + _LOGE(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Network.Connect failed: %s", + error->message); - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - if (!NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG)) - return; + if (!NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG)) + return; - goto error; - } + goto error; + } - nm_assert (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); + nm_assert(nm_device_get_state(device) == NM_DEVICE_STATE_CONFIG); - s_wireless = nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); - if (!s_wireless) - goto error; + s_wireless = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS); + if (!s_wireless) + goto error; - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid) - goto error; + ssid = nm_setting_wireless_get_ssid(s_wireless); + if (!ssid) + goto error; - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Started '%s'.", - ssid_utf8); + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Started '%s'.", + ssid_utf8); - nm_device_activate_schedule_stage3_ip_config_start (device); - return; + nm_device_activate_schedule_stage3_ip_config_start(device); + return; error: - reset_mode (self, priv->cancellable, act_failed_cb, self); + reset_mode(self, priv->cancellable, act_failed_cb, self); } /* Check if we're activating an AP/AdHoc connection and if the target @@ -1487,1150 +1513,1198 @@ error: * StartOpen on that interface. */ static void -act_check_interface (NMDeviceIwd *self) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wireless_sec; - GDBusProxy *proxy = NULL; - GBytes *ssid; - gs_free char *ssid_utf8 = NULL; - const char *mode; - - if (!priv->act_mode_switch) - return; - - s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); - - mode = nm_setting_wireless_get_mode (s_wireless); - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) - proxy = priv->dbus_ap_proxy; - else if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) - proxy = priv->dbus_adhoc_proxy; - - if (!proxy) - return; - - priv->act_mode_switch = FALSE; - - if (!NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG)) - return; - - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid) - goto failed; - - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - - s_wireless_sec = (NMSettingWirelessSecurity *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS_SECURITY); - - if (!s_wireless_sec) { - g_dbus_proxy_call (proxy, "StartOpen", - g_variant_new ("(s)", ssid_utf8), - G_DBUS_CALL_FLAGS_NONE, G_MAXINT, - priv->cancellable, act_start_cb, self); - } else { - const char *psk = nm_setting_wireless_security_get_psk (s_wireless_sec); - - if (!psk) { - _LOGE (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) No PSK for '%s'.", - ssid_utf8); - goto failed; - } - - g_dbus_proxy_call (proxy, "Start", - g_variant_new ("(ss)", ssid_utf8, psk), - G_DBUS_CALL_FLAGS_NONE, G_MAXINT, - priv->cancellable, act_start_cb, self); - } - - _LOGD (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Called Start('%s').", - ssid_utf8); - return; +act_check_interface(NMDeviceIwd *self) +{ + NMDeviceIwdPrivate * priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wireless_sec; + GDBusProxy * proxy = NULL; + GBytes * ssid; + gs_free char * ssid_utf8 = NULL; + const char * mode; + + if (!priv->act_mode_switch) + return; + + s_wireless = + (NMSettingWireless *) nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS); + + mode = nm_setting_wireless_get_mode(s_wireless); + if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) + proxy = priv->dbus_ap_proxy; + else if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) + proxy = priv->dbus_adhoc_proxy; + + if (!proxy) + return; + + priv->act_mode_switch = FALSE; + + if (!NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG)) + return; + + ssid = nm_setting_wireless_get_ssid(s_wireless); + if (!ssid) + goto failed; + + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); + + s_wireless_sec = (NMSettingWirelessSecurity *) nm_device_get_applied_setting( + device, + NM_TYPE_SETTING_WIRELESS_SECURITY); + + if (!s_wireless_sec) { + g_dbus_proxy_call(proxy, + "StartOpen", + g_variant_new("(s)", ssid_utf8), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + priv->cancellable, + act_start_cb, + self); + } else { + const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec); + + if (!psk) { + _LOGE(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) No PSK for '%s'.", ssid_utf8); + goto failed; + } + + g_dbus_proxy_call(proxy, + "Start", + g_variant_new("(ss)", ssid_utf8, psk), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + priv->cancellable, + act_start_cb, + self); + } + + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Called Start('%s').", ssid_utf8); + return; failed: - reset_mode (self, priv->cancellable, act_failed_cb, self); + reset_mode(self, priv->cancellable, act_failed_cb, self); } static void -act_set_mode_cb (GObject *source, GAsyncResult *res, gpointer user_data) +act_set_mode_cb(GObject *source, GAsyncResult *res, gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - gs_unref_variant GVariant *variant = NULL; - gs_free_error GError *error = NULL; + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; - variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); - if (!variant) { - _LOGE (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Setting Device.Mode failed: %s", - error->message); + variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!variant) { + _LOGE(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Setting Device.Mode failed: %s", + error->message); - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - if ( !NM_IN_SET (nm_device_get_state (device), NM_DEVICE_STATE_CONFIG) - || !priv->act_mode_switch) - return; + if (!NM_IN_SET(nm_device_get_state(device), NM_DEVICE_STATE_CONFIG) + || !priv->act_mode_switch) + return; - priv->act_mode_switch = FALSE; - nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return; - } + priv->act_mode_switch = FALSE; + nm_device_queue_state(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return; + } - _LOGD (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) IWD Device.Mode set successfully"); + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) IWD Device.Mode set successfully"); - act_check_interface (self); + act_check_interface(self); } static void -act_set_mode (NMDeviceIwd *self) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - const char *iwd_mode; - const char *mode; - NMSettingWireless *s_wireless; - - s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); - mode = nm_setting_wireless_get_mode (s_wireless); - - /* We need to first set interface mode (Device.Mode) to ap or ad-hoc. - * We can't directly queue a call to the Start/StartOpen method on - * the DBus interface that's going to be created after the property - * set call returns. - */ - iwd_mode = nm_streq (mode, NM_SETTING_WIRELESS_MODE_AP) ? "ap" : "ad-hoc"; - - if (!priv->cancellable) - priv->cancellable = g_cancellable_new (); - - g_dbus_proxy_call (priv->dbus_device_proxy, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new ("(ssv)", NM_IWD_DEVICE_INTERFACE, - "Mode", - g_variant_new ("s", iwd_mode)), - G_DBUS_CALL_FLAGS_NONE, 2000, - priv->cancellable, act_set_mode_cb, self); - priv->act_mode_switch = TRUE; +act_set_mode(NMDeviceIwd *self) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + const char * iwd_mode; + const char * mode; + NMSettingWireless * s_wireless; + + s_wireless = + (NMSettingWireless *) nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS); + mode = nm_setting_wireless_get_mode(s_wireless); + + /* We need to first set interface mode (Device.Mode) to ap or ad-hoc. + * We can't directly queue a call to the Start/StartOpen method on + * the DBus interface that's going to be created after the property + * set call returns. + */ + iwd_mode = nm_streq(mode, NM_SETTING_WIRELESS_MODE_AP) ? "ap" : "ad-hoc"; + + if (!priv->cancellable) + priv->cancellable = g_cancellable_new(); + + g_dbus_proxy_call( + priv->dbus_device_proxy, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", NM_IWD_DEVICE_INTERFACE, "Mode", g_variant_new("s", iwd_mode)), + G_DBUS_CALL_FLAGS_NONE, + 2000, + priv->cancellable, + act_set_mode_cb, + self); + priv->act_mode_switch = TRUE; } static void -act_psk_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *s_connection, - GError *error, - gpointer user_data) +act_psk_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * s_connection, + GError * error, + gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv; - NMDevice *device; + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv; + NMDevice * device; - if (nm_utils_error_is_cancelled (error)) - return; + if (nm_utils_error_is_cancelled(error)) + return; - priv = NM_DEVICE_IWD_GET_PRIVATE (self); - device = NM_DEVICE (self); + priv = NM_DEVICE_IWD_GET_PRIVATE(self); + device = NM_DEVICE(self); - g_return_if_fail (priv->wifi_secrets_id == call_id); - priv->wifi_secrets_id = NULL; + g_return_if_fail(priv->wifi_secrets_id == call_id); + priv->wifi_secrets_id = NULL; - g_return_if_fail (req == nm_device_get_act_request (device)); - g_return_if_fail (nm_act_request_get_settings_connection (req) == s_connection); + g_return_if_fail(req == nm_device_get_act_request(device)); + g_return_if_fail(nm_act_request_get_settings_connection(req) == s_connection); - if (nm_device_get_state (device) != NM_DEVICE_STATE_NEED_AUTH) - goto secrets_error; + if (nm_device_get_state(device) != NM_DEVICE_STATE_NEED_AUTH) + goto secrets_error; - if (error) { - _LOGW (LOGD_WIFI, "%s", error->message); - goto secrets_error; - } + if (error) { + _LOGW(LOGD_WIFI, "%s", error->message); + goto secrets_error; + } - _LOGD (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) missing PSK request completed"); + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) missing PSK request completed"); - /* Change state back to what it was before NEED_AUTH */ - nm_device_state_changed (device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); - act_set_mode (self); - return; + /* Change state back to what it was before NEED_AUTH */ + nm_device_state_changed(device, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); + act_set_mode(self); + return; secrets_error: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - cleanup_association_attempt (self, FALSE); + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + cleanup_association_attempt(self, FALSE); } static void -set_powered (NMDeviceIwd *self, gboolean powered) +set_powered(NMDeviceIwd *self, gboolean powered) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - g_dbus_proxy_call (priv->dbus_device_proxy, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new ("(ssv)", NM_IWD_DEVICE_INTERFACE, - "Powered", - g_variant_new ("b", powered)), - G_DBUS_CALL_FLAGS_NONE, 2000, - NULL, NULL, NULL); + g_dbus_proxy_call( + priv->dbus_device_proxy, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", NM_IWD_DEVICE_INTERFACE, "Powered", g_variant_new("b", powered)), + G_DBUS_CALL_FLAGS_NONE, + 2000, + NULL, + NULL, + NULL); } /*****************************************************************************/ static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMWifiAP *ap = NULL; - gs_unref_object NMWifiAP *ap_fake = NULL; - NMActRequest *req; - NMConnection *connection; - NMSettingWireless *s_wireless; - const char *mode; - const char *ap_path; - - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - connection = nm_act_request_get_applied_connection (req); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wireless, NM_ACT_STAGE_RETURN_FAILURE); - - /* AP mode never uses a specific object or existing scanned AP */ - mode = nm_setting_wireless_get_mode (s_wireless); - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) - goto add_new; - - ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); - ap = ap_path - ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) - : NULL; - if (ap) { - set_current_ap (self, ap, TRUE); - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - if (ap) { - nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); - set_current_ap (self, ap, TRUE); - return NM_ACT_STAGE_RETURN_SUCCESS; - } - - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_INFRA)) { - /* Hidden networks not supported at this time */ - return NM_ACT_STAGE_RETURN_FAILURE; - } +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMWifiAP * ap = NULL; + gs_unref_object NMWifiAP *ap_fake = NULL; + NMActRequest * req; + NMConnection * connection; + NMSettingWireless * s_wireless; + const char * mode; + const char * ap_path; + + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection(req); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wireless, NM_ACT_STAGE_RETURN_FAILURE); + + /* AP mode never uses a specific object or existing scanned AP */ + mode = nm_setting_wireless_get_mode(s_wireless); + if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) + goto add_new; + + ap_path = nm_active_connection_get_specific_object(NM_ACTIVE_CONNECTION(req)); + ap = ap_path ? nm_wifi_ap_lookup_for_device(NM_DEVICE(self), ap_path) : NULL; + if (ap) { + set_current_ap(self, ap, TRUE); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + if (ap) { + nm_active_connection_set_specific_object(NM_ACTIVE_CONNECTION(req), + nm_dbus_object_get_path(NM_DBUS_OBJECT(ap))); + set_current_ap(self, ap, TRUE); + return NM_ACT_STAGE_RETURN_SUCCESS; + } + + if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_INFRA)) { + /* Hidden networks not supported at this time */ + return NM_ACT_STAGE_RETURN_FAILURE; + } add_new: - /* If the user is trying to connect to an AP that NM doesn't yet know about - * (hidden network or something) or starting a Hotspot, create an fake AP - * from the security settings in the connection. This "fake" AP gets used - * until the real one is found in the scan list (Ad-Hoc or Hidden), or until - * the device is deactivated (Ad-Hoc or Hotspot). - */ - ap_fake = nm_wifi_ap_new_fake_from_connection (connection); - if (!ap_fake) - g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - - if (nm_wifi_ap_is_hotspot (ap_fake)) - nm_wifi_ap_set_address (ap_fake, nm_device_get_hw_address (device)); - - g_object_freeze_notify (G_OBJECT (self)); - ap_add_remove (self, TRUE, ap_fake, FALSE); - g_object_thaw_notify (G_OBJECT (self)); - set_current_ap (self, ap_fake, FALSE); - nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_dbus_object_get_path (NM_DBUS_OBJECT (ap_fake))); - return NM_ACT_STAGE_RETURN_SUCCESS; + /* If the user is trying to connect to an AP that NM doesn't yet know about + * (hidden network or something) or starting a Hotspot, create an fake AP + * from the security settings in the connection. This "fake" AP gets used + * until the real one is found in the scan list (Ad-Hoc or Hidden), or until + * the device is deactivated (Ad-Hoc or Hotspot). + */ + ap_fake = nm_wifi_ap_new_fake_from_connection(connection); + if (!ap_fake) + g_return_val_if_reached(NM_ACT_STAGE_RETURN_FAILURE); + + if (nm_wifi_ap_is_hotspot(ap_fake)) + nm_wifi_ap_set_address(ap_fake, nm_device_get_hw_address(device)); + + g_object_freeze_notify(G_OBJECT(self)); + ap_add_remove(self, TRUE, ap_fake, FALSE); + g_object_thaw_notify(G_OBJECT(self)); + set_current_ap(self, ap_fake, FALSE); + nm_active_connection_set_specific_object(NM_ACTIVE_CONNECTION(req), + nm_dbus_object_get_path(NM_DBUS_OBJECT(ap_fake))); + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMActRequest *req; - NMConnection *connection; - NMSettingWireless *s_wireless; - const char *mode; - - req = nm_device_get_act_request (device); - connection = nm_act_request_get_applied_connection (req); - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wireless, NM_ACT_STAGE_RETURN_FAILURE); - - mode = nm_setting_wireless_get_mode (s_wireless); - - if (NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { - gs_unref_object GDBusProxy *network_proxy = NULL; - NMWifiAP *ap = priv->current_ap; - - if (!ap) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - goto out_fail; - } - - /* 802.1x networks that are not IWD Known Networks will definitely - * fail, for other combinations we will let the Connect call fail - * or ask us for any missing secrets through the Agent. - */ - if ( nm_connection_get_setting_802_1x (connection) - && !is_ap_known_network (ap)) { - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) access point '%s' has 802.1x security but is not configured in IWD.", - nm_connection_get_id (connection)); - - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - goto out_fail; - } - - if ( !is_connection_known_network (connection) - && nm_setting_wireless_get_hidden (s_wireless)) { - gs_free char *ssid_str = NULL; - - /* Use Station.ConnectHiddenNetwork method instead of Network proxy. */ - ssid_str = _nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wireless)); - g_dbus_proxy_call (priv->dbus_station_proxy, - "ConnectHiddenNetwork", - g_variant_new ("(s)", ssid_str), - G_DBUS_CALL_FLAGS_NONE, G_MAXINT, - priv->cancellable, - network_connect_cb, - self); - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (!nm_wifi_ap_get_supplicant_path (ap)) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) network is provisioned but dbus supplicant path for AP unknown"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - goto out_fail; - } - - network_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (), - nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap)), - NM_IWD_NETWORK_INTERFACE); - if (!network_proxy) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) could not get Network interface proxy for %s", - nm_ref_string_get_str (nm_wifi_ap_get_supplicant_path (ap))); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - goto out_fail; - } - - if (!priv->cancellable) - priv->cancellable = g_cancellable_new (); - - /* Call Network.Connect. No timeout because IWD already handles - * timeouts. - */ - g_dbus_proxy_call (network_proxy, "Connect", - NULL, G_DBUS_CALL_FLAGS_NONE, G_MAXINT, - priv->cancellable, network_connect_cb, self); - - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (NM_IN_STRSET (mode, NM_SETTING_WIRELESS_MODE_AP, NM_SETTING_WIRELESS_MODE_ADHOC)) { - NMSettingWirelessSecurity *s_wireless_sec; - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - if ( s_wireless_sec - && !nm_setting_wireless_security_get_psk (s_wireless_sec)) { - /* PSK is missing from the settings, have to request it */ - - wifi_secrets_cancel (self); - - priv->wifi_secrets_id = nm_act_request_get_secrets (req, - TRUE, - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, - NM_MAKE_STRV (NM_SETTING_WIRELESS_SECURITY_PSK), - act_psk_cb, - self); - nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - } else - act_set_mode (self); - - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) iwd cannot handle mode %s", - mode); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMActRequest * req; + NMConnection * connection; + NMSettingWireless * s_wireless; + const char * mode; + + req = nm_device_get_act_request(device); + connection = nm_act_request_get_applied_connection(req); + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wireless, NM_ACT_STAGE_RETURN_FAILURE); + + mode = nm_setting_wireless_get_mode(s_wireless); + + if (NM_IN_STRSET(mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + gs_unref_object GDBusProxy *network_proxy = NULL; + NMWifiAP * ap = priv->current_ap; + + if (!ap) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + goto out_fail; + } + + /* 802.1x networks that are not IWD Known Networks will definitely + * fail, for other combinations we will let the Connect call fail + * or ask us for any missing secrets through the Agent. + */ + if (nm_connection_get_setting_802_1x(connection) && !is_ap_known_network(ap)) { + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) access point '%s' has 802.1x security but is not configured " + "in IWD.", + nm_connection_get_id(connection)); + + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + goto out_fail; + } + + if (!is_connection_known_network(connection) + && nm_setting_wireless_get_hidden(s_wireless)) { + gs_free char *ssid_str = NULL; + + /* Use Station.ConnectHiddenNetwork method instead of Network proxy. */ + ssid_str = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless)); + g_dbus_proxy_call(priv->dbus_station_proxy, + "ConnectHiddenNetwork", + g_variant_new("(s)", ssid_str), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + priv->cancellable, + network_connect_cb, + self); + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (!nm_wifi_ap_get_supplicant_path(ap)) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) network is provisioned but dbus supplicant path for AP " + "unknown"); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + goto out_fail; + } + + network_proxy = nm_iwd_manager_get_dbus_interface( + nm_iwd_manager_get(), + nm_ref_string_get_str(nm_wifi_ap_get_supplicant_path(ap)), + NM_IWD_NETWORK_INTERFACE); + if (!network_proxy) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) could not get Network interface proxy for %s", + nm_ref_string_get_str(nm_wifi_ap_get_supplicant_path(ap))); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + goto out_fail; + } + + if (!priv->cancellable) + priv->cancellable = g_cancellable_new(); + + /* Call Network.Connect. No timeout because IWD already handles + * timeouts. + */ + g_dbus_proxy_call(network_proxy, + "Connect", + NULL, + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + priv->cancellable, + network_connect_cb, + self); + + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (NM_IN_STRSET(mode, NM_SETTING_WIRELESS_MODE_AP, NM_SETTING_WIRELESS_MODE_ADHOC)) { + NMSettingWirelessSecurity *s_wireless_sec; + + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + if (s_wireless_sec && !nm_setting_wireless_security_get_psk(s_wireless_sec)) { + /* PSK is missing from the settings, have to request it */ + + wifi_secrets_cancel(self); + + priv->wifi_secrets_id = + nm_act_request_get_secrets(req, + TRUE, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, + NM_MAKE_STRV(NM_SETTING_WIRELESS_SECURITY_PSK), + act_psk_cb, + self); + nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); + } else + act_set_mode(self); + + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) iwd cannot handle mode %s", mode); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); out_fail: - cleanup_association_attempt (self, FALSE); - return NM_ACT_STAGE_RETURN_FAILURE; + cleanup_association_attempt(self, FALSE); + return NM_ACT_STAGE_RETURN_FAILURE; } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - return nm_device_get_configured_mtu_from_connection (device, - NM_TYPE_SETTING_WIRELESS, - out_source); + return nm_device_get_configured_mtu_from_connection(device, + NM_TYPE_SETTING_WIRELESS, + out_source); } static gboolean -periodic_scan_timeout_cb (gpointer user_data) +periodic_scan_timeout_cb(gpointer user_data) { - NMDeviceIwd *self = user_data; - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwd * self = user_data; + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - priv->periodic_scan_id = 0; + priv->periodic_scan_id = 0; - if (priv->scanning || priv->scan_requested) - return FALSE; + if (priv->scanning || priv->scan_requested) + return FALSE; - g_dbus_proxy_call (priv->dbus_station_proxy, "Scan", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, - priv->cancellable, scan_cb, self); - priv->scan_requested = TRUE; + g_dbus_proxy_call(priv->dbus_station_proxy, + "Scan", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + scan_cb, + self); + priv->scan_requested = TRUE; - return FALSE; + return FALSE; } static void -schedule_periodic_scan (NMDeviceIwd *self, gboolean initial_scan) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - GVariant *value; - gboolean disconnected; - guint interval; - - if (!priv->can_scan || priv->scan_requested) - return; - - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); - disconnected = nm_streq0 (get_variant_state (value), "disconnected"); - g_variant_unref (value); - - /* Start scan immediately after a disconnect, mode change or - * device UP, otherwise wait a period dependent on the current - * state. - * - * (initial_scan && disconnected) override priv->scanning below - * because of an IWD quirk where a device will often be in the - * autoconnect state and scanning at the time of our initial_scan, - * but our logic will the send it a Disconnect() causeing IWD to - * exit autoconnect and interrupt the ongoing scan, meaning that - * we still want a new scan ASAP. - */ - if (initial_scan && disconnected) - interval = 0; - else if (!priv->periodic_scan_id && !priv->scanning) - interval = disconnected ? 10 : 20; - else - return; - - nm_clear_g_source (&priv->periodic_scan_id); - priv->periodic_scan_id = g_timeout_add_seconds (interval, - periodic_scan_timeout_cb, - self); +schedule_periodic_scan(NMDeviceIwd *self, gboolean initial_scan) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + GVariant * value; + gboolean disconnected; + guint interval; + + if (!priv->can_scan || priv->scan_requested) + return; + + value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State"); + disconnected = nm_streq0(get_variant_state(value), "disconnected"); + g_variant_unref(value); + + /* Start scan immediately after a disconnect, mode change or + * device UP, otherwise wait a period dependent on the current + * state. + * + * (initial_scan && disconnected) override priv->scanning below + * because of an IWD quirk where a device will often be in the + * autoconnect state and scanning at the time of our initial_scan, + * but our logic will the send it a Disconnect() causing IWD to + * exit autoconnect and interrupt the ongoing scan, meaning that + * we still want a new scan ASAP. + */ + if (initial_scan && disconnected) + interval = 0; + else if (!priv->periodic_scan_id && !priv->scanning) + interval = disconnected ? 10 : 20; + else + return; + + nm_clear_g_source(&priv->periodic_scan_id); + priv->periodic_scan_id = g_timeout_add_seconds(interval, periodic_scan_timeout_cb, self); } static void -set_can_scan (NMDeviceIwd *self, gboolean can_scan) +set_can_scan(NMDeviceIwd *self, gboolean can_scan) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - if (priv->can_scan == can_scan) - return; + if (priv->can_scan == can_scan) + return; - priv->can_scan = can_scan; + priv->can_scan = can_scan; - schedule_periodic_scan (self, TRUE); + schedule_periodic_scan(self, TRUE); } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - - switch (new_state) { - case NM_DEVICE_STATE_UNMANAGED: - break; - case NM_DEVICE_STATE_UNAVAILABLE: - /* - * If the device is enabled and the IWD manager is ready, - * transition to DISCONNECTED because the device is now - * ready to use. - */ - if (priv->enabled && priv->dbus_station_proxy) { - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - } - break; - case NM_DEVICE_STATE_NEED_AUTH: - break; - case NM_DEVICE_STATE_IP_CHECK: - break; - case NM_DEVICE_STATE_ACTIVATED: - break; - case NM_DEVICE_STATE_FAILED: - break; - case NM_DEVICE_STATE_DISCONNECTED: - break; - default: - break; - } +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + break; + case NM_DEVICE_STATE_UNAVAILABLE: + /* + * If the device is enabled and the IWD manager is ready, + * transition to DISCONNECTED because the device is now + * ready to use. + */ + if (priv->enabled && priv->dbus_station_proxy) { + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + } + break; + case NM_DEVICE_STATE_NEED_AUTH: + break; + case NM_DEVICE_STATE_IP_CHECK: + break; + case NM_DEVICE_STATE_ACTIVATED: + break; + case NM_DEVICE_STATE_FAILED: + break; + case NM_DEVICE_STATE_DISCONNECTED: + break; + default: + break; + } } static gboolean -get_enabled (NMDevice *device) +get_enabled(NMDevice *device) { - return NM_DEVICE_IWD_GET_PRIVATE (device)->enabled; + return NM_DEVICE_IWD_GET_PRIVATE(device)->enabled; } static void -set_enabled (NMDevice *device, gboolean enabled) +set_enabled(NMDevice *device, gboolean enabled) { - NMDeviceIwd *self = NM_DEVICE_IWD (device); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDeviceState state; + NMDeviceIwd * self = NM_DEVICE_IWD(device); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDeviceState state; - enabled = !!enabled; + enabled = !!enabled; - if (priv->enabled == enabled) - return; + if (priv->enabled == enabled) + return; - priv->enabled = enabled; + priv->enabled = enabled; - _LOGD (LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); + _LOGD(LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); - state = nm_device_get_state (device); - if (state < NM_DEVICE_STATE_UNAVAILABLE) { - _LOGD (LOGD_WIFI, "(%s): device blocked by UNMANAGED state", - enabled ? "enable" : "disable"); - return; - } + state = nm_device_get_state(device); + if (state < NM_DEVICE_STATE_UNAVAILABLE) { + _LOGD(LOGD_WIFI, "(%s): device blocked by UNMANAGED state", enabled ? "enable" : "disable"); + return; + } - if (priv->dbus_obj) - set_powered (self, enabled); + if (priv->dbus_obj) + set_powered(self, enabled); - if (enabled) { - if (state != NM_DEVICE_STATE_UNAVAILABLE) - _LOGW (LOGD_CORE, "not in expected unavailable state!"); + if (enabled) { + if (state != NM_DEVICE_STATE_UNAVAILABLE) + _LOGW(LOGD_CORE, "not in expected unavailable state!"); - if (priv->dbus_station_proxy) { - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - } - } else { - nm_device_state_changed (device, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_NONE); - } + if (priv->dbus_station_proxy) { + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + } + } else { + nm_device_state_changed(device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NONE); + } } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) -{ - NMDeviceClass *device_class; - - /* Only handle wireless setting here, delegate other settings to parent class */ - if (nm_streq (setting_name, NM_SETTING_WIRELESS_SETTING_NAME)) { - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_WIRELESS_SETTING_NAME, - error, - NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ - NM_SETTING_WIRELESS_MTU); /* reapplied with IP config */ - } - - device_class = NM_DEVICE_CLASS (nm_device_iwd_parent_class); - return device_class->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) +{ + NMDeviceClass *device_class; + + /* Only handle wireless setting here, delegate other settings to parent class */ + if (nm_streq(setting_name, NM_SETTING_WIRELESS_SETTING_NAME)) { + return nm_device_hash_check_invalid_keys( + diffs, + NM_SETTING_WIRELESS_SETTING_NAME, + error, + NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ + NM_SETTING_WIRELESS_MTU); /* reapplied with IP config */ + } + + device_class = NM_DEVICE_CLASS(nm_device_iwd_parent_class); + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDeviceIwd *self = NM_DEVICE_IWD (object); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - const char **list; - - switch (prop_id) { - case PROP_MODE: - if (!priv->current_ap) - g_value_set_uint (value, NM_802_11_MODE_UNKNOWN); - else if (nm_wifi_ap_is_hotspot (priv->current_ap)) - g_value_set_uint (value, NM_802_11_MODE_AP); - else - g_value_set_uint (value, nm_wifi_ap_get_mode (priv->current_ap)); - - break; - case PROP_BITRATE: - g_value_set_uint (value, 65000); - break; - case PROP_CAPABILITIES: - g_value_set_uint (value, priv->capabilities); - break; - case PROP_ACCESS_POINTS: - list = nm_wifi_aps_get_paths (&priv->aps_lst_head, TRUE); - g_value_take_boxed (value, nm_utils_strv_make_deep_copied (list)); - break; - case PROP_ACTIVE_ACCESS_POINT: - nm_dbus_utils_g_value_set_object_path (value, priv->current_ap); - break; - case PROP_SCANNING: - g_value_set_boolean (value, priv->scanning); - break; - case PROP_LAST_SCAN: - g_value_set_int64 (value, - priv->last_scan > 0 - ? nm_utils_monotonic_timestamp_as_boottime (priv->last_scan, NM_UTILS_NSEC_PER_MSEC) - : (gint64) -1); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceIwd * self = NM_DEVICE_IWD(object); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + const char ** list; + + switch (prop_id) { + case PROP_MODE: + if (!priv->current_ap) + g_value_set_uint(value, NM_802_11_MODE_UNKNOWN); + else if (nm_wifi_ap_is_hotspot(priv->current_ap)) + g_value_set_uint(value, NM_802_11_MODE_AP); + else + g_value_set_uint(value, nm_wifi_ap_get_mode(priv->current_ap)); + + break; + case PROP_BITRATE: + g_value_set_uint(value, 65000); + break; + case PROP_CAPABILITIES: + g_value_set_uint(value, priv->capabilities); + break; + case PROP_ACCESS_POINTS: + list = nm_wifi_aps_get_paths(&priv->aps_lst_head, TRUE); + g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + break; + case PROP_ACTIVE_ACCESS_POINT: + nm_dbus_utils_g_value_set_object_path(value, priv->current_ap); + break; + case PROP_SCANNING: + g_value_set_boolean(value, priv->scanning); + break; + case PROP_LAST_SCAN: + g_value_set_int64( + value, + priv->last_scan > 0 + ? nm_utils_monotonic_timestamp_as_boottime(priv->last_scan, NM_UTILS_NSEC_PER_MSEC) + : (gint64) -1); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -state_changed (NMDeviceIwd *self, const char *new_state) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMDeviceState dev_state = nm_device_get_state (device); - gboolean iwd_connection = FALSE; - gboolean can_connect = priv->can_connect; - - _LOGI (LOGD_DEVICE | LOGD_WIFI, "new IWD device state is %s", new_state); - - if ( dev_state >= NM_DEVICE_STATE_CONFIG - && dev_state <= NM_DEVICE_STATE_ACTIVATED) - iwd_connection = TRUE; - - /* Don't allow scanning while connecting, disconnecting or roaming */ - set_can_scan (self, NM_IN_STRSET (new_state, "connected", "disconnected")); - - priv->can_connect = FALSE; - - if (NM_IN_STRSET (new_state, "connecting", "connected", "roaming")) { - /* If we were connecting, do nothing, the confirmation of - * a connection success is handled in the Device.Connect - * method return callback. Otherwise IWD must have connected - * without Network Manager's will so for simplicity force a - * disconnect. - */ - if (iwd_connection) - return; - - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Unsolicited connection success, asking IWD to disconnect"); - send_disconnect (self); - } else if (NM_IN_STRSET (new_state, "disconnecting", "disconnected")) { - /* Call Disconnect on the IWD device object to make sure it - * disables its own autoconnect. - */ - send_disconnect (self); - - /* - * If IWD is still handling the Connect call, let our Connect - * callback for the dbus method handle the failure. The main - * reason we can't handle the failure here is because the method - * callback will have more information on the specific failure - * reason. - */ - if (NM_IN_SET (dev_state, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH)) - return; - - if (iwd_connection) - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - } else if (!nm_streq (new_state, "unknown")) { - _LOGE (LOGD_WIFI, "State %s unknown", new_state); - return; - } - - /* Don't allow new connection until iwd exits disconnecting and no - * Connect callback is pending. - */ - if (NM_IN_STRSET (new_state, "disconnected")) { - priv->can_connect = TRUE; - if (!can_connect) - nm_device_emit_recheck_auto_activate (device); - } +state_changed(NMDeviceIwd *self, const char *new_state) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMDeviceState dev_state = nm_device_get_state(device); + gboolean iwd_connection = FALSE; + gboolean can_connect = priv->can_connect; + + _LOGI(LOGD_DEVICE | LOGD_WIFI, "new IWD device state is %s", new_state); + + if (dev_state >= NM_DEVICE_STATE_CONFIG && dev_state <= NM_DEVICE_STATE_ACTIVATED) + iwd_connection = TRUE; + + /* Don't allow scanning while connecting, disconnecting or roaming */ + set_can_scan(self, NM_IN_STRSET(new_state, "connected", "disconnected")); + + priv->can_connect = FALSE; + + if (NM_IN_STRSET(new_state, "connecting", "connected", "roaming")) { + /* If we were connecting, do nothing, the confirmation of + * a connection success is handled in the Device.Connect + * method return callback. Otherwise, IWD must have connected + * without Network Manager's will so for simplicity force a + * disconnect. + */ + if (iwd_connection) + return; + + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Unsolicited connection success, asking IWD to disconnect"); + send_disconnect(self); + } else if (NM_IN_STRSET(new_state, "disconnecting", "disconnected")) { + /* Call Disconnect on the IWD device object to make sure it + * disables its own autoconnect. + */ + send_disconnect(self); + + /* + * If IWD is still handling the Connect call, let our Connect + * callback for the dbus method handle the failure. The main + * reason we can't handle the failure here is because the method + * callback will have more information on the specific failure + * reason. + */ + if (NM_IN_SET(dev_state, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH)) + return; + + if (iwd_connection) + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + } else if (!nm_streq(new_state, "unknown")) { + _LOGE(LOGD_WIFI, "State %s unknown", new_state); + return; + } + + /* Don't allow new connection until iwd exits disconnecting and no + * Connect callback is pending. + */ + if (NM_IN_STRSET(new_state, "disconnected")) { + priv->can_connect = TRUE; + if (!can_connect) + nm_device_emit_recheck_auto_activate(device); + } } static void -scanning_changed (NMDeviceIwd *self, gboolean new_scanning) +scanning_changed(NMDeviceIwd *self, gboolean new_scanning) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - if (new_scanning == priv->scanning) - return; + if (new_scanning == priv->scanning) + return; - priv->scanning = new_scanning; + priv->scanning = new_scanning; - _notify (self, PROP_SCANNING); + _notify(self, PROP_SCANNING); - if (!priv->scanning) { - update_aps (self); + if (!priv->scanning) { + update_aps(self); - if (!priv->scan_requested) - schedule_periodic_scan (self, FALSE); - } + if (!priv->scan_requested) + schedule_periodic_scan(self, FALSE); + } } static void -station_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, - GStrv invalidate_properties, gpointer user_data) +station_properties_changed(GDBusProxy *proxy, + GVariant * changed_properties, + GStrv invalidate_properties, + gpointer user_data) { - NMDeviceIwd *self = user_data; - const char *new_str; - gboolean new_bool; + NMDeviceIwd *self = user_data; + const char * new_str; + gboolean new_bool; - if (g_variant_lookup (changed_properties, "State", "&s", &new_str)) - state_changed (self, new_str); + if (g_variant_lookup(changed_properties, "State", "&s", &new_str)) + state_changed(self, new_str); - if (g_variant_lookup (changed_properties, "Scanning", "b", &new_bool)) - scanning_changed (self, new_bool); + if (g_variant_lookup(changed_properties, "Scanning", "b", &new_bool)) + scanning_changed(self, new_bool); } static void -ap_adhoc_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, - GStrv invalidate_properties, gpointer user_data) +ap_adhoc_properties_changed(GDBusProxy *proxy, + GVariant * changed_properties, + GStrv invalidate_properties, + gpointer user_data) { - NMDeviceIwd *self = user_data; - gboolean new_bool; + NMDeviceIwd *self = user_data; + gboolean new_bool; - if (g_variant_lookup (changed_properties, "Started", "b", &new_bool)) - _LOGI (LOGD_DEVICE | LOGD_WIFI, "IWD AP/AdHoc state is now %s", new_bool ? "Started" : "Stopped"); + if (g_variant_lookup(changed_properties, "Started", "b", &new_bool)) + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "IWD AP/AdHoc state is now %s", + new_bool ? "Started" : "Stopped"); } static void -powered_changed (NMDeviceIwd *self, gboolean new_powered) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - GDBusInterface *interface; - GVariant *value; - - nm_device_queue_recheck_available (NM_DEVICE (self), - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - - interface = new_powered ? g_dbus_object_get_interface (priv->dbus_obj, NM_IWD_AP_INTERFACE) : NULL; - - if (priv->dbus_ap_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_ap_proxy, - ap_adhoc_properties_changed, self); - g_clear_object (&priv->dbus_ap_proxy); - } - - if (interface) { - priv->dbus_ap_proxy = G_DBUS_PROXY (interface); - g_signal_connect (priv->dbus_ap_proxy, "g-properties-changed", - G_CALLBACK (ap_adhoc_properties_changed), self); - - if (priv->act_mode_switch) - act_check_interface (self); - else - reset_mode (self, NULL, NULL, NULL); - } - - interface = new_powered ? g_dbus_object_get_interface (priv->dbus_obj, NM_IWD_ADHOC_INTERFACE) : NULL; - - if (priv->dbus_adhoc_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_adhoc_proxy, - ap_adhoc_properties_changed, self); - g_clear_object (&priv->dbus_adhoc_proxy); - } - - if (interface) { - priv->dbus_adhoc_proxy = G_DBUS_PROXY (interface); - g_signal_connect (priv->dbus_adhoc_proxy, "g-properties-changed", - G_CALLBACK (ap_adhoc_properties_changed), self); - - if (priv->act_mode_switch) - act_check_interface (self); - else - reset_mode (self, NULL, NULL, NULL); - } - - /* We expect one of the three interfaces to always be present when - * device is Powered so if AP and AdHoc are not present we should - * be in station mode. - */ - if (new_powered && !priv->dbus_ap_proxy && !priv->dbus_adhoc_proxy) { - interface = g_dbus_object_get_interface (priv->dbus_obj, NM_IWD_STATION_INTERFACE); - if (!interface) { - /* No Station interface on the device object. Check if the - * "State" property is present on the Device interface, that - * would mean we're dealing with an IWD version from before the - * Device/Station split (0.7 or earlier) and we can easily - * handle that by making priv->dbus_device_proxy and - * priv->dbus_station_proxy both point at the Device interface. - */ - value = g_dbus_proxy_get_cached_property (priv->dbus_device_proxy, "State"); - if (value) { - g_variant_unref (value); - interface = g_object_ref (G_DBUS_INTERFACE (priv->dbus_device_proxy)); - } else { - _LOGE (LOGD_WIFI, "Interface %s not found on obj %s", - NM_IWD_STATION_INTERFACE, - g_dbus_object_get_object_path (priv->dbus_obj)); - interface = NULL; - } - - } - } else - interface = NULL; - - if (priv->dbus_station_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_station_proxy, - station_properties_changed, self); - g_clear_object (&priv->dbus_station_proxy); - } - - if (interface) { - priv->dbus_station_proxy = G_DBUS_PROXY (interface); - g_signal_connect (priv->dbus_station_proxy, "g-properties-changed", - G_CALLBACK (station_properties_changed), self); - - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "Scanning"); - priv->scanning = get_variant_boolean (value, "Scanning"); - g_variant_unref (value); - - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); - state_changed (self, get_variant_state (value)); - g_variant_unref (value); - - update_aps (self); - } else { - set_can_scan (self, FALSE); - nm_clear_g_source (&priv->periodic_scan_id); - priv->scanning = FALSE; - priv->scan_requested = FALSE; - priv->can_connect = FALSE; - cleanup_association_attempt (self, FALSE); - remove_all_aps (self); - } +powered_changed(NMDeviceIwd *self, gboolean new_powered) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + GDBusInterface * interface; + GVariant * value; + + nm_device_queue_recheck_available(NM_DEVICE(self), + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + + interface = + new_powered ? g_dbus_object_get_interface(priv->dbus_obj, NM_IWD_AP_INTERFACE) : NULL; + + if (priv->dbus_ap_proxy) { + g_signal_handlers_disconnect_by_func(priv->dbus_ap_proxy, + ap_adhoc_properties_changed, + self); + g_clear_object(&priv->dbus_ap_proxy); + } + + if (interface) { + priv->dbus_ap_proxy = G_DBUS_PROXY(interface); + g_signal_connect(priv->dbus_ap_proxy, + "g-properties-changed", + G_CALLBACK(ap_adhoc_properties_changed), + self); + + if (priv->act_mode_switch) + act_check_interface(self); + else + reset_mode(self, NULL, NULL, NULL); + } + + interface = + new_powered ? g_dbus_object_get_interface(priv->dbus_obj, NM_IWD_ADHOC_INTERFACE) : NULL; + + if (priv->dbus_adhoc_proxy) { + g_signal_handlers_disconnect_by_func(priv->dbus_adhoc_proxy, + ap_adhoc_properties_changed, + self); + g_clear_object(&priv->dbus_adhoc_proxy); + } + + if (interface) { + priv->dbus_adhoc_proxy = G_DBUS_PROXY(interface); + g_signal_connect(priv->dbus_adhoc_proxy, + "g-properties-changed", + G_CALLBACK(ap_adhoc_properties_changed), + self); + + if (priv->act_mode_switch) + act_check_interface(self); + else + reset_mode(self, NULL, NULL, NULL); + } + + /* We expect one of the three interfaces to always be present when + * device is Powered so if AP and AdHoc are not present we should + * be in station mode. + */ + if (new_powered && !priv->dbus_ap_proxy && !priv->dbus_adhoc_proxy) { + interface = g_dbus_object_get_interface(priv->dbus_obj, NM_IWD_STATION_INTERFACE); + if (!interface) { + /* No Station interface on the device object. Check if the + * "State" property is present on the Device interface, that + * would mean we're dealing with an IWD version from before the + * Device/Station split (0.7 or earlier) and we can easily + * handle that by making priv->dbus_device_proxy and + * priv->dbus_station_proxy both point at the Device interface. + */ + value = g_dbus_proxy_get_cached_property(priv->dbus_device_proxy, "State"); + if (value) { + g_variant_unref(value); + interface = g_object_ref(G_DBUS_INTERFACE(priv->dbus_device_proxy)); + } else { + _LOGE(LOGD_WIFI, + "Interface %s not found on obj %s", + NM_IWD_STATION_INTERFACE, + g_dbus_object_get_object_path(priv->dbus_obj)); + interface = NULL; + } + } + } else + interface = NULL; + + if (priv->dbus_station_proxy) { + g_signal_handlers_disconnect_by_func(priv->dbus_station_proxy, + station_properties_changed, + self); + g_clear_object(&priv->dbus_station_proxy); + } + + if (interface) { + priv->dbus_station_proxy = G_DBUS_PROXY(interface); + g_signal_connect(priv->dbus_station_proxy, + "g-properties-changed", + G_CALLBACK(station_properties_changed), + self); + + value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "Scanning"); + priv->scanning = get_variant_boolean(value, "Scanning"); + g_variant_unref(value); + + value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State"); + state_changed(self, get_variant_state(value)); + g_variant_unref(value); + + update_aps(self); + } else { + set_can_scan(self, FALSE); + nm_clear_g_source(&priv->periodic_scan_id); + priv->scanning = FALSE; + priv->scan_requested = FALSE; + priv->can_connect = FALSE; + cleanup_association_attempt(self, FALSE); + remove_all_aps(self); + } } static void -device_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, - GStrv invalidate_properties, gpointer user_data) +device_properties_changed(GDBusProxy *proxy, + GVariant * changed_properties, + GStrv invalidate_properties, + gpointer user_data) { - NMDeviceIwd *self = user_data; - gboolean new_bool; + NMDeviceIwd *self = user_data; + gboolean new_bool; - if (g_variant_lookup (changed_properties, "Powered", "b", &new_bool)) - powered_changed (self, new_bool); + if (g_variant_lookup(changed_properties, "Powered", "b", &new_bool)) + powered_changed(self, new_bool); } void -nm_device_iwd_set_dbus_object (NMDeviceIwd *self, GDBusObject *object) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - GDBusInterface *interface; - gs_unref_variant GVariant *value = NULL; - gs_unref_object GDBusProxy *adapter_proxy = NULL; - GVariantIter *iter; - const char *mode; - gboolean powered; - NMDeviceWifiCapabilities capabilities; - - if (!nm_g_object_ref_set (&priv->dbus_obj, object)) - return; - - if (priv->dbus_device_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_device_proxy, - device_properties_changed, self); - g_clear_object (&priv->dbus_device_proxy); - - powered_changed (self, FALSE); - - priv->act_mode_switch = FALSE; - } - - if (!object) - return; - - interface = g_dbus_object_get_interface (object, NM_IWD_DEVICE_INTERFACE); - if (!interface) { - _LOGE (LOGD_WIFI, "Interface %s not found on obj %s", - NM_IWD_DEVICE_INTERFACE, - g_dbus_object_get_object_path (object)); - g_clear_object (&priv->dbus_obj); - return; - } - - priv->dbus_device_proxy = G_DBUS_PROXY (interface); - - g_signal_connect (priv->dbus_device_proxy, "g-properties-changed", - G_CALLBACK (device_properties_changed), self); - - /* Parse list of interface modes supported by adapter (wiphy) */ - - value = g_dbus_proxy_get_cached_property (priv->dbus_device_proxy, "Adapter"); - if (!value || !g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Adapter property not cached or not an object path"); - goto error; - } - - adapter_proxy = nm_iwd_manager_get_dbus_interface (nm_iwd_manager_get (), - g_variant_get_string (value, NULL), - NM_IWD_WIPHY_INTERFACE); - if (!adapter_proxy) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Can't get DBus proxy for IWD Adapter for IWD Device"); - goto error; - } - - g_variant_unref (value); - value = g_dbus_proxy_get_cached_property (adapter_proxy, "SupportedModes"); - if (!value || !g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "SupportedModes property not cached or not a string array"); - goto error; - } - - capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; - - g_variant_get (value, "as", &iter); - while (g_variant_iter_next (iter, "&s", &mode)) { - if (nm_streq (mode, "ap")) - capabilities |= NM_WIFI_DEVICE_CAP_AP; - else if (nm_streq (mode, "ad-hoc")) - capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; - } - g_variant_iter_free (iter); - - if (priv->capabilities != capabilities) { - priv->capabilities = capabilities; - _notify (self, PROP_CAPABILITIES); - } - - g_variant_unref (value); - value = g_dbus_proxy_get_cached_property (priv->dbus_device_proxy, "Powered"); - powered = get_variant_boolean (value, "Powered"); - - if (powered != priv->enabled) - set_powered (self, priv->enabled); - else if (powered) - powered_changed (self, TRUE); - - return; +nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) +{ + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); + GDBusInterface * interface; + gs_unref_variant GVariant *value = NULL; + gs_unref_object GDBusProxy *adapter_proxy = NULL; + GVariantIter * iter; + const char * mode; + gboolean powered; + NMDeviceWifiCapabilities capabilities; + + if (!nm_g_object_ref_set(&priv->dbus_obj, object)) + return; + + if (priv->dbus_device_proxy) { + g_signal_handlers_disconnect_by_func(priv->dbus_device_proxy, + device_properties_changed, + self); + g_clear_object(&priv->dbus_device_proxy); + + powered_changed(self, FALSE); + + priv->act_mode_switch = FALSE; + } + + if (!object) + return; + + interface = g_dbus_object_get_interface(object, NM_IWD_DEVICE_INTERFACE); + if (!interface) { + _LOGE(LOGD_WIFI, + "Interface %s not found on obj %s", + NM_IWD_DEVICE_INTERFACE, + g_dbus_object_get_object_path(object)); + g_clear_object(&priv->dbus_obj); + return; + } + + priv->dbus_device_proxy = G_DBUS_PROXY(interface); + + g_signal_connect(priv->dbus_device_proxy, + "g-properties-changed", + G_CALLBACK(device_properties_changed), + self); + + /* Parse list of interface modes supported by adapter (wiphy) */ + + value = g_dbus_proxy_get_cached_property(priv->dbus_device_proxy, "Adapter"); + if (!value || !g_variant_is_of_type(value, G_VARIANT_TYPE_OBJECT_PATH)) { + nm_log_warn(LOGD_DEVICE | LOGD_WIFI, "Adapter property not cached or not an object path"); + goto error; + } + + adapter_proxy = nm_iwd_manager_get_dbus_interface(nm_iwd_manager_get(), + g_variant_get_string(value, NULL), + NM_IWD_WIPHY_INTERFACE); + if (!adapter_proxy) { + nm_log_warn(LOGD_DEVICE | LOGD_WIFI, "Can't get DBus proxy for IWD Adapter for IWD Device"); + goto error; + } + + g_variant_unref(value); + value = g_dbus_proxy_get_cached_property(adapter_proxy, "SupportedModes"); + if (!value || !g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY)) { + nm_log_warn(LOGD_DEVICE | LOGD_WIFI, + "SupportedModes property not cached or not a string array"); + goto error; + } + + capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; + + g_variant_get(value, "as", &iter); + while (g_variant_iter_next(iter, "&s", &mode)) { + if (nm_streq(mode, "ap")) + capabilities |= NM_WIFI_DEVICE_CAP_AP; + else if (nm_streq(mode, "ad-hoc")) + capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; + } + g_variant_iter_free(iter); + + if (priv->capabilities != capabilities) { + priv->capabilities = capabilities; + _notify(self, PROP_CAPABILITIES); + } + + g_variant_unref(value); + value = g_dbus_proxy_get_cached_property(priv->dbus_device_proxy, "Powered"); + powered = get_variant_boolean(value, "Powered"); + + if (powered != priv->enabled) + set_powered(self, priv->enabled); + else if (powered) + powered_changed(self, TRUE); + + return; error: - g_signal_handlers_disconnect_by_func (priv->dbus_device_proxy, - device_properties_changed, self); - g_clear_object (&priv->dbus_device_proxy); + g_signal_handlers_disconnect_by_func(priv->dbus_device_proxy, device_properties_changed, self); + g_clear_object(&priv->dbus_device_proxy); } gboolean -nm_device_iwd_agent_query (NMDeviceIwd *self, - GDBusMethodInvocation *invocation) -{ - NMActRequest *req; - const char *setting_name; - const char *setting_key; - gboolean replied; - NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - - req = nm_device_get_act_request (NM_DEVICE (self)); - if (!req) - return FALSE; - - if (!try_reply_agent_request (self, nm_act_request_get_applied_connection (req), - invocation, &setting_name, &setting_key, - &replied)) - return FALSE; - - if (replied) - return TRUE; - - /* Normally require new secrets every time IWD asks for them. - * IWD only queries us if it has not saved the secrets (e.g. by policy) - * or a previous attempt has failed with current secrets so it wants - * a fresh set. However if this is a new connection it may include - * all of the needed settings already so allow using these, too. - * Connection timestamp is set after activation or after first - * activation failure (to 0). - */ - if (nm_settings_connection_get_timestamp (nm_act_request_get_settings_connection (req), - NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, - NM_DEVICE_STATE_REASON_NO_SECRETS); - wifi_secrets_get_one (self, setting_name, get_secret_flags, - setting_key, invocation); - - return TRUE; +nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) +{ + NMActRequest * req; + const char * setting_name; + const char * setting_key; + gboolean replied; + NMSecretAgentGetSecretsFlags get_secret_flags = + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + + req = nm_device_get_act_request(NM_DEVICE(self)); + if (!req) + return FALSE; + + if (!try_reply_agent_request(self, + nm_act_request_get_applied_connection(req), + invocation, + &setting_name, + &setting_key, + &replied)) + return FALSE; + + if (replied) + return TRUE; + + /* Normally require new secrets every time IWD asks for them. + * IWD only queries us if it has not saved the secrets (e.g. by policy) + * or a previous attempt has failed with current secrets so it wants + * a fresh set. However if this is a new connection it may include + * all of the needed settings already so allow using these, too. + * Connection timestamp is set after activation or after first + * activation failure (to 0). + */ + if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NO_SECRETS); + wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); + + return TRUE; } /*****************************************************************************/ static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - nm_assert (NM_IS_DEVICE_IWD (device)); + nm_assert(NM_IS_DEVICE_IWD(device)); - return "wifi"; + return "wifi"; } /*****************************************************************************/ static void -nm_device_iwd_init (NMDeviceIwd *self) +nm_device_iwd_init(NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - c_list_init (&priv->aps_lst_head); + c_list_init(&priv->aps_lst_head); - /* Make sure the manager is running */ - (void) nm_iwd_manager_get (); + /* Make sure the manager is running */ + (void) nm_iwd_manager_get(); } NMDevice * -nm_device_iwd_new (const char *iface) -{ - return g_object_new (NM_TYPE_DEVICE_IWD, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "802.11 Wi-Fi", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI, - NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN, - NULL); +nm_device_iwd_new(const char *iface) +{ + return g_object_new(NM_TYPE_DEVICE_IWD, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "802.11 Wi-Fi", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_WIFI, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_WIFI, + NM_DEVICE_RFKILL_TYPE, + RFKILL_TYPE_WLAN, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceIwd *self = NM_DEVICE_IWD (object); - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); + NMDeviceIwd * self = NM_DEVICE_IWD(object); + NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); - nm_clear_g_cancellable (&priv->cancellable); + nm_clear_g_cancellable(&priv->cancellable); - nm_clear_g_source (&priv->periodic_scan_id); + nm_clear_g_source(&priv->periodic_scan_id); - cleanup_association_attempt (self, TRUE); + cleanup_association_attempt(self, TRUE); - g_clear_object (&priv->dbus_device_proxy); - g_clear_object (&priv->dbus_station_proxy); - g_clear_object (&priv->dbus_ap_proxy); - g_clear_object (&priv->dbus_adhoc_proxy); - g_clear_object (&priv->dbus_obj); + g_clear_object(&priv->dbus_device_proxy); + g_clear_object(&priv->dbus_station_proxy); + g_clear_object(&priv->dbus_ap_proxy); + g_clear_object(&priv->dbus_adhoc_proxy); + g_clear_object(&priv->dbus_obj); - remove_all_aps (self); + remove_all_aps(self); - G_OBJECT_CLASS (nm_device_iwd_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_iwd_parent_class)->dispose(object); - nm_assert (c_list_is_empty (&priv->aps_lst_head)); + nm_assert(c_list_is_empty(&priv->aps_lst_head)); } static void -nm_device_iwd_class_init (NMDeviceIwdClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - object_class->dispose = dispose; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); - - device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIFI); - - device_class->can_auto_connect = can_auto_connect; - device_class->is_available = is_available; - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->get_enabled = get_enabled; - device_class->set_enabled = set_enabled; - device_class->get_type_description = get_type_description; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->get_configured_mtu = get_configured_mtu; - device_class->deactivate = deactivate; - device_class->deactivate_async = deactivate_async; - device_class->can_reapply_change = can_reapply_change; - - device_class->state_changed = device_state_changed; - - obj_properties[PROP_MODE] = - g_param_spec_uint (NM_DEVICE_IWD_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BITRATE] = - g_param_spec_uint (NM_DEVICE_IWD_BITRATE, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ACCESS_POINTS] = - g_param_spec_boxed (NM_DEVICE_IWD_ACCESS_POINTS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ACTIVE_ACCESS_POINT] = - g_param_spec_string (NM_DEVICE_IWD_ACTIVE_ACCESS_POINT, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_IWD_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SCANNING] = - g_param_spec_boolean (NM_DEVICE_IWD_SCANNING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LAST_SCAN] = - g_param_spec_int64 (NM_DEVICE_IWD_LAST_SCAN, "", "", - -1, G_MAXINT64, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +nm_device_iwd_class_init(NMDeviceIwdClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->dispose = dispose; + + dbus_object_class->interface_infos = + NM_DBUS_INTERFACE_INFOS(&nm_interface_info_device_wireless); + + device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_WIFI); + + device_class->can_auto_connect = can_auto_connect; + device_class->is_available = is_available; + device_class->get_autoconnect_allowed = get_autoconnect_allowed; + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + device_class->get_enabled = get_enabled; + device_class->set_enabled = set_enabled; + device_class->get_type_description = get_type_description; + + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->get_configured_mtu = get_configured_mtu; + device_class->deactivate = deactivate; + device_class->deactivate_async = deactivate_async; + device_class->can_reapply_change = can_reapply_change; + + device_class->state_changed = device_state_changed; + + obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_IWD_MODE, + "", + "", + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_AP, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_IWD_BITRATE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACCESS_POINTS] = + g_param_spec_boxed(NM_DEVICE_IWD_ACCESS_POINTS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACTIVE_ACCESS_POINT] = + g_param_spec_string(NM_DEVICE_IWD_ACTIVE_ACCESS_POINT, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_IWD_CAPABILITIES, + "", + "", + 0, + G_MAXUINT32, + NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_IWD_SCANNING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LAST_SCAN] = g_param_spec_int64(NM_DEVICE_IWD_LAST_SCAN, + "", + "", + -1, + G_MAXINT64, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h index 1f15d3f4..e364beaf 100644 --- a/src/devices/wifi/nm-device-iwd.h +++ b/src/devices/wifi/nm-device-iwd.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Intel Corporation */ @@ -10,12 +10,14 @@ #include "nm-wifi-ap.h" #include "nm-device-wifi.h" -#define NM_TYPE_DEVICE_IWD (nm_device_iwd_get_type ()) -#define NM_DEVICE_IWD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_IWD, NMDeviceIwd)) -#define NM_DEVICE_IWD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_IWD, NMDeviceIwdClass)) -#define NM_IS_DEVICE_IWD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_IWD)) -#define NM_IS_DEVICE_IWD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_IWD)) -#define NM_DEVICE_IWD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_IWD, NMDeviceIwdClass)) +#define NM_TYPE_DEVICE_IWD (nm_device_iwd_get_type()) +#define NM_DEVICE_IWD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IWD, NMDeviceIwd)) +#define NM_DEVICE_IWD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IWD, NMDeviceIwdClass)) +#define NM_IS_DEVICE_IWD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IWD)) +#define NM_IS_DEVICE_IWD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IWD)) +#define NM_DEVICE_IWD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IWD, NMDeviceIwdClass)) #define NM_DEVICE_IWD_MODE NM_DEVICE_WIFI_MODE #define NM_DEVICE_IWD_BITRATE NM_DEVICE_WIFI_BITRATE @@ -25,22 +27,21 @@ #define NM_DEVICE_IWD_SCANNING NM_DEVICE_WIFI_SCANNING #define NM_DEVICE_IWD_LAST_SCAN NM_DEVICE_WIFI_LAST_SCAN -typedef struct _NMDeviceIwd NMDeviceIwd; +typedef struct _NMDeviceIwd NMDeviceIwd; typedef struct _NMDeviceIwdClass NMDeviceIwdClass; -GType nm_device_iwd_get_type (void); +GType nm_device_iwd_get_type(void); -NMDevice *nm_device_iwd_new (const char *iface); +NMDevice *nm_device_iwd_new(const char *iface); -void nm_device_iwd_set_dbus_object (NMDeviceIwd *device, GDBusObject *object); +void nm_device_iwd_set_dbus_object(NMDeviceIwd *device, GDBusObject *object); -gboolean nm_device_iwd_agent_query (NMDeviceIwd *device, - GDBusMethodInvocation *invocation); +gboolean nm_device_iwd_agent_query(NMDeviceIwd *device, GDBusMethodInvocation *invocation); -const CList *_nm_device_iwd_get_aps (NMDeviceIwd *self); +const CList *_nm_device_iwd_get_aps(NMDeviceIwd *self); -void _nm_device_iwd_request_scan (NMDeviceIwd *self, - GVariant *options, - GDBusMethodInvocation *invocation); +void _nm_device_iwd_request_scan(NMDeviceIwd * self, + GVariant * options, + GDBusMethodInvocation *invocation); #endif /* __NETWORKMANAGER_DEVICE_IWD_H__ */ diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 770b53f6..22e94a6d 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Dan Williams * Sjoerd Simons @@ -35,511 +35,517 @@ _LOG_DECLARE_SELF(NMDeviceOlpcMesh); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceOlpcMesh, - PROP_COMPANION, - PROP_ACTIVE_CHANNEL, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceOlpcMesh, PROP_COMPANION, PROP_ACTIVE_CHANNEL, ); typedef struct { - NMDevice *companion; - NMManager *manager; - bool stage1_waiting:1; + NMDevice * companion; + NMManager *manager; + bool stage1_waiting : 1; } NMDeviceOlpcMeshPrivate; struct _NMDeviceOlpcMesh { - NMDevice parent; - NMDeviceOlpcMeshPrivate _priv; + NMDevice parent; + NMDeviceOlpcMeshPrivate _priv; }; struct _NMDeviceOlpcMeshClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) -#define NM_DEVICE_OLPC_MESH_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceOlpcMesh, NM_IS_DEVICE_OLPC_MESH, NMDevice) +#define NM_DEVICE_OLPC_MESH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceOlpcMesh, NM_IS_DEVICE_OLPC_MESH, NMDevice) /*****************************************************************************/ static gboolean -get_autoconnect_allowed (NMDevice *device) +get_autoconnect_allowed(NMDevice *device) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); - /* We can't even connect if we don't have a companion yet. */ - if (!priv->companion) - return FALSE; + /* We can't even connect if we don't have a companion yet. */ + if (!priv->companion) + return FALSE; - /* We must not attempt to autoconnect when the companion is connected or - * connecting, * because we'd tear down its connection. */ - if (nm_device_get_state (priv->companion) > NM_DEVICE_STATE_DISCONNECTED) - return FALSE; + /* We must not attempt to autoconnect when the companion is connected or + * connecting, * because we'd tear down its connection. */ + if (nm_device_get_state(priv->companion) > NM_DEVICE_STATE_DISCONNECTED) + return FALSE; - return TRUE; + return TRUE; } #define DEFAULT_SSID "olpc-mesh" static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMSettingOlpcMesh *s_mesh; - - s_mesh = nm_connection_get_setting_olpc_mesh (connection); - if (!s_mesh) { - s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new (); - nm_connection_add_setting (connection, NM_SETTING (s_mesh)); - } - - if (!nm_setting_olpc_mesh_get_ssid (s_mesh)) { - gs_unref_bytes GBytes *ssid = NULL; - - ssid = g_bytes_new_static (DEFAULT_SSID, NM_STRLEN (DEFAULT_SSID)); - g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, ssid, NULL); - } - - if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) { - const char *anycast = "c0:27:c0:27:c0:27"; - - g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, anycast, NULL); - - } - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_OLPC_MESH_SETTING_NAME, - existing_connections, - NULL, - _("Mesh"), - NULL, - NULL, - FALSE); /* No IPv6 by default */ - - return TRUE; + NMSettingOlpcMesh *s_mesh; + + s_mesh = nm_connection_get_setting_olpc_mesh(connection); + if (!s_mesh) { + s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new(); + nm_connection_add_setting(connection, NM_SETTING(s_mesh)); + } + + if (!nm_setting_olpc_mesh_get_ssid(s_mesh)) { + gs_unref_bytes GBytes *ssid = NULL; + + ssid = g_bytes_new_static(DEFAULT_SSID, NM_STRLEN(DEFAULT_SSID)); + g_object_set(G_OBJECT(s_mesh), NM_SETTING_OLPC_MESH_SSID, ssid, NULL); + } + + if (!nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh)) { + const char *anycast = "c0:27:c0:27:c0:27"; + + g_object_set(G_OBJECT(s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, anycast, NULL); + } + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_OLPC_MESH_SETTING_NAME, + existing_connections, + NULL, + _("Mesh"), + NULL, + NULL, + FALSE); /* No IPv6 by default */ + + return TRUE; } /*****************************************************************************/ static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - /* disconnect companion device, if it is connected */ - if (nm_device_get_act_request (NM_DEVICE (priv->companion))) { - _LOGI (LOGD_OLPC, "disconnecting companion device %s", - nm_device_get_iface (priv->companion)); - /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ - nm_device_state_changed (NM_DEVICE (priv->companion), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - _LOGI (LOGD_OLPC, "companion %s disconnected", - nm_device_get_iface (priv->companion)); - } - - /* wait with continuing configuration until the companion device is done scanning */ - if (nm_device_wifi_get_scanning (NM_DEVICE_WIFI (priv->companion))) { - priv->stage1_waiting = TRUE; - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - priv->stage1_waiting = FALSE; - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + + /* disconnect companion device, if it is connected */ + if (nm_device_get_act_request(NM_DEVICE(priv->companion))) { + _LOGI(LOGD_OLPC, "disconnecting companion device %s", nm_device_get_iface(priv->companion)); + /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ + nm_device_state_changed(NM_DEVICE(priv->companion), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + _LOGI(LOGD_OLPC, "companion %s disconnected", nm_device_get_iface(priv->companion)); + } + + /* wait with continuing configuration until the companion device is done scanning */ + if (nm_device_wifi_get_scanning(NM_DEVICE_WIFI(priv->companion))) { + priv->stage1_waiting = TRUE; + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + priv->stage1_waiting = FALSE; + return NM_ACT_STAGE_RETURN_SUCCESS; } static gboolean -_mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) +_mesh_set_channel(NMDeviceOlpcMesh *self, guint32 channel) { - NMPlatform *platform; - int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - guint32 old_channel; + NMPlatform *platform; + int ifindex = nm_device_get_ifindex(NM_DEVICE(self)); + guint32 old_channel; - platform = nm_device_get_platform (NM_DEVICE (self)); - old_channel = nm_platform_mesh_get_channel (platform, ifindex); + platform = nm_device_get_platform(NM_DEVICE(self)); + old_channel = nm_platform_mesh_get_channel(platform, ifindex); - if (channel == 0) - channel = old_channel; + if (channel == 0) + channel = old_channel; - /* We want to call this even if the channel number is the same, - * because that actually starts the mesh with the configured mesh ID. */ - if (!nm_platform_mesh_set_channel (platform, ifindex, channel)) - return FALSE; + /* We want to call this even if the channel number is the same, + * because that actually starts the mesh with the configured mesh ID. */ + if (!nm_platform_mesh_set_channel(platform, ifindex, channel)) + return FALSE; - if (old_channel != channel) - _notify (self, PROP_ACTIVE_CHANNEL); + if (old_channel != channel) + _notify(self, PROP_ACTIVE_CHANNEL); - return TRUE; + return TRUE; } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); - NMSettingOlpcMesh *s_mesh; - GBytes *ssid; - const char *anycast_addr; - gboolean success; - - s_mesh = nm_device_get_applied_setting (device, NM_TYPE_SETTING_OLPC_MESH); - g_return_val_if_fail (s_mesh, NM_ACT_STAGE_RETURN_FAILURE); - - ssid = nm_setting_olpc_mesh_get_ssid (s_mesh); - - nm_device_take_down (NM_DEVICE (self), TRUE); - success = nm_platform_mesh_set_ssid (nm_device_get_platform (device), - nm_device_get_ifindex (device), - g_bytes_get_data (ssid, NULL), - g_bytes_get_size (ssid)); - nm_device_bring_up (NM_DEVICE (self), TRUE, NULL); - if (!success) { - _LOGW (LOGD_WIFI, "Unable to set the mesh ID"); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); - nm_device_set_dhcp_anycast_address (device, anycast_addr); - - if (!_mesh_set_channel (self, nm_setting_olpc_mesh_get_channel (s_mesh))) { - _LOGW (LOGD_WIFI, "Unable to set the mesh channel"); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device); + NMSettingOlpcMesh *s_mesh; + GBytes * ssid; + const char * anycast_addr; + gboolean success; + + s_mesh = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OLPC_MESH); + g_return_val_if_fail(s_mesh, NM_ACT_STAGE_RETURN_FAILURE); + + ssid = nm_setting_olpc_mesh_get_ssid(s_mesh); + + nm_device_take_down(NM_DEVICE(self), TRUE); + success = nm_platform_mesh_set_ssid(nm_device_get_platform(device), + nm_device_get_ifindex(device), + g_bytes_get_data(ssid, NULL), + g_bytes_get_size(ssid)); + nm_device_bring_up(NM_DEVICE(self), TRUE, NULL); + if (!success) { + _LOGW(LOGD_WIFI, "Unable to set the mesh ID"); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh); + nm_device_set_dhcp_anycast_address(device, anycast_addr); + + if (!_mesh_set_channel(self, nm_setting_olpc_mesh_get_channel(s_mesh))) { + _LOGW(LOGD_WIFI, "Unable to set the mesh channel"); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(device); - if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion) { - _LOGD (LOGD_WIFI, "not available because companion not found"); - return FALSE; - } + if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE(self)->companion) { + _LOGD(LOGD_WIFI, "not available because companion not found"); + return FALSE; + } - return TRUE; + return TRUE; } /*****************************************************************************/ static void -companion_cleanup (NMDeviceOlpcMesh *self) +companion_cleanup(NMDeviceOlpcMesh *self) { - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - if (priv->companion) { - nm_device_wifi_scanning_prohibited_track (NM_DEVICE_WIFI (priv->companion), - self, - FALSE); - g_signal_handlers_disconnect_by_data (priv->companion, self); - g_clear_object (&priv->companion); - } - _notify (self, PROP_COMPANION); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + + if (priv->companion) { + nm_device_wifi_scanning_prohibited_track(NM_DEVICE_WIFI(priv->companion), self, FALSE); + g_signal_handlers_disconnect_by_data(priv->companion, self); + g_clear_object(&priv->companion); + } + _notify(self, PROP_COMPANION); } static void -companion_notify_cb (NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_data) +companion_notify_cb(NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_data) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(user_data); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); - nm_assert (NM_IS_DEVICE_WIFI (companion)); - nm_assert (priv->companion == (gpointer) companion); + nm_assert(NM_IS_DEVICE_WIFI(companion)); + nm_assert(priv->companion == (gpointer) companion); - if (!priv->stage1_waiting) - return; + if (!priv->stage1_waiting) + return; - if (!nm_device_wifi_get_scanning (NM_DEVICE_WIFI (companion))) { - priv->stage1_waiting = FALSE; - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); - } + if (!nm_device_wifi_get_scanning(NM_DEVICE_WIFI(companion))) { + priv->stage1_waiting = FALSE; + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); + } } /* disconnect from mesh if someone starts using the companion */ static void -companion_state_changed_cb (NMDeviceWifi *companion, - NMDeviceState state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) +companion_state_changed_cb(NMDeviceWifi * companion, + NMDeviceState state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceState self_state = nm_device_get_state (NM_DEVICE (self)); - - if ( old_state > NM_DEVICE_STATE_DISCONNECTED - && state <= NM_DEVICE_STATE_DISCONNECTED) { - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - } - - if ( self_state < NM_DEVICE_STATE_PREPARE - || self_state > NM_DEVICE_STATE_ACTIVATED - || state < NM_DEVICE_STATE_PREPARE - || state > NM_DEVICE_STATE_ACTIVATED) - return; - - _LOGD (LOGD_OLPC, "disconnecting mesh due to companion connectivity"); - /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data); + NMDeviceState self_state = nm_device_get_state(NM_DEVICE(self)); + + if (old_state > NM_DEVICE_STATE_DISCONNECTED && state <= NM_DEVICE_STATE_DISCONNECTED) { + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + } + + if (self_state < NM_DEVICE_STATE_PREPARE || self_state > NM_DEVICE_STATE_ACTIVATED + || state < NM_DEVICE_STATE_PREPARE || state > NM_DEVICE_STATE_ACTIVATED) + return; + + _LOGD(LOGD_OLPC, "disconnecting mesh due to companion connectivity"); + /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); } static gboolean -companion_autoconnect_allowed_cb (NMDeviceWifi *companion, gpointer user_data) +companion_autoconnect_allowed_cb(NMDeviceWifi *companion, gpointer user_data) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceState state = nm_device_get_state (NM_DEVICE (self)); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data); + NMDeviceState state = nm_device_get_state(NM_DEVICE(self)); - /* Don't allow the companion to autoconnect while a mesh connection is - * active */ - return (state < NM_DEVICE_STATE_PREPARE) || (state > NM_DEVICE_STATE_ACTIVATED); + /* Don't allow the companion to autoconnect while a mesh connection is + * active */ + return (state < NM_DEVICE_STATE_PREPARE) || (state > NM_DEVICE_STATE_ACTIVATED); } static gboolean -check_companion (NMDeviceOlpcMesh *self, NMDevice *other) +check_companion(NMDeviceOlpcMesh *self, NMDevice *other) { - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - const char *my_addr, *their_addr; + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + const char * my_addr, *their_addr; - if (!NM_IS_DEVICE_WIFI (other)) - return FALSE; + if (!NM_IS_DEVICE_WIFI(other)) + return FALSE; - my_addr = nm_device_get_hw_address (NM_DEVICE (self)); - their_addr = nm_device_get_hw_address (other); - if (!nm_utils_hwaddr_matches (my_addr, -1, their_addr, -1)) - return FALSE; + my_addr = nm_device_get_hw_address(NM_DEVICE(self)); + their_addr = nm_device_get_hw_address(other); + if (!nm_utils_hwaddr_matches(my_addr, -1, their_addr, -1)) + return FALSE; - nm_assert (priv->companion == NULL); - priv->companion = g_object_ref (other); + nm_assert(priv->companion == NULL); + priv->companion = g_object_ref(other); - _LOGI (LOGD_OLPC, "found companion Wi-Fi device %s", - nm_device_get_iface (other)); + _LOGI(LOGD_OLPC, "found companion Wi-Fi device %s", nm_device_get_iface(other)); - g_signal_connect (G_OBJECT (other), NM_DEVICE_STATE_CHANGED, - G_CALLBACK (companion_state_changed_cb), self); + g_signal_connect(G_OBJECT(other), + NM_DEVICE_STATE_CHANGED, + G_CALLBACK(companion_state_changed_cb), + self); - g_signal_connect (G_OBJECT (other), "notify::" NM_DEVICE_WIFI_SCANNING, - G_CALLBACK (companion_notify_cb), self); + g_signal_connect(G_OBJECT(other), + "notify::" NM_DEVICE_WIFI_SCANNING, + G_CALLBACK(companion_notify_cb), + self); - g_signal_connect (G_OBJECT (other), NM_DEVICE_AUTOCONNECT_ALLOWED, - G_CALLBACK (companion_autoconnect_allowed_cb), self); + g_signal_connect(G_OBJECT(other), + NM_DEVICE_AUTOCONNECT_ALLOWED, + G_CALLBACK(companion_autoconnect_allowed_cb), + self); - _notify (self, PROP_COMPANION); + _notify(self, PROP_COMPANION); - return TRUE; + return TRUE; } static void -device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data) +device_added_cb(NMManager *manager, NMDevice *other, gpointer user_data) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - if (!priv->companion && check_companion (self, other)) { - nm_device_queue_recheck_available (NM_DEVICE (self), - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_NONE); - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, FALSE); - } + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(user_data); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + + if (!priv->companion && check_companion(self, other)) { + nm_device_queue_recheck_available(NM_DEVICE(self), + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_NONE); + nm_device_remove_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_COMPANION, + FALSE); + } } static void -device_removed_cb (NMManager *manager, NMDevice *other, gpointer user_data) +device_removed_cb(NMManager *manager, NMDevice *other, gpointer user_data) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH(user_data); - if (other == NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion) - companion_cleanup (self); + if (other == NM_DEVICE_OLPC_MESH_GET_PRIVATE(self)->companion) + companion_cleanup(self); } static void -find_companion (NMDeviceOlpcMesh *self) +find_companion(NMDeviceOlpcMesh *self) { - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *candidate; - - if (priv->companion) - return; - - nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE); - - /* Try to find the companion if it's already known to the NMManager */ - nm_manager_for_each_device (priv->manager, candidate, tmp_lst) { - if (check_companion (self, candidate)) { - nm_device_queue_recheck_available (NM_DEVICE (self), - NM_DEVICE_STATE_REASON_NONE, - NM_DEVICE_STATE_REASON_NONE); - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE); - break; - } - } + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + const CList * tmp_lst; + NMDevice * candidate; + + if (priv->companion) + return; + + nm_device_add_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WAITING_FOR_COMPANION, TRUE); + + /* Try to find the companion if it's already known to the NMManager */ + nm_manager_for_each_device (priv->manager, candidate, tmp_lst) { + if (check_companion(self, candidate)) { + nm_device_queue_recheck_available(NM_DEVICE(self), + NM_DEVICE_STATE_REASON_NONE, + NM_DEVICE_STATE_REASON_NONE); + nm_device_remove_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_COMPANION, + TRUE); + break; + } + } } static void -state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - if (new_state == NM_DEVICE_STATE_UNAVAILABLE) - find_companion (self); - - if (priv->companion) { - gboolean temporarily_prohibited = FALSE; - - if ( new_state >= NM_DEVICE_STATE_PREPARE - && new_state <= NM_DEVICE_STATE_IP_CONFIG) { - /* Don't allow the companion to scan while configuring the mesh interface */ - temporarily_prohibited = TRUE; - } - nm_device_wifi_scanning_prohibited_track (NM_DEVICE_WIFI (priv->companion), - self, - temporarily_prohibited); - } + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + + if (new_state == NM_DEVICE_STATE_UNAVAILABLE) + find_companion(self); + + if (priv->companion) { + gboolean temporarily_prohibited = FALSE; + + if (new_state >= NM_DEVICE_STATE_PREPARE && new_state <= NM_DEVICE_STATE_IP_CONFIG) { + /* Don't allow the companion to scan while configuring the mesh interface */ + temporarily_prohibited = TRUE; + } + nm_device_wifi_scanning_prohibited_track(NM_DEVICE_WIFI(priv->companion), + self, + temporarily_prohibited); + } } static guint32 -get_dhcp_timeout_for_device (NMDevice *device, int addr_family) +get_dhcp_timeout_for_device(NMDevice *device, int addr_family) { - /* shorter timeout for mesh connectivity */ - return 20; + /* shorter timeout for mesh connectivity */ + return 20; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); - NMDevice *device = NM_DEVICE (self); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_COMPANION: - nm_dbus_utils_g_value_set_object_path (value, priv->companion); - break; - case PROP_ACTIVE_CHANNEL: - g_value_set_uint (value, nm_platform_mesh_get_channel (nm_device_get_platform (device), nm_device_get_ifindex (device))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object); + NMDevice * device = NM_DEVICE(self); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_COMPANION: + nm_dbus_utils_g_value_set_object_path(value, priv->companion); + break; + case PROP_ACTIVE_CHANNEL: + g_value_set_uint(value, + nm_platform_mesh_get_channel(nm_device_get_platform(device), + nm_device_get_ifindex(device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_olpc_mesh_init (NMDeviceOlpcMesh * self) -{ -} +nm_device_olpc_mesh_init(NMDeviceOlpcMesh *self) +{} static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); - G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_device_olpc_mesh_parent_class)->constructed(object); - priv->manager = g_object_ref (NM_MANAGER_GET); + priv->manager = g_object_ref(NM_MANAGER_GET); - g_signal_connect (priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK (device_added_cb), self); - g_signal_connect (priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK (device_removed_cb), self); + g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added_cb), self); + g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed_cb), self); } NMDevice * -nm_device_olpc_mesh_new (const char *iface) +nm_device_olpc_mesh_new(const char *iface) { - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_OLPC_MESH, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "802.11 OLPC Mesh", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_OLPC_MESH, - NULL); + return (NMDevice *) g_object_new(NM_TYPE_DEVICE_OLPC_MESH, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "802.11 OLPC Mesh", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_OLPC_MESH, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_OLPC_MESH, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); + NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(object); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE(self); - companion_cleanup (self); + companion_cleanup(self); - if (priv->manager) { - g_signal_handlers_disconnect_by_func (priv->manager, G_CALLBACK (device_added_cb), self); - g_signal_handlers_disconnect_by_func (priv->manager, G_CALLBACK (device_removed_cb), self); - g_clear_object (&priv->manager); - } + if (priv->manager) { + g_signal_handlers_disconnect_by_func(priv->manager, G_CALLBACK(device_added_cb), self); + g_signal_handlers_disconnect_by_func(priv->manager, G_CALLBACK(device_removed_cb), self); + g_clear_object(&priv->manager); + } - G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_olpc_mesh_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_olpc_mesh = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Companion", "o", NM_DEVICE_OLPC_MESH_COMPANION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveChannel", "u", NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Companion", + "o", + NM_DEVICE_OLPC_MESH_COMPANION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + "ActiveChannel", + "u", + NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) +nm_device_olpc_mesh_class_init(NMDeviceOlpcMeshClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->dispose = dispose; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_olpc_mesh); - - device_class->connection_type_supported = NM_SETTING_OLPC_MESH_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OLPC_MESH_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OLPC_MESH); - - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->complete_connection = complete_connection; - device_class->is_available = is_available; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->state_changed = state_changed; - device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; - - obj_properties[PROP_COMPANION] = - g_param_spec_string (NM_DEVICE_OLPC_MESH_COMPANION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ACTIVE_CHANNEL] = - g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->dispose = dispose; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_olpc_mesh); + + device_class->connection_type_supported = NM_SETTING_OLPC_MESH_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_OLPC_MESH_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_OLPC_MESH); + + device_class->get_autoconnect_allowed = get_autoconnect_allowed; + device_class->complete_connection = complete_connection; + device_class->is_available = is_available; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->state_changed = state_changed; + device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; + + obj_properties[PROP_COMPANION] = g_param_spec_string(NM_DEVICE_OLPC_MESH_COMPANION, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACTIVE_CHANNEL] = + g_param_spec_uint(NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } - diff --git a/src/devices/wifi/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h index e6e76d6f..d31c86fb 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.h +++ b/src/devices/wifi/nm-device-olpc-mesh.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Dan Williams * Sjoerd Simons @@ -13,22 +13,26 @@ #include "devices/nm-device.h" -#define NM_TYPE_DEVICE_OLPC_MESH (nm_device_olpc_mesh_get_type ()) -#define NM_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMesh)) -#define NM_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) -#define NM_IS_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OLPC_MESH)) -#define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OLPC_MESH)) -#define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) +#define NM_TYPE_DEVICE_OLPC_MESH (nm_device_olpc_mesh_get_type()) +#define NM_DEVICE_OLPC_MESH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMesh)) +#define NM_DEVICE_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) +#define NM_IS_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) #define NM_DEVICE_OLPC_MESH_COMPANION "companion" #define NM_DEVICE_OLPC_MESH_BITRATE "bitrate" #define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel" -typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh; +typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh; typedef struct _NMDeviceOlpcMeshClass NMDeviceOlpcMeshClass; -GType nm_device_olpc_mesh_get_type (void); +GType nm_device_olpc_mesh_get_type(void); -NMDevice *nm_device_olpc_mesh_new (const char *iface); +NMDevice *nm_device_olpc_mesh_new(const char *iface); #endif /* __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ */ diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index 497bc436..2e5317fd 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -32,292 +32,295 @@ _LOG_DECLARE_SELF(NMDeviceWifiP2P); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifiP2P, - PROP_PEERS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceWifiP2P, PROP_PEERS, ); typedef struct { - NMSupplicantManager *sup_mgr; + NMSupplicantManager *sup_mgr; - /* NOTE: In theory management and group ifaces could be identical. However, - * in practice, this cannot happen currently as NMDeviceWifiP2P is only - * created for existing non-P2P interfaces. - * (i.e. a single standalone P2P interface is not supported at this point) - */ - NMSupplicantInterface *mgmt_iface; - NMSupplicantInterface *group_iface; + /* NOTE: In theory management and group ifaces could be identical. However, + * in practice, this cannot happen currently as NMDeviceWifiP2P is only + * created for existing non-P2P interfaces. + * (i.e. a single standalone P2P interface is not supported at this point) + */ + NMSupplicantInterface *mgmt_iface; + NMSupplicantInterface *group_iface; - CList peers_lst_head; + CList peers_lst_head; - guint find_peer_timeout_id; - guint sup_timeout_id; - guint peer_dump_id; - guint peer_missing_id; + guint find_peer_timeout_id; + guint sup_timeout_id; + guint peer_dump_id; + guint peer_missing_id; - bool is_waiting_for_supplicant:1; + bool is_waiting_for_supplicant : 1; } NMDeviceWifiP2PPrivate; struct _NMDeviceWifiP2P { - NMDevice parent; - NMDeviceWifiP2PPrivate _priv; + NMDevice parent; + NMDeviceWifiP2PPrivate _priv; }; struct _NMDeviceWifiP2PClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceWifiP2P, nm_device_wifi_p2p, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceWifiP2P, nm_device_wifi_p2p, NM_TYPE_DEVICE) -#define NM_DEVICE_WIFI_P2P_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceWifiP2P, NM_IS_DEVICE_WIFI_P2P, NMDevice) +#define NM_DEVICE_WIFI_P2P_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWifiP2P, NM_IS_DEVICE_WIFI_P2P, NMDevice) /*****************************************************************************/ static const NMDBusInterfaceInfoExtended interface_info_device_wifi_p2p; -static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_added; -static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_removed; +static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_added; +static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_removed; -static void supplicant_group_interface_release (NMDeviceWifiP2P *self); -static void supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting); +static void supplicant_group_interface_release(NMDeviceWifiP2P *self); +static void supplicant_interfaces_release(NMDeviceWifiP2P *self, gboolean set_is_waiting); /*****************************************************************************/ static void -_peer_dump (NMDeviceWifiP2P *self, - NMLogLevel log_level, - const NMWifiP2PPeer *peer, - const char *prefix, - gint32 now_s) +_peer_dump(NMDeviceWifiP2P * self, + NMLogLevel log_level, + const NMWifiP2PPeer *peer, + const char * prefix, + gint32 now_s) { - char buf[1024]; + char buf[1024]; - _NMLOG (log_level, LOGD_WIFI_SCAN, "wifi-peer: %-7s %s", - prefix, - nm_wifi_p2p_peer_to_string (peer, buf, sizeof (buf), now_s)); + _NMLOG(log_level, + LOGD_WIFI_SCAN, + "wifi-peer: %-7s %s", + prefix, + nm_wifi_p2p_peer_to_string(peer, buf, sizeof(buf), now_s)); } static gboolean -peer_list_dump (gpointer user_data) +peer_list_dump(gpointer user_data) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(user_data); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - priv->peer_dump_id = 0; + priv->peer_dump_id = 0; - if (_LOGD_ENABLED (LOGD_WIFI_SCAN)) { - NMWifiP2PPeer *peer; - gint32 now_s = nm_utils_get_monotonic_timestamp_sec (); + if (_LOGD_ENABLED(LOGD_WIFI_SCAN)) { + NMWifiP2PPeer *peer; + gint32 now_s = nm_utils_get_monotonic_timestamp_sec(); - _LOGD (LOGD_WIFI_SCAN, "P2P Peers: [now:%u]", now_s); - c_list_for_each_entry (peer, &priv->peers_lst_head, peers_lst) - _peer_dump (self, LOGL_DEBUG, peer, "dump", now_s); - } - return G_SOURCE_REMOVE; + _LOGD(LOGD_WIFI_SCAN, "P2P Peers: [now:%u]", now_s); + c_list_for_each_entry (peer, &priv->peers_lst_head, peers_lst) + _peer_dump(self, LOGL_DEBUG, peer, "dump", now_s); + } + return G_SOURCE_REMOVE; } static void -schedule_peer_list_dump (NMDeviceWifiP2P *self) +schedule_peer_list_dump(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if ( !priv->peer_dump_id - && _LOGD_ENABLED (LOGD_WIFI_SCAN)) - priv->peer_dump_id = g_timeout_add_seconds (1, peer_list_dump, self); + if (!priv->peer_dump_id && _LOGD_ENABLED(LOGD_WIFI_SCAN)) + priv->peer_dump_id = g_timeout_add_seconds(1, peer_list_dump, self); } /*****************************************************************************/ static void -_set_is_waiting_for_supplicant (NMDeviceWifiP2P *self, gboolean is_waiting) +_set_is_waiting_for_supplicant(NMDeviceWifiP2P *self, gboolean is_waiting) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if (priv->is_waiting_for_supplicant == (!!is_waiting)) - return; + if (priv->is_waiting_for_supplicant == (!!is_waiting)) + return; - priv->is_waiting_for_supplicant = is_waiting; + priv->is_waiting_for_supplicant = is_waiting; - if (is_waiting) - nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); - else - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); + if (is_waiting) + nm_device_add_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, + TRUE); + else + nm_device_remove_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, + TRUE); } /*****************************************************************************/ static gboolean -check_connection_peer_joined (NMDeviceWifiP2P *device) +check_connection_peer_joined(NMDeviceWifiP2P *device) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (device); - NMConnection *conn = nm_device_get_applied_connection (NM_DEVICE (device)); - NMWifiP2PPeer *peer; - const char* group; - const char * const * groups; - - if (!conn || !priv->group_iface) - return FALSE; - - /* Comparing the object path found on the group_iface with the peers - * found on the mgmt_iface is legal. */ - group = nm_supplicant_interface_get_p2p_group_path (priv->group_iface); - if (!group) - return FALSE; - - /* NOTE: We currently only support connections to a specific peer */ - peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, conn); - if (!peer) - return FALSE; - - groups = nm_wifi_p2p_peer_get_groups (peer); - if ( !groups - || !g_strv_contains (groups, group)) - return FALSE; - - return TRUE; + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(device); + NMConnection * conn = nm_device_get_applied_connection(NM_DEVICE(device)); + NMWifiP2PPeer * peer; + const char * group; + const char *const * groups; + + if (!conn || !priv->group_iface) + return FALSE; + + /* Comparing the object path found on the group_iface with the peers + * found on the mgmt_iface is legal. */ + group = nm_supplicant_interface_get_p2p_group_path(priv->group_iface); + if (!group) + return FALSE; + + /* NOTE: We currently only support connections to a specific peer */ + peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, conn); + if (!peer) + return FALSE; + + groups = nm_wifi_p2p_peer_get_groups(peer); + if (!groups || !g_strv_contains(groups, group)) + return FALSE; + + return TRUE; } static gboolean -disconnect_on_connection_peer_missing_cb (gpointer user_data) +disconnect_on_connection_peer_missing_cb(gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - _LOGW (LOGD_WIFI, "Peer requested in connection is missing for too long, failing connection."); + _LOGW(LOGD_WIFI, "Peer requested in connection is missing for too long, failing connection."); - priv->peer_missing_id = 0; + priv->peer_missing_id = 0; - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); - return FALSE; + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); + return FALSE; } static void -update_disconnect_on_connection_peer_missing (NMDeviceWifiP2P *self) +update_disconnect_on_connection_peer_missing(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMDeviceState state; - - state = nm_device_get_state (NM_DEVICE (self)); - if ( state < NM_DEVICE_STATE_IP_CONFIG - || state > NM_DEVICE_STATE_ACTIVATED) { - nm_clear_g_source (&priv->peer_missing_id); - return; - } - - if (check_connection_peer_joined (self)) { - if (nm_clear_g_source (&priv->peer_missing_id)) - _LOGD (LOGD_WIFI, "Peer requested in connection is joined, removing timeout"); - return; - } - - if (priv->peer_missing_id == 0) { - _LOGD (LOGD_WIFI, "Peer requested in connection is missing, adding timeout"); - priv->peer_missing_id = g_timeout_add_seconds (5, disconnect_on_connection_peer_missing_cb, self); - } + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMDeviceState state; + + state = nm_device_get_state(NM_DEVICE(self)); + if (state < NM_DEVICE_STATE_IP_CONFIG || state > NM_DEVICE_STATE_ACTIVATED) { + nm_clear_g_source(&priv->peer_missing_id); + return; + } + + if (check_connection_peer_joined(self)) { + if (nm_clear_g_source(&priv->peer_missing_id)) + _LOGD(LOGD_WIFI, "Peer requested in connection is joined, removing timeout"); + return; + } + + if (priv->peer_missing_id == 0) { + _LOGD(LOGD_WIFI, "Peer requested in connection is missing, adding timeout"); + priv->peer_missing_id = + g_timeout_add_seconds(5, disconnect_on_connection_peer_missing_cb, self); + } } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMSupplicantInterfaceState supplicant_state; + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate * priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMSupplicantInterfaceState supplicant_state; - if (!priv->mgmt_iface) - return FALSE; + if (!priv->mgmt_iface) + return FALSE; - supplicant_state = nm_supplicant_interface_get_state (priv->mgmt_iface); - return nm_supplicant_interface_state_is_operational (supplicant_state); + supplicant_state = nm_supplicant_interface_get_state(priv->mgmt_iface); + return nm_supplicant_interface_state_is_operational(supplicant_state); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { - if (!NM_DEVICE_CLASS (nm_device_wifi_p2p_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_wifi_p2p_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; - /* TODO: Allow limitting the interface using the HW-address? */ + /* TODO: Allow limitting the interface using the HW-address? */ - /* We don't need to check anything else here. The P2P device will only - * exists if we are able to establish a P2P connection, and there should - * be no further restrictions necessary. - */ + /* We don't need to check anything else here. The P2P device will only + * exists if we are able to establish a P2P connection, and there should + * be no further restrictions necessary. + */ - return TRUE; + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - gs_free char *setting_name = NULL; - NMSettingWifiP2P *s_wifi_p2p; - NMWifiP2PPeer *peer; - const char *setting_peer; - - s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P)); - - if (!specific_object) { - /* If not given a specific object, we need at minimum a peer address */ - if (!s_wifi_p2p) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A '%s' setting is required if no Peer path was given", - NM_SETTING_WIFI_P2P_SETTING_NAME); - return FALSE; - } - - setting_peer = nm_setting_wifi_p2p_get_peer (s_wifi_p2p); - if (!setting_peer) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A '%s' setting with a valid Peer is required if no Peer path was given", - NM_SETTING_WIFI_P2P_SETTING_NAME); - return FALSE; - } - - } else { - peer = nm_wifi_p2p_peer_lookup_for_device (NM_DEVICE (self), specific_object); - if (!peer) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, - "The P2P peer %s is unknown", - specific_object); - return FALSE; - } - - setting_peer = nm_wifi_p2p_peer_get_address (peer); - g_return_val_if_fail (setting_peer, FALSE); - } - - /* Add a Wi-Fi P2P setting if one doesn't exist yet */ - if (!s_wifi_p2p) { - s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_setting_wifi_p2p_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wifi_p2p)); - } - - g_object_set (G_OBJECT (s_wifi_p2p), NM_SETTING_WIFI_P2P_PEER, setting_peer, NULL); - - setting_name = g_strdup_printf ("Wi-Fi P2P Peer %s", setting_peer); - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_WIFI_P2P_SETTING_NAME, - existing_connections, - setting_name, - setting_name, - NULL, - NULL, - TRUE); - - return TRUE; + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + gs_free char * setting_name = NULL; + NMSettingWifiP2P *s_wifi_p2p; + NMWifiP2PPeer * peer; + const char * setting_peer; + + s_wifi_p2p = + NM_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)); + + if (!specific_object) { + /* If not given a specific object, we need at minimum a peer address */ + if (!s_wifi_p2p) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A '%s' setting is required if no Peer path was given", + NM_SETTING_WIFI_P2P_SETTING_NAME); + return FALSE; + } + + setting_peer = nm_setting_wifi_p2p_get_peer(s_wifi_p2p); + if (!setting_peer) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A '%s' setting with a valid Peer is required if no Peer path was given", + NM_SETTING_WIFI_P2P_SETTING_NAME); + return FALSE; + } + + } else { + peer = nm_wifi_p2p_peer_lookup_for_device(NM_DEVICE(self), specific_object); + if (!peer) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, + "The P2P peer %s is unknown", + specific_object); + return FALSE; + } + + setting_peer = nm_wifi_p2p_peer_get_address(peer); + g_return_val_if_fail(setting_peer, FALSE); + } + + /* Add a Wi-Fi P2P setting if one doesn't exist yet */ + if (!s_wifi_p2p) { + s_wifi_p2p = NM_SETTING_WIFI_P2P(nm_setting_wifi_p2p_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wifi_p2p)); + } + + g_object_set(G_OBJECT(s_wifi_p2p), NM_SETTING_WIFI_P2P_PEER, setting_peer, NULL); + + setting_name = g_strdup_printf("Wi-Fi P2P Peer %s", setting_peer); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_WIFI_P2P_SETTING_NAME, + existing_connections, + setting_name, + setting_name, + NULL, + NULL, + TRUE); + + return TRUE; } /* @@ -326,60 +329,61 @@ complete_connection (NMDevice *device, * Called when the supplicant has been unable to find the peer we want to connect to. */ static gboolean -supplicant_find_timeout_cb (gpointer user_data) +supplicant_find_timeout_cb(gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(user_data); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - priv->find_peer_timeout_id = 0; + priv->find_peer_timeout_id = 0; - nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface); + nm_supplicant_interface_p2p_cancel_connect(priv->mgmt_iface); - if (nm_device_is_activating (device)) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi-p2p) could not find peer, failing activation"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); - } + if (nm_device_is_activating(device)) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi-p2p) could not find peer, failing activation"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); + } - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMConnection *connection; - NMSettingWifiP2P *s_wifi_p2p; - NMWifiP2PPeer *peer; - - if (!priv->mgmt_iface) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P)); - g_return_val_if_fail (s_wifi_p2p, NM_ACT_STAGE_RETURN_FAILURE); - - peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection); - if (!peer) { - /* Set up a timeout on the find attempt and run a find for the same period of time */ - if (priv->find_peer_timeout_id == 0) { - priv->find_peer_timeout_id = g_timeout_add_seconds (10, - supplicant_find_timeout_cb, - self); - - nm_supplicant_interface_p2p_start_find (priv->mgmt_iface, 10); - } - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - return NM_ACT_STAGE_RETURN_SUCCESS; + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMConnection * connection; + NMSettingWifiP2P * s_wifi_p2p; + NMWifiP2PPeer * peer; + + if (!priv->mgmt_iface) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + s_wifi_p2p = + NM_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)); + g_return_val_if_fail(s_wifi_p2p, NM_ACT_STAGE_RETURN_FAILURE); + + peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection); + if (!peer) { + /* Set up a timeout on the find attempt and run a find for the same period of time */ + if (priv->find_peer_timeout_id == 0) { + priv->find_peer_timeout_id = + g_timeout_add_seconds(10, supplicant_find_timeout_cb, self); + + nm_supplicant_interface_p2p_start_find(priv->mgmt_iface, 10); + } + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; } /* @@ -389,881 +393,888 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) * within a specified period of time. */ static gboolean -supplicant_connection_timeout_cb (gpointer user_data) +supplicant_connection_timeout_cb(gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(user_data); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - priv->sup_timeout_id = 0; + priv->sup_timeout_id = 0; - nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface); + nm_supplicant_interface_p2p_cancel_connect(priv->mgmt_iface); - if (nm_device_is_activating (device)) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi-p2p) connecting took too long, failing activation"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); - } + if (nm_device_is_activating(device)) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi-p2p) connecting took too long, failing activation"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); + } - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMConnection *connection; - NMSettingWifiP2P *s_wifi_p2p; - NMWifiP2PPeer *peer; - GBytes *wfd_ies; - - if (nm_clear_g_source (&priv->find_peer_timeout_id)) - nm_assert_not_reached (); - - if (!priv->mgmt_iface) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - connection = nm_device_get_applied_connection (device); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - nm_assert (NM_IS_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P))); - - /* The prepare stage ensures that the peer has been found */ - peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection); - if (!peer) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - /* Set the WFD IEs before trying to establish the connection. */ - s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P)); - wfd_ies = nm_setting_wifi_p2p_get_wfd_ies (s_wifi_p2p); - nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, wfd_ies); - - /* TODO: Grab secrets if we don't have them yet! */ - - /* TODO: Fix "pbc" being hardcoded here! */ - nm_supplicant_interface_p2p_connect (priv->mgmt_iface, - nm_wifi_p2p_peer_get_supplicant_path (peer), - "pbc", - NULL); - - /* Set up a timeout on the connect attempt */ - if (priv->sup_timeout_id == 0) { - priv->sup_timeout_id = g_timeout_add_seconds (45, - supplicant_connection_timeout_cb, - self); - } - - /* We'll get stage3 started when the P2P group has been started */ - return NM_ACT_STAGE_RETURN_POSTPONE; + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMConnection * connection; + NMSettingWifiP2P * s_wifi_p2p; + NMWifiP2PPeer * peer; + GBytes * wfd_ies; + + if (nm_clear_g_source(&priv->find_peer_timeout_id)) + nm_assert_not_reached(); + + if (!priv->mgmt_iface) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + connection = nm_device_get_applied_connection(device); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + nm_assert( + NM_IS_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P))); + + /* The prepare stage ensures that the peer has been found */ + peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection); + if (!peer) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PEER_NOT_FOUND); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + /* Set the WFD IEs before trying to establish the connection. */ + s_wifi_p2p = + NM_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)); + wfd_ies = nm_setting_wifi_p2p_get_wfd_ies(s_wifi_p2p); + nm_supplicant_manager_set_wfd_ies(priv->sup_mgr, wfd_ies); + + /* TODO: Grab secrets if we don't have them yet! */ + + /* TODO: Fix "pbc" being hardcoded here! */ + nm_supplicant_interface_p2p_connect(priv->mgmt_iface, + nm_wifi_p2p_peer_get_supplicant_path(peer), + "pbc", + NULL); + + /* Set up a timeout on the connect attempt */ + if (priv->sup_timeout_id == 0) { + priv->sup_timeout_id = g_timeout_add_seconds(45, supplicant_connection_timeout_cb, self); + } + + /* We'll get stage3 started when the P2P group has been started */ + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ static void -emit_signal_p2p_peer_add_remove (NMDeviceWifiP2P *device, - NMWifiP2PPeer *peer, - gboolean is_added /* or else is_removed */) +emit_signal_p2p_peer_add_remove(NMDeviceWifiP2P *device, + NMWifiP2PPeer * peer, + gboolean is_added /* or else is_removed */) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (device), - &interface_info_device_wifi_p2p, - is_added - ? &nm_signal_info_wifi_p2p_peer_added - : &nm_signal_info_wifi_p2p_peer_removed, - "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (peer))); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(device), + &interface_info_device_wifi_p2p, + is_added ? &nm_signal_info_wifi_p2p_peer_added + : &nm_signal_info_wifi_p2p_peer_removed, + "(o)", + nm_dbus_object_get_path(NM_DBUS_OBJECT(peer))); } static void -peer_add_remove (NMDeviceWifiP2P *self, - gboolean is_adding, /* or else removing */ - NMWifiP2PPeer *peer, - gboolean recheck_available_connections) +peer_add_remove(NMDeviceWifiP2P *self, + gboolean is_adding, /* or else removing */ + NMWifiP2PPeer * peer, + gboolean recheck_available_connections) { - NMDevice *device = NM_DEVICE (self); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - - if (is_adding) { - g_object_ref (peer); - peer->wifi_device = device; - c_list_link_tail (&priv->peers_lst_head, &peer->peers_lst); - nm_dbus_object_export (NM_DBUS_OBJECT (peer)); - _peer_dump (self, LOGL_DEBUG, peer, "added", 0); - - emit_signal_p2p_peer_add_remove (self, peer, TRUE); - } else { - peer->wifi_device = NULL; - c_list_unlink (&peer->peers_lst); - _peer_dump (self, LOGL_DEBUG, peer, "removed", 0); - } - - _notify (self, PROP_PEERS); - - if (!is_adding) { - emit_signal_p2p_peer_add_remove (self, peer, FALSE); - nm_dbus_object_clear_and_unexport (&peer); - } - - if (is_adding) { - /* If we are in prepare state, then we are currently runnign a find - * to search for the requested peer. */ - if (priv->find_peer_timeout_id != 0) { - NMConnection *connection; - - nm_assert (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE); - - connection = nm_device_get_applied_connection (device); - nm_assert (NM_IS_CONNECTION (connection)); - - peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection); - if (peer) { - /* A peer for the connection was found, cancel the timeout and go to configure state. */ - nm_clear_g_source (&priv->find_peer_timeout_id); - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); - } - } - - /* TODO: We may want to re-check auto-activation here, otherwise it will never work. */ - } - - update_disconnect_on_connection_peer_missing (self); + NMDevice * device = NM_DEVICE(self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + + if (is_adding) { + g_object_ref(peer); + peer->wifi_device = device; + c_list_link_tail(&priv->peers_lst_head, &peer->peers_lst); + nm_dbus_object_export(NM_DBUS_OBJECT(peer)); + _peer_dump(self, LOGL_DEBUG, peer, "added", 0); + + emit_signal_p2p_peer_add_remove(self, peer, TRUE); + } else { + peer->wifi_device = NULL; + c_list_unlink(&peer->peers_lst); + _peer_dump(self, LOGL_DEBUG, peer, "removed", 0); + } + + _notify(self, PROP_PEERS); + + if (!is_adding) { + emit_signal_p2p_peer_add_remove(self, peer, FALSE); + nm_dbus_object_clear_and_unexport(&peer); + } + + if (is_adding) { + /* If we are in prepare state, then we are currently runnign a find + * to search for the requested peer. */ + if (priv->find_peer_timeout_id != 0) { + NMConnection *connection; + + nm_assert(nm_device_get_state(device) == NM_DEVICE_STATE_PREPARE); + + connection = nm_device_get_applied_connection(device); + nm_assert(NM_IS_CONNECTION(connection)); + + peer = nm_wifi_p2p_peers_find_first_compatible(&priv->peers_lst_head, connection); + if (peer) { + /* A peer for the connection was found, cancel the timeout and go to configure state. */ + nm_clear_g_source(&priv->find_peer_timeout_id); + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); + } + } + + /* TODO: We may want to re-check auto-activation here, otherwise it will never work. */ + } + + update_disconnect_on_connection_peer_missing(self); } static void -remove_all_peers (NMDeviceWifiP2P *self) +remove_all_peers(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMWifiP2PPeer *peer; + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMWifiP2PPeer * peer; - if (c_list_is_empty (&priv->peers_lst_head)) - return; + if (c_list_is_empty(&priv->peers_lst_head)) + return; - while ((peer = c_list_first_entry (&priv->peers_lst_head, NMWifiP2PPeer, peers_lst))) - peer_add_remove (self, FALSE, peer, FALSE); + while ((peer = c_list_first_entry(&priv->peers_lst_head, NMWifiP2PPeer, peers_lst))) + peer_add_remove(self, FALSE, peer, FALSE); - nm_device_recheck_available_connections (NM_DEVICE (self)); + nm_device_recheck_available_connections(NM_DEVICE(self)); } /*****************************************************************************/ - static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - gboolean indicate_addressing_running; - NMConnection *connection; - const char *method; + gboolean indicate_addressing_running; + NMConnection *connection; + const char * method; - connection = nm_device_get_applied_connection (device); + connection = nm_device_get_applied_connection(device); - method = nm_utils_get_ip_config_method (connection, addr_family); + method = nm_utils_get_ip_config_method(connection, addr_family); - if (addr_family == AF_INET) - indicate_addressing_running = NM_IN_STRSET (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - else { - indicate_addressing_running = NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_DHCP); - } + if (addr_family == AF_INET) + indicate_addressing_running = NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + else { + indicate_addressing_running = NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP); + } - if (indicate_addressing_running) - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), TRUE); + if (indicate_addressing_running) + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + TRUE); - return NM_DEVICE_CLASS (nm_device_wifi_p2p_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_wifi_p2p_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - int ifindex = nm_device_get_ip_ifindex (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + int ifindex = nm_device_get_ip_ifindex(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - nm_clear_g_source (&priv->find_peer_timeout_id); - nm_clear_g_source (&priv->sup_timeout_id); - nm_clear_g_source (&priv->peer_missing_id); + nm_clear_g_source(&priv->find_peer_timeout_id); + nm_clear_g_source(&priv->sup_timeout_id); + nm_clear_g_source(&priv->peer_missing_id); - if (priv->mgmt_iface) - nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface); + if (priv->mgmt_iface) + nm_supplicant_interface_p2p_cancel_connect(priv->mgmt_iface); - if (priv->group_iface) - nm_supplicant_interface_p2p_disconnect (priv->group_iface); + if (priv->group_iface) + nm_supplicant_interface_p2p_disconnect(priv->group_iface); - /* Clear any critical protocol notification in the Wi-Fi stack */ - if (ifindex > 0) - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE); + /* Clear any critical protocol notification in the Wi-Fi stack */ + if (ifindex > 0) + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + ifindex, + FALSE); } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - *out_source = NM_DEVICE_MTU_SOURCE_NONE; - return 0; + *out_source = NM_DEVICE_MTU_SOURCE_NONE; + return 0; } static const char * -get_auto_ip_config_method (NMDevice *device, int addr_family) +get_auto_ip_config_method(NMDevice *device, int addr_family) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - /* Override the AUTO method to mean shared if we are group owner. */ - if ( priv->group_iface - && nm_supplicant_interface_get_p2p_group_owner (priv->group_iface)) { - if (addr_family == AF_INET) - return NM_SETTING_IP4_CONFIG_METHOD_SHARED; + /* Override the AUTO method to mean shared if we are group owner. */ + if (priv->group_iface && nm_supplicant_interface_get_p2p_group_owner(priv->group_iface)) { + if (addr_family == AF_INET) + return NM_SETTING_IP4_CONFIG_METHOD_SHARED; - if (addr_family == AF_INET6) - return NM_SETTING_IP6_CONFIG_METHOD_SHARED; - } + if (addr_family == AF_INET6) + return NM_SETTING_IP6_CONFIG_METHOD_SHARED; + } - return NULL; + return NULL; } static gboolean -unmanaged_on_quit (NMDevice *self) +unmanaged_on_quit(NMDevice *self) { - return TRUE; + return TRUE; } static void -supplicant_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data) +supplicant_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); - NMDevice *device = NM_DEVICE (self); - NMSupplicantInterfaceState new_state = new_state_i; - NMSupplicantInterfaceState old_state = old_state_i; - - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "supplicant management interface state: %s -> %s", - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); - - if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { - supplicant_interfaces_release (self, TRUE); - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return; - } - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - _LOGD (LOGD_WIFI, "supplicant ready"); - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - _set_is_waiting_for_supplicant (self, FALSE); - } + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(user_data); + NMDevice * device = NM_DEVICE(self); + NMSupplicantInterfaceState new_state = new_state_i; + NMSupplicantInterfaceState old_state = old_state_i; + + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "supplicant management interface state: %s -> %s", + nm_supplicant_interface_state_to_string(old_state), + nm_supplicant_interface_state_to_string(new_state)); + + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + supplicant_interfaces_release(self, TRUE); + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return; + } + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + _LOGD(LOGD_WIFI, "supplicant ready"); + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + _set_is_waiting_for_supplicant(self, FALSE); + } } static void -supplicant_iface_peer_changed_cb (NMSupplicantInterface *iface, - NMSupplicantPeerInfo *peer_info, - gboolean is_present, - NMDeviceWifiP2P *self) +supplicant_iface_peer_changed_cb(NMSupplicantInterface *iface, + NMSupplicantPeerInfo * peer_info, + gboolean is_present, + NMDeviceWifiP2P * self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - NMWifiP2PPeer *found_peer; + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + NMWifiP2PPeer * found_peer; - found_peer = nm_wifi_p2p_peers_find_by_supplicant_path (&priv->peers_lst_head, peer_info->peer_path->str); + found_peer = + nm_wifi_p2p_peers_find_by_supplicant_path(&priv->peers_lst_head, peer_info->peer_path->str); - if (!is_present) { - if (!found_peer) - return; + if (!is_present) { + if (!found_peer) + return; - peer_add_remove (self, FALSE, found_peer, TRUE); - goto out; - } + peer_add_remove(self, FALSE, found_peer, TRUE); + goto out; + } - if (found_peer) { - if (!nm_wifi_p2p_peer_update_from_properties (found_peer, peer_info)) - return; + if (found_peer) { + if (!nm_wifi_p2p_peer_update_from_properties(found_peer, peer_info)) + return; - update_disconnect_on_connection_peer_missing (self); - _peer_dump (self, LOGL_DEBUG, found_peer, "updated", 0); - } else { - gs_unref_object NMWifiP2PPeer *peer = NULL; + update_disconnect_on_connection_peer_missing(self); + _peer_dump(self, LOGL_DEBUG, found_peer, "updated", 0); + } else { + gs_unref_object NMWifiP2PPeer *peer = NULL; - peer = nm_wifi_p2p_peer_new_from_properties (peer_info); - peer_add_remove (self, TRUE, peer, TRUE); - } + peer = nm_wifi_p2p_peer_new_from_properties(peer_info); + peer_add_remove(self, TRUE, peer, TRUE); + } out: - schedule_peer_list_dump (self); + schedule_peer_list_dump(self); } static void -check_group_iface_ready (NMDeviceWifiP2P *self) +check_group_iface_ready(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);; + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if (!priv->group_iface) - return; + if (!priv->group_iface) + return; - if (!nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (priv->group_iface))) - return; + if (!nm_supplicant_interface_state_is_operational( + nm_supplicant_interface_get_state(priv->group_iface))) + return; - if (!nm_supplicant_interface_get_p2p_group_joined (priv->group_iface)) - return; + if (!nm_supplicant_interface_get_p2p_group_joined(priv->group_iface)) + return; - nm_clear_g_source (&priv->sup_timeout_id); - update_disconnect_on_connection_peer_missing (self); + nm_clear_g_source(&priv->sup_timeout_id); + update_disconnect_on_connection_peer_missing(self); - nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self)); + nm_device_activate_schedule_stage3_ip_config_start(NM_DEVICE(self)); } static void -supplicant_group_iface_is_ready (NMDeviceWifiP2P *self) +supplicant_group_iface_is_ready(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - _LOGD (LOGD_WIFI, "P2P Group supplicant ready"); + _LOGD(LOGD_WIFI, "P2P Group supplicant ready"); - if (!nm_device_set_ip_iface (NM_DEVICE (self), nm_supplicant_interface_get_ifname (priv->group_iface))) { - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - return; - } + if (!nm_device_set_ip_iface(NM_DEVICE(self), + nm_supplicant_interface_get_ifname(priv->group_iface))) { + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + return; + } - _set_is_waiting_for_supplicant (self, FALSE); - check_group_iface_ready (self); + _set_is_waiting_for_supplicant(self, FALSE); + check_group_iface_ready(self); } static void -supplicant_group_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data) +supplicant_group_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); - NMSupplicantInterfaceState new_state = new_state_i; - NMSupplicantInterfaceState old_state = old_state_i; - - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "P2P Group supplicant interface state: %s -> %s", - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); - - if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { - supplicant_group_interface_release (self); - - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - return; - } - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - supplicant_group_iface_is_ready (self); - return; - } + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(user_data); + NMSupplicantInterfaceState new_state = new_state_i; + NMSupplicantInterfaceState old_state = old_state_i; + + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "P2P Group supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string(old_state), + nm_supplicant_interface_state_to_string(new_state)); + + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + supplicant_group_interface_release(self); + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + return; + } + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + supplicant_group_iface_is_ready(self); + return; + } } static void -supplicant_group_iface_group_finished_cb (NMSupplicantInterface *iface, - const char *iface_path, - void *user_data) +supplicant_group_iface_group_finished_cb(NMSupplicantInterface *iface, + const char * iface_path, + void * user_data) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); + NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P(user_data); - supplicant_group_interface_release (self); + supplicant_group_interface_release(self); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); } static void -supplicant_iface_group_joined_updated_cb (NMSupplicantInterface *iface, - GParamSpec *pspec, - void *user_data) +supplicant_iface_group_joined_updated_cb(NMSupplicantInterface *iface, + GParamSpec * pspec, + void * user_data) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); + NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P(user_data); - check_group_iface_ready (self); + check_group_iface_ready(self); } static void -supplicant_iface_group_started_cb (NMSupplicantInterface *iface, - NMSupplicantInterface *group_iface, - NMDeviceWifiP2P *self) +supplicant_iface_group_started_cb(NMSupplicantInterface *iface, + NMSupplicantInterface *group_iface, + NMDeviceWifiP2P * self) { - NMDeviceWifiP2PPrivate *priv; - NMSupplicantInterfaceState state; + NMDeviceWifiP2PPrivate * priv; + NMSupplicantInterfaceState state; - g_return_if_fail (self); + g_return_if_fail(self); - if (!nm_device_is_activating (NM_DEVICE (self))) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant notified a group start but we are not trying to connect! Ignoring the event."); - return; - } + if (!nm_device_is_activating(NM_DEVICE(self))) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "P2P: WPA supplicant notified a group start but we are not trying to connect! " + "Ignoring the event."); + return; + } - priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - supplicant_group_interface_release (self); + supplicant_group_interface_release(self); - priv->group_iface = g_object_ref (group_iface); + priv->group_iface = g_object_ref(group_iface); - /* We need to wait for the interface to be ready and the group - * information to be resolved. */ - g_signal_connect (priv->group_iface, - "notify::" NM_SUPPLICANT_INTERFACE_P2P_GROUP_JOINED, - G_CALLBACK (supplicant_iface_group_joined_updated_cb), - self); + /* We need to wait for the interface to be ready and the group + * information to be resolved. */ + g_signal_connect(priv->group_iface, + "notify::" NM_SUPPLICANT_INTERFACE_P2P_GROUP_JOINED, + G_CALLBACK(supplicant_iface_group_joined_updated_cb), + self); - g_signal_connect (priv->group_iface, - NM_SUPPLICANT_INTERFACE_STATE, - G_CALLBACK (supplicant_group_iface_state_cb), - self); + g_signal_connect(priv->group_iface, + NM_SUPPLICANT_INTERFACE_STATE, + G_CALLBACK(supplicant_group_iface_state_cb), + self); - g_signal_connect (priv->group_iface, NM_SUPPLICANT_INTERFACE_GROUP_FINISHED, - G_CALLBACK (supplicant_group_iface_group_finished_cb), - self); + g_signal_connect(priv->group_iface, + NM_SUPPLICANT_INTERFACE_GROUP_FINISHED, + G_CALLBACK(supplicant_group_iface_group_finished_cb), + self); - state = nm_supplicant_interface_get_state (priv->group_iface); - if (state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - _set_is_waiting_for_supplicant (self, TRUE); - return; - } + state = nm_supplicant_interface_get_state(priv->group_iface); + if (state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + _set_is_waiting_for_supplicant(self, TRUE); + return; + } - supplicant_group_iface_is_ready (self); + supplicant_group_iface_is_ready(self); } static void -supplicant_group_interface_release (NMDeviceWifiP2P *self) +supplicant_group_interface_release(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if (!priv->group_iface) - return; + if (!priv->group_iface) + return; - g_signal_handlers_disconnect_by_data (priv->group_iface, self); + g_signal_handlers_disconnect_by_data(priv->group_iface, self); - nm_supplicant_interface_p2p_disconnect (priv->group_iface); + nm_supplicant_interface_p2p_disconnect(priv->group_iface); - g_clear_object (&priv->group_iface); + g_clear_object(&priv->group_iface); } static void -supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting) +supplicant_interfaces_release(NMDeviceWifiP2P *self, gboolean set_is_waiting) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - nm_clear_g_source (&priv->peer_dump_id); + nm_clear_g_source(&priv->peer_dump_id); - remove_all_peers (self); + remove_all_peers(self); - if (priv->mgmt_iface) { - _LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface."); - nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL); - g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self); - g_clear_object (&priv->mgmt_iface); - nm_clear_g_source (&priv->find_peer_timeout_id); - nm_clear_g_source (&priv->sup_timeout_id); - } + if (priv->mgmt_iface) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface."); + nm_supplicant_manager_set_wfd_ies(priv->sup_mgr, NULL); + g_signal_handlers_disconnect_by_data(priv->mgmt_iface, self); + g_clear_object(&priv->mgmt_iface); + nm_clear_g_source(&priv->find_peer_timeout_id); + nm_clear_g_source(&priv->sup_timeout_id); + } - supplicant_group_interface_release (self); + supplicant_group_interface_release(self); - if (set_is_waiting) - _set_is_waiting_for_supplicant (self, TRUE); + if (set_is_waiting) + _set_is_waiting_for_supplicant(self, TRUE); } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - - update_disconnect_on_connection_peer_missing (self); - - if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) { - /* Clean up the supplicant interface because in these states the - * device cannot be used. - * Do not clean up for the UNMANAGED to UNAVAILABLE transition which - * will happen during initialization. - */ - if (priv->mgmt_iface && old_state > new_state) - supplicant_interfaces_release (self, TRUE); - - /* TODO: More cleanup needed? */ - } - - switch (new_state) { - case NM_DEVICE_STATE_UNMANAGED: - break; - case NM_DEVICE_STATE_UNAVAILABLE: - if ( !priv->mgmt_iface - || !nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (priv->mgmt_iface))) - _set_is_waiting_for_supplicant (self, TRUE); - break; - case NM_DEVICE_STATE_NEED_AUTH: - /* Disconnect? */ - break; - case NM_DEVICE_STATE_IP_CHECK: - /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), FALSE); - break; - case NM_DEVICE_STATE_ACTIVATED: - //activation_success_handler (device); - break; - case NM_DEVICE_STATE_FAILED: - /* Clear any critical protocol notification in the wifi stack. - * At this point the IP device may have been removed already. */ - nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL); - if (nm_device_get_ip_ifindex (device) > 0) - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), FALSE); - break; - case NM_DEVICE_STATE_DISCONNECTED: - nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL); - break; - default: - break; - } + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + + update_disconnect_on_connection_peer_missing(self); + + if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) { + /* Clean up the supplicant interface because in these states the + * device cannot be used. + * Do not clean up for the UNMANAGED to UNAVAILABLE transition which + * will happen during initialization. + */ + if (priv->mgmt_iface && old_state > new_state) + supplicant_interfaces_release(self, TRUE); + + /* TODO: More cleanup needed? */ + } + + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + break; + case NM_DEVICE_STATE_UNAVAILABLE: + if (!priv->mgmt_iface + || !nm_supplicant_interface_state_is_operational( + nm_supplicant_interface_get_state(priv->mgmt_iface))) + _set_is_waiting_for_supplicant(self, TRUE); + break; + case NM_DEVICE_STATE_NEED_AUTH: + /* Disconnect? */ + break; + case NM_DEVICE_STATE_IP_CHECK: + /* Clear any critical protocol notification in the wifi stack */ + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + FALSE); + break; + case NM_DEVICE_STATE_ACTIVATED: + //activation_success_handler (device); + break; + case NM_DEVICE_STATE_FAILED: + /* Clear any critical protocol notification in the wifi stack. + * At this point the IP device may have been removed already. */ + nm_supplicant_manager_set_wfd_ies(priv->sup_mgr, NULL); + if (nm_device_get_ip_ifindex(device) > 0) + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + FALSE); + break; + case NM_DEVICE_STATE_DISCONNECTED: + nm_supplicant_manager_set_wfd_ies(priv->sup_mgr, NULL); + break; + default: + break; + } } static void -impl_device_wifi_p2p_start_find (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_device_wifi_p2p_start_find(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (obj); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - gs_unref_variant GVariant *options = NULL; - const char *opts_key; - GVariant *opts_val; - GVariantIter iter; - gint32 timeout = 30; - - g_variant_get (parameters, "(@a{sv})", &options); - - g_variant_iter_init (&iter, options); - while (g_variant_iter_next (&iter, "{&sv}", &opts_key, &opts_val)) { - _nm_unused gs_unref_variant GVariant *opts_val_free = opts_val; - - if (nm_streq (opts_key, "timeout")) { - if (!g_variant_is_of_type (opts_val, G_VARIANT_TYPE_INT32)) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "\"timeout\" must be an integer \"i\""); - return; - } - - timeout = g_variant_get_int32 (opts_val); - if (timeout <= 0 || timeout > 600) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "The timeout for a find operation needs to be in the range of 1-600s."); - return; - } - - continue; - } - - g_dbus_method_invocation_return_error (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "Unsupported options key \"%s\"", - opts_key); - return; - } - - if (!priv->mgmt_iface) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "WPA Supplicant management interface is currently unavailable."); - return; - } - - nm_supplicant_interface_p2p_start_find (priv->mgmt_iface, timeout); - - g_dbus_method_invocation_return_value (invocation, NULL); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(obj); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + gs_unref_variant GVariant *options = NULL; + const char * opts_key; + GVariant * opts_val; + GVariantIter iter; + gint32 timeout = 30; + + g_variant_get(parameters, "(@a{sv})", &options); + + g_variant_iter_init(&iter, options); + while (g_variant_iter_next(&iter, "{&sv}", &opts_key, &opts_val)) { + _nm_unused gs_unref_variant GVariant *opts_val_free = opts_val; + + if (nm_streq(opts_key, "timeout")) { + if (!g_variant_is_of_type(opts_val, G_VARIANT_TYPE_INT32)) { + g_dbus_method_invocation_return_error_literal( + invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "\"timeout\" must be an integer \"i\""); + return; + } + + timeout = g_variant_get_int32(opts_val); + if (timeout <= 0 || timeout > 600) { + g_dbus_method_invocation_return_error_literal( + invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "The timeout for a find operation needs to be in the range of 1-600s."); + return; + } + + continue; + } + + g_dbus_method_invocation_return_error(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "Unsupported options key \"%s\"", + opts_key); + return; + } + + if (!priv->mgmt_iface) { + g_dbus_method_invocation_return_error_literal( + invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "WPA Supplicant management interface is currently unavailable."); + return; + } + + nm_supplicant_interface_p2p_start_find(priv->mgmt_iface, timeout); + + g_dbus_method_invocation_return_value(invocation, NULL); } static void -impl_device_wifi_p2p_stop_find (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_device_wifi_p2p_stop_find(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (obj); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(obj); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if (!priv->mgmt_iface) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "WPA Supplicant management interface is currently unavailable."); - return; - } + if (!priv->mgmt_iface) { + g_dbus_method_invocation_return_error_literal( + invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "WPA Supplicant management interface is currently unavailable."); + return; + } - nm_supplicant_interface_p2p_stop_find (priv->mgmt_iface); + nm_supplicant_interface_p2p_stop_find(priv->mgmt_iface); - g_dbus_method_invocation_return_value (invocation, NULL); + g_dbus_method_invocation_return_value(invocation, NULL); } /*****************************************************************************/ NMSupplicantInterface * -nm_device_wifi_p2p_get_mgmt_iface (NMDeviceWifiP2P *self) +nm_device_wifi_p2p_get_mgmt_iface(NMDeviceWifiP2P *self) { - g_return_val_if_fail (NM_IS_DEVICE_WIFI_P2P (self), NULL); + g_return_val_if_fail(NM_IS_DEVICE_WIFI_P2P(self), NULL); - return NM_DEVICE_WIFI_P2P_GET_PRIVATE (self)->mgmt_iface; + return NM_DEVICE_WIFI_P2P_GET_PRIVATE(self)->mgmt_iface; } void -nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self, - NMSupplicantInterface *iface) +nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self, NMSupplicantInterface *iface) { - NMDeviceWifiP2PPrivate *priv; + NMDeviceWifiP2PPrivate *priv; - g_return_if_fail (NM_IS_DEVICE_WIFI_P2P (self)); - g_return_if_fail (!iface || NM_IS_SUPPLICANT_INTERFACE (iface)); + g_return_if_fail(NM_IS_DEVICE_WIFI_P2P(self)); + g_return_if_fail(!iface || NM_IS_SUPPLICANT_INTERFACE(iface)); - priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - if (priv->mgmt_iface == iface) - goto done; + if (priv->mgmt_iface == iface) + goto done; - supplicant_interfaces_release (self, FALSE); + supplicant_interfaces_release(self, FALSE); - if (!iface) - goto done; + if (!iface) + goto done; - _LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface changed to %s.", - nm_ref_string_get_str (nm_supplicant_interface_get_object_path (iface))); + _LOGD(LOGD_DEVICE | LOGD_WIFI, + "P2P: WPA supplicant management interface changed to %s.", + nm_ref_string_get_str(nm_supplicant_interface_get_object_path(iface))); - priv->mgmt_iface = g_object_ref (iface); + priv->mgmt_iface = g_object_ref(iface); - g_signal_connect (priv->mgmt_iface, - NM_SUPPLICANT_INTERFACE_STATE, - G_CALLBACK (supplicant_iface_state_cb), - self); - g_signal_connect (priv->mgmt_iface, - NM_SUPPLICANT_INTERFACE_PEER_CHANGED, - G_CALLBACK (supplicant_iface_peer_changed_cb), - self); - g_signal_connect (priv->mgmt_iface, - NM_SUPPLICANT_INTERFACE_GROUP_STARTED, - G_CALLBACK (supplicant_iface_group_started_cb), - self); + g_signal_connect(priv->mgmt_iface, + NM_SUPPLICANT_INTERFACE_STATE, + G_CALLBACK(supplicant_iface_state_cb), + self); + g_signal_connect(priv->mgmt_iface, + NM_SUPPLICANT_INTERFACE_PEER_CHANGED, + G_CALLBACK(supplicant_iface_peer_changed_cb), + self); + g_signal_connect(priv->mgmt_iface, + NM_SUPPLICANT_INTERFACE_GROUP_STARTED, + G_CALLBACK(supplicant_iface_group_started_cb), + self); done: - nm_device_queue_recheck_available (NM_DEVICE (self), - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - _set_is_waiting_for_supplicant (self, - !priv->mgmt_iface - || !nm_supplicant_interface_state_is_operational (nm_supplicant_interface_get_state (priv->mgmt_iface))); + nm_device_queue_recheck_available(NM_DEVICE(self), + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + _set_is_waiting_for_supplicant(self, + !priv->mgmt_iface + || !nm_supplicant_interface_state_is_operational( + nm_supplicant_interface_get_state(priv->mgmt_iface))); } void -nm_device_wifi_p2p_remove (NMDeviceWifiP2P* self) +nm_device_wifi_p2p_remove(NMDeviceWifiP2P *self) { - g_signal_emit_by_name (self, NM_DEVICE_REMOVED); + g_signal_emit_by_name(self, NM_DEVICE_REMOVED); } /*****************************************************************************/ static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - return "wifi-p2p"; + return "wifi-p2p"; } /*****************************************************************************/ -static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "PeerAdded", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("peer", "o"), - ), -); +static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "PeerAdded", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("peer", "o"), ), ); -static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "PeerRemoved", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("peer", "o"), - ), -); +static const GDBusSignalInfo nm_signal_info_wifi_p2p_peer_removed = + NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "PeerRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("peer", "o"), ), ); static const NMDBusInterfaceInfoExtended interface_info_device_wifi_p2p = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "StartFind", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("options", "a{sv}"), - ), - ), - .handle = impl_device_wifi_p2p_start_find, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "StopFind", - ), - .handle = impl_device_wifi_p2p_stop_find, - ), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_wifi_p2p_peer_added, - &nm_signal_info_wifi_p2p_peer_removed, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Peers", "ao", NM_DEVICE_WIFI_P2P_PEERS), - ), - ), - .legacy_property_changed = FALSE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "StartFind", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("options", "a{sv}"), ), ), + .handle = impl_device_wifi_p2p_start_find, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(NM_DEFINE_GDBUS_METHOD_INFO_INIT("StopFind", ), + .handle = impl_device_wifi_p2p_stop_find, ), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_wifi_p2p_peer_added, + &nm_signal_info_wifi_p2p_peer_removed, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Peers", + "ao", + NM_DEVICE_WIFI_P2P_PEERS), ), ), + .legacy_property_changed = FALSE, }; /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (object); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - const char **list; - - switch (prop_id) { - case PROP_PEERS: - list = nm_wifi_p2p_peers_get_paths (&priv->peers_lst_head); - g_value_take_boxed (value, nm_utils_strv_make_deep_copied (list)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(object); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + const char ** list; + + switch (prop_id) { + case PROP_PEERS: + list = nm_wifi_p2p_peers_get_paths(&priv->peers_lst_head); + g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_wifi_p2p_init (NMDeviceWifiP2P * self) +nm_device_wifi_p2p_init(NMDeviceWifiP2P *self) { - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); - c_list_init (&priv->peers_lst_head); + c_list_init(&priv->peers_lst_head); - priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ()); + priv->sup_mgr = g_object_ref(nm_supplicant_manager_get()); } static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (object); + NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P(object); - G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_device_wifi_p2p_parent_class)->constructed(object); - _set_is_waiting_for_supplicant (self, TRUE); + _set_is_waiting_for_supplicant(self, TRUE); } NMDeviceWifiP2P * -nm_device_wifi_p2p_new (const char *iface) +nm_device_wifi_p2p_new(const char *iface) { - return g_object_new (NM_TYPE_DEVICE_WIFI_P2P, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "802.11 Wi-Fi P2P", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI_P2P, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI, - NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN, - NULL); + return g_object_new(NM_TYPE_DEVICE_WIFI_P2P, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "802.11 Wi-Fi P2P", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_WIFI_P2P, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_WIFI, + NM_DEVICE_RFKILL_TYPE, + RFKILL_TYPE_WLAN, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (object); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (object); + NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(object); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(object); - g_clear_object (&priv->sup_mgr); + g_clear_object(&priv->sup_mgr); - supplicant_interfaces_release (self, FALSE); + supplicant_interfaces_release(self, FALSE); - G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_wifi_p2p_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDeviceWifiP2P *peer = NM_DEVICE_WIFI_P2P (object); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (peer); + NMDeviceWifiP2P * peer = NM_DEVICE_WIFI_P2P(object); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(peer); - nm_assert (c_list_is_empty (&priv->peers_lst_head)); + nm_assert(c_list_is_empty(&priv->peers_lst_head)); - G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_device_wifi_p2p_parent_class)->finalize(object); } static void -nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *klass) +nm_device_wifi_p2p_class_init(NMDeviceWifiP2PClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->dispose = dispose; - object_class->finalize = finalize; + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wifi_p2p); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_wifi_p2p); - device_class->connection_type_supported = NM_SETTING_WIFI_P2P_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIFI_P2P_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIFI_P2P); - device_class->get_type_description = get_type_description; + device_class->connection_type_supported = NM_SETTING_WIFI_P2P_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_WIFI_P2P_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_WIFI_P2P); + device_class->get_type_description = get_type_description; - /* Do we need compatibility checking or is the default good enough? */ - device_class->is_available = is_available; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; + /* Do we need compatibility checking or is the default good enough? */ + device_class->is_available = is_available; + device_class->check_connection_compatible = check_connection_compatible; + device_class->complete_connection = complete_connection; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->get_configured_mtu = get_configured_mtu; - device_class->get_auto_ip_config_method = get_auto_ip_config_method; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->get_configured_mtu = get_configured_mtu; + device_class->get_auto_ip_config_method = get_auto_ip_config_method; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->deactivate = deactivate; - device_class->unmanaged_on_quit = unmanaged_on_quit; + device_class->deactivate = deactivate; + device_class->unmanaged_on_quit = unmanaged_on_quit; - device_class->state_changed = device_state_changed; + device_class->state_changed = device_state_changed; - obj_properties[PROP_PEERS] = - g_param_spec_boxed (NM_DEVICE_WIFI_P2P_PEERS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PEERS] = g_param_spec_boxed(NM_DEVICE_WIFI_P2P_PEERS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/wifi/nm-device-wifi-p2p.h b/src/devices/wifi/nm-device-wifi-p2p.h index df25ec65..03e49311 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.h +++ b/src/devices/wifi/nm-device-wifi-p2p.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -9,27 +9,30 @@ #include "devices/nm-device.h" #include "supplicant/nm-supplicant-interface.h" -#define NM_TYPE_DEVICE_WIFI_P2P (nm_device_wifi_p2p_get_type ()) -#define NM_DEVICE_WIFI_P2P(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2P)) -#define NM_DEVICE_WIFI_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) -#define NM_IS_DEVICE_WIFI_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIFI_P2P)) -#define NM_IS_DEVICE_WIFI_P2P_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI_P2P)) -#define NM_DEVICE_WIFI_P2P_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) - -#define NM_DEVICE_WIFI_P2P_PEERS "peers" -#define NM_DEVICE_WIFI_P2P_GROUPS "groups" - -typedef struct _NMDeviceWifiP2P NMDeviceWifiP2P; +#define NM_TYPE_DEVICE_WIFI_P2P (nm_device_wifi_p2p_get_type()) +#define NM_DEVICE_WIFI_P2P(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2P)) +#define NM_DEVICE_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) +#define NM_IS_DEVICE_WIFI_P2P(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIFI_P2P)) +#define NM_IS_DEVICE_WIFI_P2P_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIFI_P2P)) +#define NM_DEVICE_WIFI_P2P_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIFI_P2P, NMDeviceWifiP2PClass)) + +#define NM_DEVICE_WIFI_P2P_PEERS "peers" +#define NM_DEVICE_WIFI_P2P_GROUPS "groups" + +typedef struct _NMDeviceWifiP2P NMDeviceWifiP2P; typedef struct _NMDeviceWifiP2PClass NMDeviceWifiP2PClass; -GType nm_device_wifi_p2p_get_type (void); +GType nm_device_wifi_p2p_get_type(void); -NMDeviceWifiP2P *nm_device_wifi_p2p_new (const char *iface); +NMDeviceWifiP2P *nm_device_wifi_p2p_new(const char *iface); -NMSupplicantInterface * nm_device_wifi_p2p_get_mgmt_iface (NMDeviceWifiP2P *self); -void nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self, - NMSupplicantInterface *iface); +NMSupplicantInterface *nm_device_wifi_p2p_get_mgmt_iface(NMDeviceWifiP2P *self); +void nm_device_wifi_p2p_set_mgmt_iface(NMDeviceWifiP2P *self, NMSupplicantInterface *iface); -void nm_device_wifi_p2p_remove (NMDeviceWifiP2P *self); +void nm_device_wifi_p2p_remove(NMDeviceWifiP2P *self); #endif /* __NM_DEVICE_WIFI_P2P_H__ */ diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 2a342886..55062644 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2017 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -44,1786 +44,1806 @@ #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceWifi); -#define SCAN_INTERVAL_SEC_MIN 3 +#define SCAN_INTERVAL_SEC_MIN 3 #define SCAN_INTERVAL_SEC_STEP 20 -#define SCAN_INTERVAL_SEC_MAX 120 +#define SCAN_INTERVAL_SEC_MAX 120 #define SCAN_EXTRA_DELAY_MSEC 500 -#define SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC (5*60) +#define SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC (5 * 60) #define SCAN_REQUEST_SSIDS_MAX_NUM 32u #define SCAN_REQUEST_SSIDS_MAX_AGE_MSEC (3 * 60 * NM_UTILS_MSEC_PER_SEC) -#define _LOGT_scan(...) _LOGT (LOGD_WIFI_SCAN, "wifi-scan: " __VA_ARGS__) +#define _LOGT_scan(...) _LOGT(LOGD_WIFI_SCAN, "wifi-scan: " __VA_ARGS__) /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifi, - PROP_MODE, - PROP_BITRATE, - PROP_ACCESS_POINTS, - PROP_ACTIVE_ACCESS_POINT, - PROP_CAPABILITIES, - PROP_SCANNING, - PROP_LAST_SCAN, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceWifi, + PROP_MODE, + PROP_BITRATE, + PROP_ACCESS_POINTS, + PROP_ACTIVE_ACCESS_POINT, + PROP_CAPABILITIES, + PROP_SCANNING, + PROP_LAST_SCAN, ); enum { - P2P_DEVICE_CREATED, + P2P_DEVICE_CREATED, - LAST_SIGNAL + LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - CList aps_lst_head; - GHashTable *aps_idx_by_supplicant_path; + CList aps_lst_head; + GHashTable *aps_idx_by_supplicant_path; - CList scanning_prohibited_lst_head; + CList scanning_prohibited_lst_head; - GCancellable *scan_request_cancellable; + GCancellable *scan_request_cancellable; - GSource *scan_request_delay_source; + GSource *scan_request_delay_source; - NMWifiAP * current_ap; + NMWifiAP *current_ap; - GHashTable *scan_request_ssids_hash; - CList scan_request_ssids_lst_head; + GHashTable *scan_request_ssids_hash; + CList scan_request_ssids_lst_head; - NMActRequestGetSecretsCallId *wifi_secrets_id; + NMActRequestGetSecretsCallId *wifi_secrets_id; - NMSupplicantManager *sup_mgr; - NMSupplMgrCreateIfaceHandle *sup_create_handle; - NMSupplicantInterface *sup_iface; + NMSupplicantManager * sup_mgr; + NMSupplMgrCreateIfaceHandle *sup_create_handle; + NMSupplicantInterface * sup_iface; - gint64 scan_last_complete_msec; - gint64 scan_periodic_next_msec; + gint64 scan_last_complete_msec; + gint64 scan_periodic_next_msec; - gint64 scan_last_request_started_at_msec; + gint64 scan_last_request_started_at_msec; - guint scan_kickoff_timeout_id; + guint scan_kickoff_timeout_id; - guint ap_dump_id; + guint ap_dump_id; - guint periodic_update_id; + guint periodic_update_id; - guint link_timeout_id; - guint reacquire_iface_id; - guint wps_timeout_id; - guint sup_timeout_id; /* supplicant association timeout */ + guint link_timeout_id; + guint reacquire_iface_id; + guint wps_timeout_id; + guint sup_timeout_id; /* supplicant association timeout */ - NMDeviceWifiCapabilities capabilities; - NMSettingWirelessWakeOnWLan wowlan_restore; + NMDeviceWifiCapabilities capabilities; + NMSettingWirelessWakeOnWLan wowlan_restore; - NMDeviceWifiP2P *p2p_device; - NM80211Mode mode; + NMDeviceWifiP2P *p2p_device; + NM80211Mode mode; - guint32 failed_iface_count; - gint32 hw_addr_scan_expire; + guint32 failed_iface_count; + gint32 hw_addr_scan_expire; - guint32 rate; + guint32 rate; - guint8 scan_periodic_interval_sec; + guint8 scan_periodic_interval_sec; - bool enabled:1; /* rfkilled or not */ - bool scan_is_scanning:1; - bool scan_periodic_allowed:1; - bool scan_explicit_allowed:1; - bool scan_explicit_requested:1; - bool ssid_found:1; - bool hidden_probe_scan_warn:1; + bool enabled : 1; /* rfkilled or not */ + bool scan_is_scanning : 1; + bool scan_periodic_allowed : 1; + bool scan_explicit_allowed : 1; + bool scan_explicit_requested : 1; + bool ssid_found : 1; + bool hidden_probe_scan_warn : 1; } NMDeviceWifiPrivate; -struct _NMDeviceWifi -{ - NMDevice parent; - NMDeviceWifiPrivate _priv; +struct _NMDeviceWifi { + NMDevice parent; + NMDeviceWifiPrivate _priv; }; -struct _NMDeviceWifiClass -{ - NMDeviceClass parent; +struct _NMDeviceWifiClass { + NMDeviceClass parent; }; /*****************************************************************************/ -G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) -#define NM_DEVICE_WIFI_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceWifi, NM_IS_DEVICE_WIFI, NMDevice) +#define NM_DEVICE_WIFI_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceWifi, NM_IS_DEVICE_WIFI, NMDevice) /*****************************************************************************/ -static void supplicant_iface_state_down (NMDeviceWifi *self); +static void supplicant_iface_state_down(NMDeviceWifi *self); -static void cleanup_association_attempt (NMDeviceWifi * self, - gboolean disconnect); +static void cleanup_association_attempt(NMDeviceWifi *self, gboolean disconnect); -static void supplicant_iface_state (NMDeviceWifi *self, - NMSupplicantInterfaceState new_state, - NMSupplicantInterfaceState old_state, - int disconnect_reason, - gboolean is_real_signal); +static void supplicant_iface_state(NMDeviceWifi * self, + NMSupplicantInterfaceState new_state, + NMSupplicantInterfaceState old_state, + int disconnect_reason, + gboolean is_real_signal); -static void supplicant_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data); +static void supplicant_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data); -static void supplicant_iface_bss_changed_cb (NMSupplicantInterface *iface, - NMSupplicantBssInfo *bss_info, - gboolean is_present, - NMDeviceWifi *self); +static void supplicant_iface_bss_changed_cb(NMSupplicantInterface *iface, + NMSupplicantBssInfo * bss_info, + gboolean is_present, + NMDeviceWifi * self); -static void supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface, - GVariant *credentials, - NMDeviceWifi *self); +static void supplicant_iface_wps_credentials_cb(NMSupplicantInterface *iface, + GVariant * credentials, + NMDeviceWifi * self); -static void supplicant_iface_notify_current_bss (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceWifi *self); +static void supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceWifi * self); -static void supplicant_iface_notify_p2p_available (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceWifi *self); +static void supplicant_iface_notify_p2p_available(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceWifi * self); -static void periodic_update (NMDeviceWifi *self); +static void periodic_update(NMDeviceWifi *self); -static void ap_add_remove (NMDeviceWifi *self, - gboolean is_adding, - NMWifiAP *ap, - gboolean recheck_available_connections); +static void ap_add_remove(NMDeviceWifi *self, + gboolean is_adding, + NMWifiAP * ap, + gboolean recheck_available_connections); -static void _hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset); +static void _hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset); -static void recheck_p2p_availability (NMDeviceWifi *self); +static void recheck_p2p_availability(NMDeviceWifi *self); -static void _scan_kickoff (NMDeviceWifi *self); +static void _scan_kickoff(NMDeviceWifi *self); -static gboolean _scan_notify_allowed (NMDeviceWifi *self, NMTernary do_kickoff); +static gboolean _scan_notify_allowed(NMDeviceWifi *self, NMTernary do_kickoff); /*****************************************************************************/ typedef struct { - GBytes *ssid; - CList lst; - gint64 timestamp_msec; + GBytes *ssid; + CList lst; + gint64 timestamp_msec; } ScanRequestSsidData; static void -_scan_request_ssids_remove (ScanRequestSsidData *srs_data) +_scan_request_ssids_remove(ScanRequestSsidData *srs_data) { - c_list_unlink_stale (&srs_data->lst); - g_bytes_unref (srs_data->ssid); - nm_g_slice_free (srs_data); + c_list_unlink_stale(&srs_data->lst); + g_bytes_unref(srs_data->ssid); + nm_g_slice_free(srs_data); } static void -_scan_request_ssids_remove_with_hash (NMDeviceWifiPrivate *priv, - ScanRequestSsidData *srs_data) +_scan_request_ssids_remove_with_hash(NMDeviceWifiPrivate *priv, ScanRequestSsidData *srs_data) { - nm_assert (srs_data); - nm_assert (nm_g_hash_table_lookup (priv->scan_request_ssids_hash, srs_data) == srs_data); - if (!g_hash_table_remove (priv->scan_request_ssids_hash, srs_data)) - nm_assert_not_reached (); - _scan_request_ssids_remove (srs_data); + nm_assert(srs_data); + nm_assert(nm_g_hash_table_lookup(priv->scan_request_ssids_hash, srs_data) == srs_data); + if (!g_hash_table_remove(priv->scan_request_ssids_hash, srs_data)) + nm_assert_not_reached(); + _scan_request_ssids_remove(srs_data); } static void -_scan_request_ssids_remove_all (NMDeviceWifiPrivate *priv, - gint64 cutoff_with_now_msec, - guint cutoff_at_len) -{ - ScanRequestSsidData *srs_data; - - nm_assert ((!priv->scan_request_ssids_hash) == c_list_is_empty (&priv->scan_request_ssids_lst_head)); - if (!priv->scan_request_ssids_hash) - return; - - if (cutoff_at_len == 0) { - nm_clear_pointer (&priv->scan_request_ssids_hash, g_hash_table_destroy); - while ((srs_data = c_list_first_entry (&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) - _scan_request_ssids_remove (srs_data); - return; - } - - if (cutoff_with_now_msec != 0) { - gint64 cutoff_time_msec; - - /* remove all entries that are older than a max-age. */ - nm_assert (cutoff_with_now_msec > 0); - cutoff_time_msec = cutoff_with_now_msec - SCAN_REQUEST_SSIDS_MAX_AGE_MSEC; - while ((srs_data = c_list_last_entry (&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) { - if (srs_data->timestamp_msec > cutoff_time_msec) - break; - _scan_request_ssids_remove_with_hash (priv, srs_data); - } - } - - if (cutoff_at_len != G_MAXUINT) { - guint i; - - /* trim the list to cutoff_at_len elements. */ - i = nm_g_hash_table_size (priv->scan_request_ssids_hash); - for (; i > cutoff_at_len; i--) { - ScanRequestSsidData *d; - - d = c_list_last_entry (&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst); - _scan_request_ssids_remove_with_hash (priv, d); - } - } - - nm_assert (nm_g_hash_table_size (priv->scan_request_ssids_hash) <= SCAN_REQUEST_SSIDS_MAX_NUM); - nm_assert (nm_g_hash_table_size (priv->scan_request_ssids_hash) == c_list_length (&priv->scan_request_ssids_lst_head)); - if (c_list_is_empty (&priv->scan_request_ssids_lst_head)) - nm_clear_pointer (&priv->scan_request_ssids_hash, g_hash_table_destroy); +_scan_request_ssids_remove_all(NMDeviceWifiPrivate *priv, + gint64 cutoff_with_now_msec, + guint cutoff_at_len) +{ + ScanRequestSsidData *srs_data; + + nm_assert((!priv->scan_request_ssids_hash) + == c_list_is_empty(&priv->scan_request_ssids_lst_head)); + if (!priv->scan_request_ssids_hash) + return; + + if (cutoff_at_len == 0) { + nm_clear_pointer(&priv->scan_request_ssids_hash, g_hash_table_destroy); + while ( + (srs_data = + c_list_first_entry(&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) + _scan_request_ssids_remove(srs_data); + return; + } + + if (cutoff_with_now_msec != 0) { + gint64 cutoff_time_msec; + + /* remove all entries that are older than a max-age. */ + nm_assert(cutoff_with_now_msec > 0); + cutoff_time_msec = cutoff_with_now_msec - SCAN_REQUEST_SSIDS_MAX_AGE_MSEC; + while ( + (srs_data = + c_list_last_entry(&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) { + if (srs_data->timestamp_msec > cutoff_time_msec) + break; + _scan_request_ssids_remove_with_hash(priv, srs_data); + } + } + + if (cutoff_at_len != G_MAXUINT) { + guint i; + + /* trim the list to cutoff_at_len elements. */ + i = nm_g_hash_table_size(priv->scan_request_ssids_hash); + for (; i > cutoff_at_len; i--) { + ScanRequestSsidData *d; + + d = c_list_last_entry(&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst); + _scan_request_ssids_remove_with_hash(priv, d); + } + } + + nm_assert(nm_g_hash_table_size(priv->scan_request_ssids_hash) <= SCAN_REQUEST_SSIDS_MAX_NUM); + nm_assert(nm_g_hash_table_size(priv->scan_request_ssids_hash) + == c_list_length(&priv->scan_request_ssids_lst_head)); + if (c_list_is_empty(&priv->scan_request_ssids_lst_head)) + nm_clear_pointer(&priv->scan_request_ssids_hash, g_hash_table_destroy); } static GPtrArray * -_scan_request_ssids_fetch (NMDeviceWifiPrivate *priv, gint64 now_msec) +_scan_request_ssids_fetch(NMDeviceWifiPrivate *priv, gint64 now_msec) { - ScanRequestSsidData *srs_data; - GPtrArray *ssids; - guint len; + ScanRequestSsidData *srs_data; + GPtrArray * ssids; + guint len; - _scan_request_ssids_remove_all (priv, now_msec, G_MAXUINT); + _scan_request_ssids_remove_all(priv, now_msec, G_MAXUINT); - len = nm_g_hash_table_size (priv->scan_request_ssids_hash); - if (len == 0) - return NULL; + len = nm_g_hash_table_size(priv->scan_request_ssids_hash); + if (len == 0) + return NULL; - ssids = g_ptr_array_new_full (len, (GDestroyNotify) g_bytes_unref); - nm_clear_pointer (&priv->scan_request_ssids_hash, g_hash_table_destroy); - while ((srs_data = c_list_first_entry (&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) { - g_ptr_array_add (ssids, g_steal_pointer (&srs_data->ssid)); - _scan_request_ssids_remove (srs_data); - } - return ssids; + ssids = g_ptr_array_new_full(len, (GDestroyNotify) g_bytes_unref); + nm_clear_pointer(&priv->scan_request_ssids_hash, g_hash_table_destroy); + while ((srs_data = + c_list_first_entry(&priv->scan_request_ssids_lst_head, ScanRequestSsidData, lst))) { + g_ptr_array_add(ssids, g_steal_pointer(&srs_data->ssid)); + _scan_request_ssids_remove(srs_data); + } + return ssids; } static void -_scan_request_ssids_track (NMDeviceWifiPrivate *priv, - const GPtrArray *ssids) -{ - CList old_lst_head; - gint64 now_msec; - guint i; - - if ( !ssids - || ssids->len == 0) - return; - - now_msec = nm_utils_get_monotonic_timestamp_msec (); - - if (!priv->scan_request_ssids_hash) - priv->scan_request_ssids_hash = g_hash_table_new (nm_pgbytes_hash, nm_pgbytes_equal); - - /* Do a little dance. New elements shall keep their order as in @ssids, but all - * new elements should be sorted in the list preexisting elements of the list. - * First move the old elements away, and splice them back afterwards. */ - c_list_init (&old_lst_head); - c_list_splice (&old_lst_head, &priv->scan_request_ssids_lst_head); - - for (i = 0; i < ssids->len; i++) { - GBytes *ssid = ssids->pdata[i]; - ScanRequestSsidData *d; - - G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ScanRequestSsidData, ssid) == 0); - d = g_hash_table_lookup (priv->scan_request_ssids_hash, &ssid); - if (!d) { - d = g_slice_new (ScanRequestSsidData); - *d = (ScanRequestSsidData) { - .lst = C_LIST_INIT (d->lst), - .timestamp_msec = now_msec, - .ssid = g_bytes_ref (ssid), - }; - g_hash_table_add (priv->scan_request_ssids_hash, d); - } else - d->timestamp_msec = now_msec; - c_list_link_tail (&priv->scan_request_ssids_lst_head, &d->lst); - } - - c_list_splice (&priv->scan_request_ssids_lst_head, &old_lst_head); - - /* Trim the excess. After our splice with old_lst_head, the list contains the new - * elements (from @ssids) at the front (in there original order), followed by older elements. */ - _scan_request_ssids_remove_all (priv, now_msec, SCAN_REQUEST_SSIDS_MAX_NUM); +_scan_request_ssids_track(NMDeviceWifiPrivate *priv, const GPtrArray *ssids) +{ + CList old_lst_head; + gint64 now_msec; + guint i; + + if (!ssids || ssids->len == 0) + return; + + now_msec = nm_utils_get_monotonic_timestamp_msec(); + + if (!priv->scan_request_ssids_hash) + priv->scan_request_ssids_hash = g_hash_table_new(nm_pgbytes_hash, nm_pgbytes_equal); + + /* Do a little dance. New elements shall keep their order as in @ssids, but all + * new elements should be sorted in the list preexisting elements of the list. + * First move the old elements away, and splice them back afterwards. */ + c_list_init(&old_lst_head); + c_list_splice(&old_lst_head, &priv->scan_request_ssids_lst_head); + + for (i = 0; i < ssids->len; i++) { + GBytes * ssid = ssids->pdata[i]; + ScanRequestSsidData *d; + + G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(ScanRequestSsidData, ssid) == 0); + d = g_hash_table_lookup(priv->scan_request_ssids_hash, &ssid); + if (!d) { + d = g_slice_new(ScanRequestSsidData); + *d = (ScanRequestSsidData){ + .lst = C_LIST_INIT(d->lst), + .timestamp_msec = now_msec, + .ssid = g_bytes_ref(ssid), + }; + g_hash_table_add(priv->scan_request_ssids_hash, d); + } else + d->timestamp_msec = now_msec; + c_list_link_tail(&priv->scan_request_ssids_lst_head, &d->lst); + } + + c_list_splice(&priv->scan_request_ssids_lst_head, &old_lst_head); + + /* Trim the excess. After our splice with old_lst_head, the list contains the new + * elements (from @ssids) at the front (in there original order), followed by older elements. */ + _scan_request_ssids_remove_all(priv, now_msec, SCAN_REQUEST_SSIDS_MAX_NUM); } /*****************************************************************************/ void -nm_device_wifi_scanning_prohibited_track (NMDeviceWifi *self, - gpointer tag, - gboolean temporarily_prohibited) +nm_device_wifi_scanning_prohibited_track(NMDeviceWifi *self, + gpointer tag, + gboolean temporarily_prohibited) { - NMDeviceWifiPrivate *priv; - NMCListElem *elem; + NMDeviceWifiPrivate *priv; + NMCListElem * elem; - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); - nm_assert (tag); + g_return_if_fail(NM_IS_DEVICE_WIFI(self)); + nm_assert(tag); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - /* We track these with a simple CList. This would be not efficient, if - * there would be many users that need to be tracked at the same time (there - * aren't). In fact, most of the time there is no NMDeviceOlpcMesh and - * nobody tracks itself here. Optimize for that and simplicity. */ + /* We track these with a simple CList. This would be not efficient, if + * there would be many users that need to be tracked at the same time (there + * aren't). In fact, most of the time there is no NMDeviceOlpcMesh and + * nobody tracks itself here. Optimize for that and simplicity. */ - elem = nm_c_list_elem_find_first (&priv->scanning_prohibited_lst_head, - iter, - iter == tag); + elem = nm_c_list_elem_find_first(&priv->scanning_prohibited_lst_head, iter, iter == tag); - if (!temporarily_prohibited) { - if (!elem) - return; - nm_c_list_elem_free (elem); - } else { - if (elem) - return; - c_list_link_tail (&priv->scanning_prohibited_lst_head, - &nm_c_list_elem_new_stale (tag)->lst); - } + if (!temporarily_prohibited) { + if (!elem) + return; + nm_c_list_elem_free(elem); + } else { + if (elem) + return; + c_list_link_tail(&priv->scanning_prohibited_lst_head, &nm_c_list_elem_new_stale(tag)->lst); + } - _scan_notify_allowed (self, NM_TERNARY_DEFAULT); + _scan_notify_allowed(self, NM_TERNARY_DEFAULT); } /*****************************************************************************/ static void -_ap_dump (NMDeviceWifi *self, - NMLogLevel log_level, - const NMWifiAP *ap, - const char *prefix, - gint64 now_msec) +_ap_dump(NMDeviceWifi * self, + NMLogLevel log_level, + const NMWifiAP *ap, + const char * prefix, + gint64 now_msec) { - char buf[1024]; + char buf[1024]; - buf[0] = '\0'; - _NMLOG (log_level, LOGD_WIFI_SCAN, "wifi-ap: %-7s %s", - prefix, - nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_msec)); + buf[0] = '\0'; + _NMLOG(log_level, + LOGD_WIFI_SCAN, + "wifi-ap: %-7s %s", + prefix, + nm_wifi_ap_to_string(ap, buf, sizeof(buf), now_msec)); } gboolean -nm_device_wifi_get_scanning (NMDeviceWifi *self) +nm_device_wifi_get_scanning(NMDeviceWifi *self) { - g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), FALSE); + g_return_val_if_fail(NM_IS_DEVICE_WIFI(self), FALSE); - return NM_DEVICE_WIFI_GET_PRIVATE (self)->scan_is_scanning; + return NM_DEVICE_WIFI_GET_PRIVATE(self)->scan_is_scanning; } static gboolean -_scan_is_scanning_eval (NMDeviceWifiPrivate *priv) +_scan_is_scanning_eval(NMDeviceWifiPrivate *priv) { - return priv->scan_request_cancellable - || priv->scan_request_delay_source - || ( priv->sup_iface - && nm_supplicant_interface_get_scanning (priv->sup_iface)); + return priv->scan_request_cancellable || priv->scan_request_delay_source + || (priv->sup_iface && nm_supplicant_interface_get_scanning(priv->sup_iface)); } static gboolean -_scan_notify_is_scanning (NMDeviceWifi *self) +_scan_notify_is_scanning(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gboolean last_scan_changed = FALSE; - NMDeviceState state; - gboolean scanning; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gboolean last_scan_changed = FALSE; + NMDeviceState state; + gboolean scanning; - scanning = _scan_is_scanning_eval (priv); - if (scanning == priv->scan_is_scanning) - return FALSE; + scanning = _scan_is_scanning_eval(priv); + if (scanning == priv->scan_is_scanning) + return FALSE; - priv->scan_is_scanning = scanning; + priv->scan_is_scanning = scanning; - if ( !scanning - || priv->scan_last_complete_msec == 0) { - last_scan_changed = TRUE; - priv->scan_last_complete_msec = nm_utils_get_monotonic_timestamp_msec (); - } + if (!scanning || priv->scan_last_complete_msec == 0) { + last_scan_changed = TRUE; + priv->scan_last_complete_msec = nm_utils_get_monotonic_timestamp_msec(); + } - _LOGD (LOGD_WIFI, - "wifi-scan: scanning-state: %s%s", - scanning ? "scanning" : "idle", - last_scan_changed ? " (notify last-scan)" : ""); + _LOGD(LOGD_WIFI, + "wifi-scan: scanning-state: %s%s", + scanning ? "scanning" : "idle", + last_scan_changed ? " (notify last-scan)" : ""); - state = nm_device_get_state (NM_DEVICE (self)); + state = nm_device_get_state(NM_DEVICE(self)); - if (scanning) { - /* while the device is activating/activated, we don't need the pending - * action. The pending action exists to delay startup complete, while - * activating that is already achieved via other means. */ - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state > NM_DEVICE_STATE_ACTIVATED) - nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WIFI_SCAN, FALSE); - } + if (scanning) { + /* while the device is activating/activated, we don't need the pending + * action. The pending action exists to delay startup complete, while + * activating that is already achieved via other means. */ + if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_ACTIVATED) + nm_device_add_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WIFI_SCAN, FALSE); + } - nm_gobject_notify_together (self, - PROP_SCANNING, - last_scan_changed - ? PROP_LAST_SCAN - : PROP_0); + nm_gobject_notify_together(self, PROP_SCANNING, last_scan_changed ? PROP_LAST_SCAN : PROP_0); - _scan_kickoff (self); + _scan_kickoff(self); - if (!_scan_is_scanning_eval (priv)) { - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state > NM_DEVICE_STATE_ACTIVATED) - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WIFI_SCAN, FALSE); - } + if (!_scan_is_scanning_eval(priv)) { + if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_ACTIVATED) + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_remove_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WIFI_SCAN, FALSE); + } - return TRUE; + return TRUE; } static gboolean -_scan_notify_allowed (NMDeviceWifi *self, NMTernary do_kickoff) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gboolean explicit_allowed; - gboolean periodic_allowed; - NMDeviceState state; - gboolean changed = FALSE; - - state = nm_device_get_state (NM_DEVICE (self)); - - explicit_allowed = FALSE; - periodic_allowed = FALSE; - - if (!c_list_is_empty (&priv->scanning_prohibited_lst_head)) { - /* something prohibits scanning. */ - } else if (NM_IN_SET (priv->mode, NM_802_11_MODE_ADHOC, - NM_802_11_MODE_AP)) { - /* Don't scan when a an AP or Ad-Hoc connection is active as it will - * disrupt connected clients or peers. */ - } else if (NM_IN_SET (state, NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_FAILED)) { - /* Can always scan when disconnected */ - explicit_allowed = TRUE; - periodic_allowed = TRUE; - } else if (NM_IN_SET (state, NM_DEVICE_STATE_ACTIVATED)) { - /* Prohibit periodic scans when connected; we ask the supplicant to - * background scan for us, unless the connection is locked to a specific - * BSSID (in which case scanning is effectively disabled). */ - periodic_allowed = FALSE; - - /* Prohibit scans if the supplicant is busy */ - explicit_allowed = !NM_IN_SET (nm_supplicant_interface_get_state (priv->sup_iface), - NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING, - NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED, - NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE, - NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE); - } - - if ( explicit_allowed != priv->scan_explicit_allowed - || periodic_allowed != priv->scan_periodic_allowed) { - priv->scan_periodic_allowed = periodic_allowed; - priv->scan_explicit_allowed = explicit_allowed; - _LOGT_scan ("scan-periodic-allowed=%d, scan-explicit-allowed=%d", - periodic_allowed, - explicit_allowed); - changed = TRUE; - } - - if ( do_kickoff == NM_TERNARY_TRUE - || ( do_kickoff == NM_TERNARY_DEFAULT - && changed)) - _scan_kickoff (self); - - return changed; +_scan_notify_allowed(NMDeviceWifi *self, NMTernary do_kickoff) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gboolean explicit_allowed; + gboolean periodic_allowed; + NMDeviceState state; + gboolean changed = FALSE; + + state = nm_device_get_state(NM_DEVICE(self)); + + explicit_allowed = FALSE; + periodic_allowed = FALSE; + + if (!c_list_is_empty(&priv->scanning_prohibited_lst_head)) { + /* something prohibits scanning. */ + } else if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP)) { + /* Don't scan when a an AP or Ad-Hoc connection is active as it will + * disrupt connected clients or peers. */ + } else if (NM_IN_SET(state, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_FAILED)) { + /* Can always scan when disconnected */ + explicit_allowed = TRUE; + periodic_allowed = TRUE; + } else if (NM_IN_SET(state, NM_DEVICE_STATE_ACTIVATED)) { + /* Prohibit periodic scans when connected; we ask the supplicant to + * background scan for us, unless the connection is locked to a specific + * BSSID (in which case scanning is effectively disabled). */ + periodic_allowed = FALSE; + + /* Prohibit scans if the supplicant is busy */ + if (priv->sup_iface) { + explicit_allowed = !NM_IN_SET(nm_supplicant_interface_get_state(priv->sup_iface), + NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING, + NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED, + NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE, + NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE); + } else + explicit_allowed = FALSE; + } + + if (explicit_allowed != priv->scan_explicit_allowed + || periodic_allowed != priv->scan_periodic_allowed) { + priv->scan_periodic_allowed = periodic_allowed; + priv->scan_explicit_allowed = explicit_allowed; + _LOGT_scan("scan-periodic-allowed=%d, scan-explicit-allowed=%d", + periodic_allowed, + explicit_allowed); + changed = TRUE; + } + + if (do_kickoff == NM_TERNARY_TRUE || (do_kickoff == NM_TERNARY_DEFAULT && changed)) + _scan_kickoff(self); + + return changed; } static void -supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceWifi *self) +supplicant_iface_notify_scanning_cb(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceWifi * self) { - _scan_notify_is_scanning (self); + _scan_notify_is_scanning(self); } static gboolean -unmanaged_on_quit (NMDevice *self) +unmanaged_on_quit(NMDevice *self) { - /* Wi-Fi devices cannot be assumed and are always taken down. - * However, also when being disconnected, we scan and thus - * set the MAC address to a random value. - * - * We must restore the original MAC address when quitting, thus - * signal to unmanage the device. */ - return TRUE; + /* Wi-Fi devices cannot be assumed and are always taken down. + * However, also when being disconnected, we scan and thus + * set the MAC address to a random value. + * + * We must restore the original MAC address when quitting, thus + * signal to unmanage the device. */ + return TRUE; } static void -supplicant_interface_acquire_cb (NMSupplicantManager *supplicant_manager, - NMSupplMgrCreateIfaceHandle *handle, - NMSupplicantInterface *iface, - GError *error, - gpointer user_data) -{ - NMDeviceWifi *self = user_data; - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if (nm_utils_error_is_cancelled (error)) - return; - - nm_assert (priv->sup_create_handle == handle); - - priv->sup_create_handle = NULL; - - if (error) { - _LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface: %s", - error->message); - supplicant_iface_state_down (self); - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); - return; - } - - priv->sup_iface = g_object_ref (iface); - - g_signal_connect (priv->sup_iface, - NM_SUPPLICANT_INTERFACE_STATE, - G_CALLBACK (supplicant_iface_state_cb), - self); - g_signal_connect (priv->sup_iface, - NM_SUPPLICANT_INTERFACE_BSS_CHANGED, - G_CALLBACK (supplicant_iface_bss_changed_cb), - self); - g_signal_connect (priv->sup_iface, - NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS, - G_CALLBACK (supplicant_iface_wps_credentials_cb), - self); - g_signal_connect (priv->sup_iface, - "notify::"NM_SUPPLICANT_INTERFACE_SCANNING, - G_CALLBACK (supplicant_iface_notify_scanning_cb), - self); - g_signal_connect (priv->sup_iface, - "notify::" NM_SUPPLICANT_INTERFACE_CURRENT_BSS, - G_CALLBACK (supplicant_iface_notify_current_bss), - self); - g_signal_connect (priv->sup_iface, - "notify::" NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, - G_CALLBACK (supplicant_iface_notify_p2p_available), - self); - - _scan_notify_is_scanning (self); - - if (nm_supplicant_interface_get_state (priv->sup_iface) != NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - /* fake an initial state change. */ - supplicant_iface_state (user_data, - NM_SUPPLICANT_INTERFACE_STATE_STARTING, - nm_supplicant_interface_get_state (priv->sup_iface), - 0, - FALSE); - } +supplicant_interface_acquire_cb(NMSupplicantManager * supplicant_manager, + NMSupplMgrCreateIfaceHandle *handle, + NMSupplicantInterface * iface, + GError * error, + gpointer user_data) +{ + NMDeviceWifi * self = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + if (nm_utils_error_is_cancelled(error)) + return; + + nm_assert(priv->sup_create_handle == handle); + + priv->sup_create_handle = NULL; + + if (error) { + _LOGE(LOGD_WIFI, "Couldn't initialize supplicant interface: %s", error->message); + supplicant_iface_state_down(self); + nm_device_remove_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, + TRUE); + return; + } + + priv->sup_iface = g_object_ref(iface); + + g_signal_connect(priv->sup_iface, + NM_SUPPLICANT_INTERFACE_STATE, + G_CALLBACK(supplicant_iface_state_cb), + self); + g_signal_connect(priv->sup_iface, + NM_SUPPLICANT_INTERFACE_BSS_CHANGED, + G_CALLBACK(supplicant_iface_bss_changed_cb), + self); + g_signal_connect(priv->sup_iface, + NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS, + G_CALLBACK(supplicant_iface_wps_credentials_cb), + self); + g_signal_connect(priv->sup_iface, + "notify::" NM_SUPPLICANT_INTERFACE_SCANNING, + G_CALLBACK(supplicant_iface_notify_scanning_cb), + self); + g_signal_connect(priv->sup_iface, + "notify::" NM_SUPPLICANT_INTERFACE_CURRENT_BSS, + G_CALLBACK(supplicant_iface_notify_current_bss), + self); + g_signal_connect(priv->sup_iface, + "notify::" NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, + G_CALLBACK(supplicant_iface_notify_p2p_available), + self); + + _scan_notify_is_scanning(self); + + if (nm_supplicant_interface_get_state(priv->sup_iface) + != NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + /* fake an initial state change. */ + supplicant_iface_state(user_data, + NM_SUPPLICANT_INTERFACE_STATE_STARTING, + nm_supplicant_interface_get_state(priv->sup_iface), + 0, + FALSE); + } } static void -supplicant_interface_acquire (NMDeviceWifi *self) +supplicant_interface_acquire(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_assert (!priv->sup_iface); - nm_assert (!priv->sup_create_handle); + nm_assert(!priv->sup_iface); + nm_assert(!priv->sup_create_handle); - priv->sup_create_handle = nm_supplicant_manager_create_interface (priv->sup_mgr, - nm_device_get_ifindex (NM_DEVICE (self)), - NM_SUPPLICANT_DRIVER_WIRELESS, - supplicant_interface_acquire_cb, - self); - nm_device_add_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); + priv->sup_create_handle = + nm_supplicant_manager_create_interface(priv->sup_mgr, + nm_device_get_ifindex(NM_DEVICE(self)), + NM_SUPPLICANT_DRIVER_WIRELESS, + supplicant_interface_acquire_cb, + self); + nm_device_add_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); } static void -supplicant_interface_release (NMDeviceWifi *self) +supplicant_interface_release(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - if (nm_clear_pointer (&priv->sup_create_handle, nm_supplicant_manager_create_interface_cancel)) - nm_device_remove_pending_action (NM_DEVICE (self), NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); + if (nm_clear_pointer(&priv->sup_create_handle, nm_supplicant_manager_create_interface_cancel)) + nm_device_remove_pending_action(NM_DEVICE(self), + NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, + TRUE); - nm_clear_g_source (&priv->scan_kickoff_timeout_id); - nm_clear_g_source_inst (&priv->scan_request_delay_source); - nm_clear_g_cancellable (&priv->scan_request_cancellable); + nm_clear_g_source(&priv->scan_kickoff_timeout_id); + nm_clear_g_source_inst(&priv->scan_request_delay_source); + nm_clear_g_cancellable(&priv->scan_request_cancellable); - _scan_request_ssids_remove_all (priv, 0, 0); + _scan_request_ssids_remove_all(priv, 0, 0); - priv->scan_periodic_interval_sec = 0; - priv->scan_periodic_next_msec = 0; + priv->scan_periodic_interval_sec = 0; + priv->scan_periodic_next_msec = 0; - nm_clear_g_source (&priv->ap_dump_id); + nm_clear_g_source(&priv->ap_dump_id); - if (priv->sup_iface) { - /* Clear supplicant interface signal handlers */ - g_signal_handlers_disconnect_by_data (priv->sup_iface, self); + if (priv->sup_iface) { + /* Clear supplicant interface signal handlers */ + g_signal_handlers_disconnect_by_data(priv->sup_iface, self); - /* Tell the supplicant to disconnect from the current AP */ - nm_supplicant_interface_disconnect (priv->sup_iface); + /* Tell the supplicant to disconnect from the current AP */ + nm_supplicant_interface_disconnect(priv->sup_iface); - g_clear_object (&priv->sup_iface); - } + g_clear_object(&priv->sup_iface); + } - if (priv->p2p_device) { - /* Signal to P2P device to also release its reference */ - nm_device_wifi_p2p_set_mgmt_iface (priv->p2p_device, NULL); - } + if (priv->p2p_device) { + /* Signal to P2P device to also release its reference */ + nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, NULL); + } - _scan_notify_is_scanning (self); + _scan_notify_is_scanning(self); } static void -update_seen_bssids_cache (NMDeviceWifi *self, NMWifiAP *ap) +update_seen_bssids_cache(NMDeviceWifi *self, NMWifiAP *ap) { - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); + g_return_if_fail(NM_IS_DEVICE_WIFI(self)); - if (ap == NULL) - return; + if (ap == NULL) + return; - /* Don't cache the BSSID for Ad-Hoc APs */ - if (nm_wifi_ap_get_mode (ap) != NM_802_11_MODE_INFRA) - return; + /* Don't cache the BSSID for Ad-Hoc APs */ + if (nm_wifi_ap_get_mode(ap) != NM_802_11_MODE_INFRA) + return; - if ( nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED - && nm_device_has_unmodified_applied_connection (NM_DEVICE (self), NM_SETTING_COMPARE_FLAG_NONE)) { - nm_settings_connection_add_seen_bssid (nm_device_get_settings_connection (NM_DEVICE (self)), - nm_wifi_ap_get_address (ap)); - } + if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_ACTIVATED + && nm_device_has_unmodified_applied_connection(NM_DEVICE(self), + NM_SETTING_COMPARE_FLAG_NONE)) { + nm_settings_connection_add_seen_bssid(nm_device_get_settings_connection(NM_DEVICE(self)), + nm_wifi_ap_get_address(ap)); + } } static void -set_current_ap (NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available_connections) +set_current_ap(NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available_connections) { - NMDeviceWifiPrivate *priv; - NMWifiAP *old_ap; + NMDeviceWifiPrivate *priv; + NMWifiAP * old_ap; - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); + g_return_if_fail(NM_IS_DEVICE_WIFI(self)); - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - old_ap = priv->current_ap; + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + old_ap = priv->current_ap; - if (old_ap == new_ap) - return; + if (old_ap == new_ap) + return; - if (new_ap) { - priv->current_ap = g_object_ref (new_ap); + if (new_ap) { + priv->current_ap = g_object_ref(new_ap); - /* Update seen BSSIDs cache */ - update_seen_bssids_cache (self, priv->current_ap); - } else - priv->current_ap = NULL; + /* Update seen BSSIDs cache */ + update_seen_bssids_cache(self, priv->current_ap); + } else + priv->current_ap = NULL; - if (old_ap) { - NM80211Mode mode = nm_wifi_ap_get_mode (old_ap); + if (old_ap) { + NM80211Mode mode = nm_wifi_ap_get_mode(old_ap); - /* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */ - if ( NM_IN_SET (mode, NM_802_11_MODE_ADHOC, - NM_802_11_MODE_AP) - || nm_wifi_ap_get_fake (old_ap)) - ap_add_remove (self, FALSE, old_ap, recheck_available_connections); - g_object_unref (old_ap); - } + /* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */ + if (NM_IN_SET(mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP) || nm_wifi_ap_get_fake(old_ap)) + ap_add_remove(self, FALSE, old_ap, recheck_available_connections); + g_object_unref(old_ap); + } - _notify (self, PROP_ACTIVE_ACCESS_POINT); + _notify(self, PROP_ACTIVE_ACCESS_POINT); } static void -periodic_update (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv; - int ifindex; - guint32 new_rate; - - if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_ACTIVATED) { - /* BSSID and signal strength have meaningful values only if the device - * is activated and not scanning. - */ - return; - } - - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if ( !nm_supplicant_interface_state_is_associated (nm_supplicant_interface_get_state (priv->sup_iface)) - || nm_supplicant_interface_get_scanning (priv->sup_iface)) { - /* Only update current AP if we're actually talking to something, otherwise - * assume the old one (if any) is still valid until we're told otherwise or - * the connection fails. - */ - return; - } - - if (priv->mode == NM_802_11_MODE_AP) { - /* In AP mode we currently have nothing to do. */ - return; - } - - ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - if (ifindex <= 0) - g_return_if_reached (); - - if (priv->current_ap) { - int percent; - - percent = nm_platform_wifi_get_quality (nm_device_get_platform (NM_DEVICE (self)), ifindex); - if ( percent >= 0 - && percent <= 100) { - if (nm_wifi_ap_set_strength (priv->current_ap, (gint8) percent)) { +periodic_update(NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv; + int ifindex; + guint32 new_rate; + + if (nm_device_get_state(NM_DEVICE(self)) != NM_DEVICE_STATE_ACTIVATED) { + /* BSSID and signal strength have meaningful values only if the device + * is activated and not scanning. + */ + return; + } + + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + if (!nm_supplicant_interface_state_is_associated( + nm_supplicant_interface_get_state(priv->sup_iface)) + || nm_supplicant_interface_get_scanning(priv->sup_iface)) { + /* Only update current AP if we're actually talking to something, otherwise + * assume the old one (if any) is still valid until we're told otherwise or + * the connection fails. + */ + return; + } + + if (priv->mode == NM_802_11_MODE_AP) { + /* In AP mode we currently have nothing to do. */ + return; + } + + ifindex = nm_device_get_ifindex(NM_DEVICE(self)); + if (ifindex <= 0) + g_return_if_reached(); + + if (priv->current_ap) { + int percent; + + percent = nm_platform_wifi_get_quality(nm_device_get_platform(NM_DEVICE(self)), ifindex); + if (percent >= 0 && percent <= 100) { + if (nm_wifi_ap_set_strength(priv->current_ap, (gint8) percent)) { #if NM_MORE_LOGGING - _ap_dump (self, LOGL_TRACE, priv->current_ap, "updated", 0); + _ap_dump(self, LOGL_TRACE, priv->current_ap, "updated", 0); #endif - } - } - } + } + } + } - new_rate = nm_platform_wifi_get_rate (nm_device_get_platform (NM_DEVICE (self)), ifindex); - if (new_rate != priv->rate) { - priv->rate = new_rate; - _notify (self, PROP_BITRATE); - } + new_rate = nm_platform_wifi_get_rate(nm_device_get_platform(NM_DEVICE(self)), ifindex); + if (new_rate != priv->rate) { + priv->rate = new_rate; + _notify(self, PROP_BITRATE); + } } static gboolean -periodic_update_cb (gpointer user_data) +periodic_update_cb(gpointer user_data) { - periodic_update (user_data); - return TRUE; + periodic_update(user_data); + return TRUE; } static void -ap_add_remove (NMDeviceWifi *self, - gboolean is_adding, /* or else removing */ - NMWifiAP *ap, - gboolean recheck_available_connections) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - if (is_adding) { - g_object_ref (ap); - ap->wifi_device = NM_DEVICE (self); - c_list_link_tail (&priv->aps_lst_head, &ap->aps_lst); - if (!g_hash_table_insert (priv->aps_idx_by_supplicant_path, nm_wifi_ap_get_supplicant_path (ap), ap)) - nm_assert_not_reached (); - nm_dbus_object_export (NM_DBUS_OBJECT (ap)); - _ap_dump (self, LOGL_DEBUG, ap, "added", 0); - nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, TRUE); - } else { - ap->wifi_device = NULL; - c_list_unlink (&ap->aps_lst); - if (!g_hash_table_remove (priv->aps_idx_by_supplicant_path, nm_wifi_ap_get_supplicant_path (ap))) - nm_assert_not_reached (); - _ap_dump (self, LOGL_DEBUG, ap, "removed", 0); - } - - _notify (self, PROP_ACCESS_POINTS); - - if (!is_adding) { - nm_device_wifi_emit_signal_access_point (NM_DEVICE (self), ap, FALSE); - nm_dbus_object_clear_and_unexport (&ap); - } - - nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); - if (recheck_available_connections) - nm_device_recheck_available_connections (NM_DEVICE (self)); +ap_add_remove(NMDeviceWifi *self, + gboolean is_adding, /* or else removing */ + NMWifiAP * ap, + gboolean recheck_available_connections) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + if (is_adding) { + g_object_ref(ap); + ap->wifi_device = NM_DEVICE(self); + c_list_link_tail(&priv->aps_lst_head, &ap->aps_lst); + if (!g_hash_table_insert(priv->aps_idx_by_supplicant_path, + nm_wifi_ap_get_supplicant_path(ap), + ap)) + nm_assert_not_reached(); + nm_dbus_object_export(NM_DBUS_OBJECT(ap)); + _ap_dump(self, LOGL_DEBUG, ap, "added", 0); + nm_device_wifi_emit_signal_access_point(NM_DEVICE(self), ap, TRUE); + } else { + ap->wifi_device = NULL; + c_list_unlink(&ap->aps_lst); + if (!g_hash_table_remove(priv->aps_idx_by_supplicant_path, + nm_wifi_ap_get_supplicant_path(ap))) + nm_assert_not_reached(); + _ap_dump(self, LOGL_DEBUG, ap, "removed", 0); + } + + _notify(self, PROP_ACCESS_POINTS); + + if (!is_adding) { + nm_device_wifi_emit_signal_access_point(NM_DEVICE(self), ap, FALSE); + nm_dbus_object_clear_and_unexport(&ap); + } + + nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + if (recheck_available_connections) + nm_device_recheck_available_connections(NM_DEVICE(self)); } static void -remove_all_aps (NMDeviceWifi *self) +remove_all_aps(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMWifiAP *ap; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMWifiAP * ap; - if (c_list_is_empty (&priv->aps_lst_head)) - return; + if (c_list_is_empty(&priv->aps_lst_head)) + return; - set_current_ap (self, NULL, FALSE); + set_current_ap(self, NULL, FALSE); - while ((ap = c_list_first_entry (&priv->aps_lst_head, NMWifiAP, aps_lst))) - ap_add_remove (self, FALSE, ap, FALSE); + while ((ap = c_list_first_entry(&priv->aps_lst_head, NMWifiAP, aps_lst))) + ap_add_remove(self, FALSE, ap, FALSE); - nm_device_recheck_available_connections (NM_DEVICE (self)); + nm_device_recheck_available_connections(NM_DEVICE(self)); } static gboolean -wake_on_wlan_restore (NMDeviceWifi *self) +wake_on_wlan_restore(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWirelessWakeOnWLan w; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWirelessWakeOnWLan w; - w = priv->wowlan_restore; - if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) - return TRUE; + w = priv->wowlan_restore; + if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) + return TRUE; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; - return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET, - nm_device_get_ifindex (NM_DEVICE (self)), - w); + priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, + nm_device_get_ifindex(NM_DEVICE(self)), + w); } static void -disconnect_cb (NMSupplicantInterface *iface, GError *error, gpointer user_data) +disconnect_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data) { - gs_unref_object NMDeviceWifi *self = NULL; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; + gs_unref_object NMDeviceWifi *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; - nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data); - /* error will be freed by sup_iface */ - callback (NM_DEVICE (self), error, callback_user_data); + /* error will be freed by sup_iface */ + callback(NM_DEVICE(self), error, callback_user_data); } static void -disconnect_cb_on_idle (gpointer user_data, - GCancellable *cancellable) +disconnect_cb_on_idle(gpointer user_data, GCancellable *cancellable) { - gs_unref_object NMDeviceWifi *self = NULL; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; - gs_free_error GError *cancelled_error = NULL; + gs_unref_object NMDeviceWifi *self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; + gs_free_error GError *cancelled_error = NULL; - nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); + nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data); - g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error); - callback (NM_DEVICE (self), cancelled_error, callback_user_data); + g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); + callback(NM_DEVICE(self), cancelled_error, callback_user_data); } static void -deactivate_async (NMDevice *device, - GCancellable *cancellable, - NMDeviceDeactivateCallback callback, - gpointer callback_user_data) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gpointer user_data; +deactivate_async(NMDevice * device, + GCancellable * cancellable, + NMDeviceDeactivateCallback callback, + gpointer callback_user_data) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gpointer user_data; - nm_assert (G_IS_CANCELLABLE (cancellable)); - nm_assert (callback); + nm_assert(G_IS_CANCELLABLE(cancellable)); + nm_assert(callback); - user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data); - if (!priv->sup_iface) { - nm_utils_invoke_on_idle (cancellable, disconnect_cb_on_idle, user_data); - return; - } + user_data = nm_utils_user_data_pack(g_object_ref(self), callback, callback_user_data); + if (!priv->sup_iface) { + nm_utils_invoke_on_idle(cancellable, disconnect_cb_on_idle, user_data); + return; + } - cleanup_association_attempt (self, FALSE); + cleanup_association_attempt(self, FALSE); - nm_supplicant_interface_disconnect_async (priv->sup_iface, - cancellable, - disconnect_cb, - user_data); + nm_supplicant_interface_disconnect_async(priv->sup_iface, + cancellable, + disconnect_cb, + user_data); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (device); + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + int ifindex = nm_device_get_ifindex(device); - nm_clear_g_source (&priv->periodic_update_id); + nm_clear_g_source(&priv->periodic_update_id); - cleanup_association_attempt (self, TRUE); + cleanup_association_attempt(self, TRUE); - priv->rate = 0; + priv->rate = 0; - set_current_ap (self, NULL, TRUE); + set_current_ap(self, NULL, TRUE); - if (!wake_on_wlan_restore (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot unconfigure WoWLAN."); + if (!wake_on_wlan_restore(self)) + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Cannot unconfigure WoWLAN."); - /* Clear any critical protocol notification in the Wi-Fi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE); + /* Clear any critical protocol notification in the Wi-Fi stack */ + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), ifindex, FALSE); - /* Ensure we're in infrastructure mode after deactivation; some devices - * (usually older ones) don't scan well in adhoc mode. - */ - if (nm_platform_wifi_get_mode (nm_device_get_platform (device), ifindex) != NM_802_11_MODE_INFRA) { - nm_device_take_down (NM_DEVICE (self), TRUE); - nm_platform_wifi_set_mode (nm_device_get_platform (device), ifindex, NM_802_11_MODE_INFRA); - nm_device_bring_up (NM_DEVICE (self), TRUE, NULL); - } + /* Ensure we're in infrastructure mode after deactivation; some devices + * (usually older ones) don't scan well in adhoc mode. + */ + if (nm_platform_wifi_get_mode(nm_device_get_platform(device), ifindex) + != NM_802_11_MODE_INFRA) { + nm_device_take_down(NM_DEVICE(self), TRUE); + nm_platform_wifi_set_mode(nm_device_get_platform(device), ifindex, NM_802_11_MODE_INFRA); + nm_device_bring_up(NM_DEVICE(self), TRUE, NULL); + } - if (priv->mode != NM_802_11_MODE_INFRA) { - priv->mode = NM_802_11_MODE_INFRA; - _notify (self, PROP_MODE); - } + if (priv->mode != NM_802_11_MODE_INFRA) { + priv->mode = NM_802_11_MODE_INFRA; + _notify(self, PROP_MODE); + } - _scan_notify_allowed (self, NM_TERNARY_TRUE); + _scan_notify_allowed(self, NM_TERNARY_TRUE); } static void -deactivate_reset_hw_addr (NMDevice *device) +deactivate_reset_hw_addr(NMDevice *device) { - _hw_addr_set_scanning ((NMDeviceWifi *) device, TRUE); + _hw_addr_set_scanning((NMDeviceWifi *) device, TRUE); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWireless *s_wireless; - const char *mac; - const char * const *mac_blacklist; - int i; - const char *mode; - const char *perm_hw_addr; - - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - s_wireless = nm_connection_get_setting_wireless (connection); - - perm_hw_addr = nm_device_get_permanent_hw_address (device); - mac = nm_setting_wireless_get_mac_address (s_wireless); - if (perm_hw_addr) { - if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device MAC address does not match the profile"); - return FALSE; - } - - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - for (i = 0; mac_blacklist[i]; i++) { - if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { - g_warn_if_reached (); - return FALSE; - } - - 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, - "MAC address blacklisted"); - return FALSE; - } - } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no valid MAC address as required by profile"); - return FALSE; - } - - /* Early exit if supplicant or device doesn't support requested mode */ - mode = nm_setting_wireless_get_mode (s_wireless); - if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the device does not support Ad-Hoc networks"); - return FALSE; - } - } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the device does not support Access Point mode"); - return FALSE; - } - - if (priv->sup_iface) { - if (nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) == NM_TERNARY_FALSE) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "wpa_supplicant does not support Access Point mode"); - return FALSE; - } - } - } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the device does not support Mesh mode"); - return FALSE; - } - - if (priv->sup_iface) { - if (nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_MESH) == NM_TERNARY_FALSE) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "wpa_supplicant does not support Mesh mode"); - return FALSE; - } - } - } - - // FIXME: check channel/freq/band against bands the hardware supports - // FIXME: check encryption against device capabilities - // FIXME: check bitrate against device capabilities - - return TRUE; +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWireless * s_wireless; + const char * mac; + const char *const * mac_blacklist; + int i; + const char * mode; + const char * perm_hw_addr; + + if (!NM_DEVICE_CLASS(nm_device_wifi_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + s_wireless = nm_connection_get_setting_wireless(connection); + + perm_hw_addr = nm_device_get_permanent_hw_address(device); + mac = nm_setting_wireless_get_mac_address(s_wireless); + if (perm_hw_addr) { + if (mac && !nm_utils_hwaddr_matches(mac, -1, perm_hw_addr, -1)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device MAC address does not match the profile"); + return FALSE; + } + + /* Check for MAC address blacklist */ + mac_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless); + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)) { + g_warn_if_reached(); + return FALSE; + } + + 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, + "MAC address blacklisted"); + return FALSE; + } + } + } else if (mac) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has no valid MAC address as required by profile"); + return FALSE; + } + + /* Early exit if supplicant or device doesn't support requested mode */ + mode = nm_setting_wireless_get_mode(s_wireless); + if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the device does not support Ad-Hoc networks"); + return FALSE; + } + } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the device does not support Access Point mode"); + return FALSE; + } + + if (priv->sup_iface) { + if (nm_supplicant_interface_get_capability(priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) + == NM_TERNARY_FALSE) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "wpa_supplicant does not support Access Point mode"); + return FALSE; + } + } + } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the device does not support Mesh mode"); + return FALSE; + } + + if (priv->sup_iface) { + if (nm_supplicant_interface_get_capability(priv->sup_iface, NM_SUPPL_CAP_TYPE_MESH) + == NM_TERNARY_FALSE) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "wpa_supplicant does not support Mesh mode"); + return FALSE; + } + } + } + + // FIXME: check channel/freq/band against bands the hardware supports + // FIXME: check encryption against device capabilities + // FIXME: check bitrate against device capabilities + + return TRUE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWireless *s_wifi; - const char *mode; - - s_wifi = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wifi, FALSE); - - /* a connection that is available for a certain @specific_object, MUST - * also be available in general (without @specific_object). */ - - if (specific_object) { - NMWifiAP *ap; - - ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point not found"); - return FALSE; - } - if (!nm_wifi_ap_check_compatible (ap, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point is not compatible with profile"); - return FALSE; - } - return TRUE; - } - - /* Ad-Hoc, AP and Mesh connections are always available because they may be - * started at any time. - */ - mode = nm_setting_wireless_get_mode (s_wifi); - if ( g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0 - || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0 - || g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) - return TRUE; - - /* Hidden SSIDs obviously don't always appear in the scan list either. - * - * For an explicit user-activation-request, a connection is considered - * available because for hidden Wi-Fi, clients didn't consistently - * set the 'hidden' property to indicate hidden SSID networks. If - * activating but the network isn't available let the device recheck - * availability. - */ - if ( nm_setting_wireless_get_hidden (s_wifi) - || NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) - return TRUE; - - if (!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no compatible access point found"); - return FALSE; - } - - return TRUE; +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWireless * s_wifi; + const char * mode; + + s_wifi = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wifi, FALSE); + + /* a connection that is available for a certain @specific_object, MUST + * also be available in general (without @specific_object). */ + + if (specific_object) { + NMWifiAP *ap; + + ap = nm_wifi_ap_lookup_for_device(NM_DEVICE(self), specific_object); + if (!ap) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "requested access point not found"); + return FALSE; + } + if (!nm_wifi_ap_check_compatible(ap, connection)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "requested access point is not compatible with profile"); + return FALSE; + } + return TRUE; + } + + /* Ad-Hoc, AP and Mesh connections are always available because they may be + * started at any time. + */ + mode = nm_setting_wireless_get_mode(s_wifi); + if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0 + || g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0 + || g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) + return TRUE; + + /* Hidden SSIDs obviously don't always appear in the scan list either. + * + * For an explicit user-activation-request, a connection is considered + * available because for hidden Wi-Fi, clients didn't consistently + * set the 'hidden' property to indicate hidden SSID networks. If + * activating but the network isn't available let the device recheck + * availability. + */ + if (nm_setting_wireless_get_hidden(s_wifi) + || NM_FLAGS_HAS(flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) + return TRUE; + + if (!nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "no compatible access point found"); + return FALSE; + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWireless *s_wifi; - gs_free char *ssid_utf8 = NULL; - NMWifiAP *ap; - GBytes *ssid = NULL; - GBytes *setting_ssid = NULL; - gboolean hidden = FALSE; - const char *mode; - - s_wifi = nm_connection_get_setting_wireless (connection); - - mode = s_wifi ? nm_setting_wireless_get_mode (s_wifi) : NULL; - - if (!specific_object) { - /* If not given a specific object, we need at minimum an SSID */ - if (!s_wifi) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting is required if no AP path was given."); - return FALSE; - } - - setting_ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!setting_ssid || g_bytes_get_size (setting_ssid) == 0) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'wireless' setting with a valid SSID is required if no AP path was given."); - return FALSE; - } - - if (!nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) { - /* Find a compatible AP in the scan list */ - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - - /* If we still don't have an AP, then the WiFI settings needs to be - * fully specified by the client. Might not be able to find an AP - * if the network isn't broadcasting the SSID for example. - */ - if (!ap) { - if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) - return FALSE; - - hidden = TRUE; - } - } else { - if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) - return FALSE; - ap = NULL; - } - } else if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) - return FALSE; - ap = NULL; - } else { - ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, - "The access point %s was not in the scan list.", - specific_object); - return FALSE; - } - } - - /* Add a wifi setting if one doesn't exist yet */ - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - } - - if (ap) - ssid = nm_wifi_ap_get_ssid (ap); - - if (ssid == NULL) { - /* The AP must be hidden. Connecting to a Wi-Fi AP requires the SSID - * as part of the initial handshake, so check the connection details - * for the SSID. The AP object will still be used for encryption - * settings and such. - */ - ssid = nm_setting_wireless_get_ssid (s_wifi); - } - - if (ssid == NULL) { - /* If there's no SSID on the AP itself, and no SSID in the - * connection data, then we cannot connect at all. Return an error. - */ - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - ap - ? "A 'wireless' setting with a valid SSID is required for hidden access points." - : "Cannot create 'wireless' setting due to missing SSID."); - return FALSE; - } - - if (ap) { - /* If the SSID is a well-known SSID, lock the connection to the AP's - * specific BSSID so NM doesn't autoconnect to some random wifi net. - */ - if (!nm_wifi_ap_complete_connection (ap, - connection, - nm_wifi_utils_is_manf_default_ssid (ssid), - error)) - return FALSE; - } - - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_WIRELESS_SETTING_NAME, - existing_connections, - ssid_utf8, - ssid_utf8, - NULL, - nm_setting_wireless_get_mac_address (s_wifi) ? NULL : nm_device_get_iface (device), - TRUE); - - if (hidden) - g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - - return TRUE; +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWireless * s_wifi; + gs_free char * ssid_utf8 = NULL; + NMWifiAP * ap; + GBytes * ssid = NULL; + GBytes * setting_ssid = NULL; + gboolean hidden = FALSE; + const char * mode; + + s_wifi = nm_connection_get_setting_wireless(connection); + + mode = s_wifi ? nm_setting_wireless_get_mode(s_wifi) : NULL; + + if (!specific_object) { + /* If not given a specific object, we need at minimum an SSID */ + if (!s_wifi) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wireless' setting is required if no AP path was given."); + return FALSE; + } + + setting_ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!setting_ssid || g_bytes_get_size(setting_ssid) == 0) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "A 'wireless' setting with a valid SSID is required if no AP path was given."); + return FALSE; + } + + if (!nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) { + /* Find a compatible AP in the scan list */ + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + + /* If we still don't have an AP, then the WiFI settings needs to be + * fully specified by the client. Might not be able to find an AP + * if the network isn't broadcasting the SSID for example. + */ + if (!ap) { + if (!nm_setting_verify(NM_SETTING(s_wifi), connection, error)) + return FALSE; + + hidden = TRUE; + } + } else { + if (!nm_setting_verify(NM_SETTING(s_wifi), connection, error)) + return FALSE; + ap = NULL; + } + } else if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) { + if (!nm_setting_verify(NM_SETTING(s_wifi), connection, error)) + return FALSE; + ap = NULL; + } else { + ap = nm_wifi_ap_lookup_for_device(NM_DEVICE(self), specific_object); + if (!ap) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, + "The access point %s was not in the scan list.", + specific_object); + return FALSE; + } + } + + /* Add a wifi setting if one doesn't exist yet */ + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + } + + if (ap) + ssid = nm_wifi_ap_get_ssid(ap); + + if (ssid == NULL) { + /* The AP must be hidden. Connecting to a Wi-Fi AP requires the SSID + * as part of the initial handshake, so check the connection details + * for the SSID. The AP object will still be used for encryption + * settings and such. + */ + ssid = nm_setting_wireless_get_ssid(s_wifi); + } + + if (ssid == NULL) { + /* If there's no SSID on the AP itself, and no SSID in the + * connection data, then we cannot connect at all. Return an error. + */ + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + ap ? "A 'wireless' setting with a valid SSID is required for hidden access points." + : "Cannot create 'wireless' setting due to missing SSID."); + return FALSE; + } + + if (ap) { + /* If the SSID is a well-known SSID, lock the connection to the AP's + * specific BSSID so NM doesn't autoconnect to some random wifi net. + */ + if (!nm_wifi_ap_complete_connection(ap, + connection, + nm_wifi_utils_is_manf_default_ssid(ssid), + error)) + return FALSE; + } + + ssid_utf8 = _nm_utils_ssid_to_utf8(ssid); + nm_utils_complete_generic( + nm_device_get_platform(device), + connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + ssid_utf8, + ssid_utf8, + NULL, + nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device), + TRUE); + + if (hidden) + g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); + + return TRUE; } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSupplicantInterfaceState supplicant_state; + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSupplicantInterfaceState supplicant_state; - if (!priv->enabled) - return FALSE; + if (!priv->enabled) + return FALSE; - if (!priv->sup_iface) - return FALSE; + if (!priv->sup_iface) + return FALSE; - supplicant_state = nm_supplicant_interface_get_state (priv->sup_iface); - if ( supplicant_state <= NM_SUPPLICANT_INTERFACE_STATE_STARTING - || supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) - return FALSE; + supplicant_state = nm_supplicant_interface_get_state(priv->sup_iface); + if (supplicant_state <= NM_SUPPLICANT_INTERFACE_STATE_STARTING + || supplicant_state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) + return FALSE; - return TRUE; + return TRUE; } static gboolean -get_autoconnect_allowed (NMDevice *device) +get_autoconnect_allowed(NMDevice *device) { - return !NM_DEVICE_WIFI_GET_PRIVATE (NM_DEVICE_WIFI (device))->scan_is_scanning; + return !NM_DEVICE_WIFI_GET_PRIVATE(NM_DEVICE_WIFI(device))->scan_is_scanning; } static gboolean -can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, - char **specific_object) +can_auto_connect(NMDevice *device, NMSettingsConnection *sett_conn, char **specific_object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMConnection *connection; - NMSettingWireless *s_wifi; - NMWifiAP *ap; - const char *method6, *mode; - gboolean auto4, auto6; + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMConnection * connection; + NMSettingWireless * s_wifi; + NMWifiAP * ap; + const char * method6, *mode; + gboolean auto4, auto6; - nm_assert (!specific_object || !*specific_object); + nm_assert(!specific_object || !*specific_object); - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (device, sett_conn, NULL)) - return FALSE; + if (!NM_DEVICE_CLASS(nm_device_wifi_parent_class)->can_auto_connect(device, sett_conn, NULL)) + return FALSE; - connection = nm_settings_connection_get_connection (sett_conn); + connection = nm_settings_connection_get_connection(sett_conn); - s_wifi = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wifi, FALSE); + s_wifi = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wifi, FALSE); - /* Always allow autoconnect for AP and non-autoconf Ad-Hoc or Mesh */ - auto4 = nm_streq0 (nm_utils_get_ip_config_method (connection, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_AUTO); - method6 = nm_utils_get_ip_config_method (connection, AF_INET6); - auto6 = nm_streq0 (method6, NM_SETTING_IP6_CONFIG_METHOD_AUTO) - || nm_streq0 (method6, NM_SETTING_IP6_CONFIG_METHOD_DHCP); + /* Always allow autoconnect for AP and non-autoconf Ad-Hoc or Mesh */ + auto4 = nm_streq0(nm_utils_get_ip_config_method(connection, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_AUTO); + method6 = nm_utils_get_ip_config_method(connection, AF_INET6); + auto6 = nm_streq0(method6, NM_SETTING_IP6_CONFIG_METHOD_AUTO) + || nm_streq0(method6, NM_SETTING_IP6_CONFIG_METHOD_DHCP); - mode = nm_setting_wireless_get_mode (s_wifi); + mode = nm_setting_wireless_get_mode(s_wifi); - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) - return TRUE; - else if (!auto4 && nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) - return TRUE; - else if (!auto4 && !auto6 && nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_MESH)) - return TRUE; + if (nm_streq0(mode, NM_SETTING_WIRELESS_MODE_AP)) + return TRUE; + else if (!auto4 && nm_streq0(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) + return TRUE; + else if (!auto4 && !auto6 && nm_streq0(mode, NM_SETTING_WIRELESS_MODE_MESH)) + return TRUE; - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - if (ap) { - /* All good; connection is usable */ - NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)))); - return TRUE; - } + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + if (ap) { + /* All good; connection is usable */ + NM_SET_OUT(specific_object, g_strdup(nm_dbus_object_get_path(NM_DBUS_OBJECT(ap)))); + return TRUE; + } - return FALSE; + return FALSE; } const CList * -_nm_device_wifi_get_aps (NMDeviceWifi *self) +_nm_device_wifi_get_aps(NMDeviceWifi *self) { - return &NM_DEVICE_WIFI_GET_PRIVATE (self)->aps_lst_head; + return &NM_DEVICE_WIFI_GET_PRIVATE(self)->aps_lst_head; } static void -_hw_addr_set_scanning (NMDeviceWifi *self, gboolean do_reset) -{ - NMDevice *device = (NMDevice *) self; - NMDeviceWifiPrivate *priv; - guint32 now; - gboolean randomize; - - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); - - if ( nm_device_is_activating (device) - || nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) - return; - - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - randomize = nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS, - device, - TRUE, TRUE); - - if (!randomize) { - /* expire the temporary MAC address used during scanning */ - priv->hw_addr_scan_expire = 0; - - if (do_reset) { - priv->scan_last_request_started_at_msec = G_MININT64; - priv->scan_periodic_next_msec = 0; - priv->scan_periodic_interval_sec = 0; - nm_device_hw_addr_reset (device, "scanning"); - } - return; - } - - now = nm_utils_get_monotonic_timestamp_sec (); - - if (now >= priv->hw_addr_scan_expire) { - gs_free char *generate_mac_address_mask = NULL; - gs_free char *hw_addr_scan = NULL; - - /* the random MAC address for scanning expires after a while. - * - * We don't bother with to update the MAC address exactly when - * it expires, instead on the next scan request, we will generate - * a new one.*/ - priv->hw_addr_scan_expire = now + SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC; - - generate_mac_address_mask = nm_config_data_get_device_config (NM_CONFIG_GET_DATA, - "wifi.scan-generate-mac-address-mask", - device, - NULL); - - priv->scan_last_request_started_at_msec = G_MININT64; - priv->scan_periodic_next_msec = 0; - priv->scan_periodic_interval_sec = 0; - hw_addr_scan = nm_utils_hw_addr_gen_random_eth (nm_device_get_initial_hw_address (device), - generate_mac_address_mask); - nm_device_hw_addr_set (device, hw_addr_scan, "scanning", TRUE); - } +_hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset) +{ + NMDevice * device = (NMDevice *) self; + NMDeviceWifiPrivate *priv; + guint32 now; + gboolean randomize; + + g_return_if_fail(NM_IS_DEVICE_WIFI(self)); + + if (nm_device_is_activating(device) || nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) + return; + + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + randomize = nm_config_data_get_device_config_boolean( + NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS, + device, + TRUE, + TRUE); + + if (!randomize) { + /* expire the temporary MAC address used during scanning */ + priv->hw_addr_scan_expire = 0; + + if (do_reset) { + priv->scan_last_request_started_at_msec = G_MININT64; + priv->scan_periodic_next_msec = 0; + priv->scan_periodic_interval_sec = 0; + nm_device_hw_addr_reset(device, "scanning"); + } + return; + } + + now = nm_utils_get_monotonic_timestamp_sec(); + + if (now >= priv->hw_addr_scan_expire) { + gs_free char *generate_mac_address_mask = NULL; + gs_free char *hw_addr_scan = NULL; + + /* the random MAC address for scanning expires after a while. + * + * We don't bother with to update the MAC address exactly when + * it expires, instead on the next scan request, we will generate + * a new one.*/ + priv->hw_addr_scan_expire = now + SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC; + + generate_mac_address_mask = + nm_config_data_get_device_config(NM_CONFIG_GET_DATA, + "wifi.scan-generate-mac-address-mask", + device, + NULL); + + priv->scan_last_request_started_at_msec = G_MININT64; + priv->scan_periodic_next_msec = 0; + priv->scan_periodic_interval_sec = 0; + hw_addr_scan = nm_utils_hw_addr_gen_random_eth(nm_device_get_initial_hw_address(device), + generate_mac_address_mask); + nm_device_hw_addr_set(device, hw_addr_scan, "scanning", TRUE); + } } static GPtrArray * -ssids_options_to_ptrarray (GVariant *value, GError **error) -{ - gs_unref_ptrarray GPtrArray *ssids = NULL; - gsize num_ssids; - gsize i; - - nm_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("aay"))); - - num_ssids = g_variant_n_children (value); - if (num_ssids > 32) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "too many SSIDs requested to scan"); - return NULL; - } - - if (num_ssids) { - ssids = g_ptr_array_new_full (num_ssids, (GDestroyNotify) g_bytes_unref); - for (i = 0; i < num_ssids; i++) { - gs_unref_variant GVariant *v = NULL; - gsize len; - const guint8 *bytes; - - v = g_variant_get_child_value (value, i); - bytes = g_variant_get_fixed_array (v, &len, sizeof (guint8)); - if (len > 32) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "SSID at index %d more than 32 bytes", (int) i); - return NULL; - } - - g_ptr_array_add (ssids, g_bytes_new (bytes, len)); - } - } - - return g_steal_pointer (&ssids); +ssids_options_to_ptrarray(GVariant *value, GError **error) +{ + gs_unref_ptrarray GPtrArray *ssids = NULL; + gsize num_ssids; + gsize i; + + nm_assert(g_variant_is_of_type(value, G_VARIANT_TYPE("aay"))); + + num_ssids = g_variant_n_children(value); + if (num_ssids > 32) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "too many SSIDs requested to scan"); + return NULL; + } + + if (num_ssids) { + ssids = g_ptr_array_new_full(num_ssids, (GDestroyNotify) g_bytes_unref); + for (i = 0; i < num_ssids; i++) { + gs_unref_variant GVariant *v = NULL; + gsize len; + const guint8 * bytes; + + v = g_variant_get_child_value(value, i); + bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8)); + if (len > 32) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "SSID at index %d more than 32 bytes", + (int) i); + return NULL; + } + + g_ptr_array_add(ssids, g_bytes_new(bytes, len)); + } + } + + return g_steal_pointer(&ssids); } GPtrArray * -nmtst_ssids_options_to_ptrarray (GVariant *value, GError **error) +nmtst_ssids_options_to_ptrarray(GVariant *value, GError **error) { - return ssids_options_to_ptrarray (value, error); + return ssids_options_to_ptrarray(value, error); } static void -dbus_request_scan_cb (NMDevice *device, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) +dbus_request_scan_cb(NMDevice * device, + GDBusMethodInvocation *context, + NMAuthSubject * subject, + GError * error, + gpointer user_data) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *ssids = user_data; + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *ssids = user_data; - if (error) { - g_dbus_method_invocation_return_gerror (context, error); - return; - } + if (error) { + g_dbus_method_invocation_return_gerror(context, error); + return; + } - _scan_request_ssids_track (priv, ssids); - priv->scan_explicit_requested = TRUE; - _scan_kickoff (self); - g_dbus_method_invocation_return_value (context, NULL); + _scan_request_ssids_track(priv, ssids); + priv->scan_explicit_requested = TRUE; + _scan_kickoff(self); + g_dbus_method_invocation_return_value(context, NULL); } void -_nm_device_wifi_request_scan (NMDeviceWifi *self, - GVariant *options, - GDBusMethodInvocation *invocation) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - gs_unref_ptrarray GPtrArray *ssids = NULL; - - if (options) { - gs_unref_variant GVariant *val = g_variant_lookup_value (options, "ssids", NULL); - - if (val) { - gs_free_error GError *ssid_error = NULL; - - if (!g_variant_is_of_type (val, G_VARIANT_TYPE ("aay"))) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_ARGUMENT, - "Invalid 'ssid' scan option"); - return; - } - - ssids = ssids_options_to_ptrarray (val, &ssid_error); - if (ssid_error) { - g_dbus_method_invocation_return_gerror (invocation, ssid_error); - return; - } - } - } - - if ( !priv->enabled - || !priv->sup_iface - || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED) { - g_dbus_method_invocation_return_error_literal (invocation, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ALLOWED, - "Scanning not allowed while unavailable"); - return; - } - - nm_device_auth_request (device, - invocation, - NULL, - NM_AUTH_PERMISSION_WIFI_SCAN, - TRUE, - NULL, - dbus_request_scan_cb, - g_steal_pointer (&ssids)); +_nm_device_wifi_request_scan(NMDeviceWifi * self, + GVariant * options, + GDBusMethodInvocation *invocation) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + gs_unref_ptrarray GPtrArray *ssids = NULL; + + if (options) { + gs_unref_variant GVariant *val = g_variant_lookup_value(options, "ssids", NULL); + + if (val) { + gs_free_error GError *ssid_error = NULL; + + if (!g_variant_is_of_type(val, G_VARIANT_TYPE("aay"))) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_ARGUMENT, + "Invalid 'ssid' scan option"); + return; + } + + ssids = ssids_options_to_ptrarray(val, &ssid_error); + if (ssid_error) { + g_dbus_method_invocation_return_gerror(invocation, ssid_error); + return; + } + } + } + + if (!priv->enabled || !priv->sup_iface + || nm_device_get_state(device) < NM_DEVICE_STATE_DISCONNECTED) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, + "Scanning not allowed while unavailable"); + return; + } + + nm_device_auth_request(device, + invocation, + NULL, + NM_AUTH_PERMISSION_WIFI_SCAN, + TRUE, + NULL, + dbus_request_scan_cb, + g_steal_pointer(&ssids)); } static gboolean -hidden_filter_func (NMSettings *settings, - NMSettingsConnection *set_con, - gpointer user_data) +hidden_filter_func(NMSettings *settings, NMSettingsConnection *set_con, gpointer user_data) { - NMConnection *connection = nm_settings_connection_get_connection (set_con); - NMSettingWireless *s_wifi; + NMConnection * connection = nm_settings_connection_get_connection(set_con); + NMSettingWireless *s_wifi; - if (!nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) - return FALSE; - s_wifi = nm_connection_get_setting_wireless (connection); - if (!s_wifi) - return FALSE; - if (nm_streq0 (nm_setting_wireless_get_mode (s_wifi), NM_SETTING_WIRELESS_MODE_AP)) - return FALSE; - return nm_setting_wireless_get_hidden (s_wifi); + if (!nm_connection_is_type(connection, NM_SETTING_WIRELESS_SETTING_NAME)) + return FALSE; + s_wifi = nm_connection_get_setting_wireless(connection); + if (!s_wifi) + return FALSE; + if (nm_streq0(nm_setting_wireless_get_mode(s_wifi), NM_SETTING_WIRELESS_MODE_AP)) + return FALSE; + return nm_setting_wireless_get_hidden(s_wifi); } static GPtrArray * -_scan_request_ssids_build_hidden (NMDeviceWifi *self, - gint64 now_msec, - gboolean *out_has_hidden_profiles) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - guint max_scan_ssids = nm_supplicant_interface_get_max_scan_ssids (priv->sup_iface); - gs_free NMSettingsConnection **connections = NULL; - gs_unref_ptrarray GPtrArray *ssids = NULL; - gs_unref_hashtable GHashTable *unique_ssids = NULL; - guint connections_len; - guint n_hidden; - guint i; - - NM_SET_OUT (out_has_hidden_profiles, FALSE); - - /* collect all pending explicit SSIDs. */ - ssids = _scan_request_ssids_fetch (priv, now_msec); - - if (max_scan_ssids == 0) { - /* no space. @ssids will be ignored. */ - return NULL; - } - - if (ssids) { - if (ssids->len < max_scan_ssids) { - /* Add wildcard SSID using a static wildcard SSID used for every scan */ - g_ptr_array_insert (ssids, 0, g_bytes_ref (nm_gbytes_get_empty ())); - } - if (ssids->len >= max_scan_ssids) { - /* there is no more space. Use what we have. */ - g_ptr_array_set_size (ssids, max_scan_ssids); - return g_steal_pointer (&ssids); - } - } - - connections = nm_settings_get_connections_clone (nm_device_get_settings ((NMDevice *) self), - &connections_len, - hidden_filter_func, - NULL, - NULL, - NULL); - if (!connections[0]) - return g_steal_pointer (&ssids); - - if (!ssids) { - ssids = g_ptr_array_new_full (max_scan_ssids, (GDestroyNotify) g_bytes_unref); - /* Add wildcard SSID using a static wildcard SSID used for every scan */ - g_ptr_array_insert (ssids, 0, g_bytes_ref (nm_gbytes_get_empty ())); - } - - unique_ssids = g_hash_table_new (nm_gbytes_hash, nm_gbytes_equal); - for (i = 1; i < ssids->len; i++) { - if (!g_hash_table_add (unique_ssids, ssids->pdata[i])) - nm_assert_not_reached (); - } - - g_qsort_with_data (connections, - connections_len, - sizeof (NMSettingsConnection *), - nm_settings_connection_cmp_timestamp_p_with_data, - NULL); - - n_hidden = 0; - for (i = 0; i < connections_len; i++) { - NMSettingWireless *s_wifi; - GBytes *ssid; - - if (ssids->len >= max_scan_ssids) - break; - - if (n_hidden > 4) { - /* we allow at most 4 hidden profiles to be actively scanned. The - * reason is speed and to not disclose too many SSIDs. */ - break; - } - - s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (connections[i])); - ssid = nm_setting_wireless_get_ssid (s_wifi); - - if (!g_hash_table_add (unique_ssids, ssid)) - continue; - - g_ptr_array_add (ssids, g_bytes_ref (ssid)); - n_hidden++; - } - - NM_SET_OUT (out_has_hidden_profiles, n_hidden > 0); - return g_steal_pointer (&ssids); +_scan_request_ssids_build_hidden(NMDeviceWifi *self, + gint64 now_msec, + gboolean * out_has_hidden_profiles) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + guint max_scan_ssids = nm_supplicant_interface_get_max_scan_ssids(priv->sup_iface); + gs_free NMSettingsConnection **connections = NULL; + gs_unref_ptrarray GPtrArray *ssids = NULL; + gs_unref_hashtable GHashTable *unique_ssids = NULL; + guint connections_len; + guint n_hidden; + guint i; + + NM_SET_OUT(out_has_hidden_profiles, FALSE); + + /* collect all pending explicit SSIDs. */ + ssids = _scan_request_ssids_fetch(priv, now_msec); + + if (max_scan_ssids == 0) { + /* no space. @ssids will be ignored. */ + return NULL; + } + + if (ssids) { + if (ssids->len < max_scan_ssids) { + /* Add wildcard SSID using a static wildcard SSID used for every scan */ + g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_gbytes_get_empty())); + } + if (ssids->len >= max_scan_ssids) { + /* there is no more space. Use what we have. */ + g_ptr_array_set_size(ssids, max_scan_ssids); + return g_steal_pointer(&ssids); + } + } + + connections = nm_settings_get_connections_clone(nm_device_get_settings((NMDevice *) self), + &connections_len, + hidden_filter_func, + NULL, + NULL, + NULL); + if (!connections[0]) + return g_steal_pointer(&ssids); + + if (!ssids) { + ssids = g_ptr_array_new_full(max_scan_ssids, (GDestroyNotify) g_bytes_unref); + /* Add wildcard SSID using a static wildcard SSID used for every scan */ + g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_gbytes_get_empty())); + } + + unique_ssids = g_hash_table_new(nm_gbytes_hash, nm_gbytes_equal); + for (i = 1; i < ssids->len; i++) { + if (!g_hash_table_add(unique_ssids, ssids->pdata[i])) + nm_assert_not_reached(); + } + + g_qsort_with_data(connections, + connections_len, + sizeof(NMSettingsConnection *), + nm_settings_connection_cmp_timestamp_p_with_data, + NULL); + + n_hidden = 0; + for (i = 0; i < connections_len; i++) { + NMSettingWireless *s_wifi; + GBytes * ssid; + + if (ssids->len >= max_scan_ssids) + break; + + if (n_hidden > 4) { + /* we allow at most 4 hidden profiles to be actively scanned. The + * reason is speed and to not disclose too many SSIDs. */ + break; + } + + s_wifi = nm_connection_get_setting_wireless( + nm_settings_connection_get_connection(connections[i])); + ssid = nm_setting_wireless_get_ssid(s_wifi); + + if (!g_hash_table_add(unique_ssids, ssid)) + continue; + + g_ptr_array_add(ssids, g_bytes_ref(ssid)); + n_hidden++; + } + + NM_SET_OUT(out_has_hidden_profiles, n_hidden > 0); + return g_steal_pointer(&ssids); } static gboolean -_scan_request_delay_cb (gpointer user_data) +_scan_request_delay_cb(gpointer user_data) { - NMDeviceWifi *self = user_data; - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_clear_g_source_inst (&priv->scan_request_delay_source); + nm_clear_g_source_inst(&priv->scan_request_delay_source); - _LOGT_scan ("scan request completed (after extra delay)"); + _LOGT_scan("scan request completed (after extra delay)"); - _scan_notify_is_scanning (self); - return G_SOURCE_REMOVE; + _scan_notify_is_scanning(self); + return G_SOURCE_REMOVE; } static void -_scan_supplicant_request_scan_cb (NMSupplicantInterface *supp_iface, - GCancellable *cancellable, - gpointer user_data) +_scan_supplicant_request_scan_cb(NMSupplicantInterface *supp_iface, + GCancellable * cancellable, + gpointer user_data) { - NMDeviceWifi *self; - NMDeviceWifiPrivate *priv; + NMDeviceWifi * self; + NMDeviceWifiPrivate *priv; - if (g_cancellable_is_cancelled (cancellable)) - return; + if (g_cancellable_is_cancelled(cancellable)) + return; - self = user_data; - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + self = user_data; + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - _LOGT_scan ("scan request completed (D-Bus request)"); + _LOGT_scan("scan request completed (D-Bus request)"); - /* we just completed a scan request, but possibly the supplicant's state is not yet toggled - * to "scanning". That means, our internal scanning state "priv->scan_is_scanning" would already - * flip to idle, while in a moment the supplicant would toggle the state again. - * - * Artificially keep the scanning state on, for another SCAN_EXTRA_DELAY_MSEC msec. */ - nm_clear_g_source_inst (&priv->scan_request_delay_source); - priv->scan_request_delay_source = nm_g_source_attach (nm_g_timeout_source_new (SCAN_EXTRA_DELAY_MSEC, - G_PRIORITY_DEFAULT, - _scan_request_delay_cb, - self, - NULL), - NULL); + /* we just completed a scan request, but possibly the supplicant's state is not yet toggled + * to "scanning". That means, our internal scanning state "priv->scan_is_scanning" would already + * flip to idle, while in a moment the supplicant would toggle the state again. + * + * Artificially keep the scanning state on, for another SCAN_EXTRA_DELAY_MSEC msec. */ + nm_clear_g_source_inst(&priv->scan_request_delay_source); + priv->scan_request_delay_source = + nm_g_source_attach(nm_g_timeout_source_new(SCAN_EXTRA_DELAY_MSEC, + G_PRIORITY_DEFAULT, + _scan_request_delay_cb, + self, + NULL), + NULL); - g_clear_object (&priv->scan_request_cancellable); - _scan_notify_is_scanning (self); + g_clear_object(&priv->scan_request_cancellable); + _scan_notify_is_scanning(self); } static gboolean -_scan_kickoff_timeout_cb (gpointer user_data) +_scan_kickoff_timeout_cb(gpointer user_data) { - NMDeviceWifi *self = user_data; - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - priv->scan_kickoff_timeout_id = 0; - _scan_kickoff (self); - return G_SOURCE_REMOVE; + priv->scan_kickoff_timeout_id = 0; + _scan_kickoff(self); + return G_SOURCE_REMOVE; } static void -_scan_kickoff (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *ssids = NULL; - gboolean is_explict = FALSE; - NMDeviceState device_state; - gboolean has_hidden_profiles; - gint64 now_msec; - gint64 ratelimit_duration_msec; - - if (!priv->sup_iface) { - _LOGT_scan ("kickoff: don't scan (has no supplicant interface)"); - return; - } - - if (priv->scan_request_cancellable) { - _LOGT_scan ("kickoff: don't scan (has scan_request_cancellable)"); - /* We are currently waiting for a scan request to complete. Wait longer. */ - return; - } - - now_msec = nm_utils_get_monotonic_timestamp_msec (); - - _scan_request_ssids_remove_all (priv, now_msec, G_MAXUINT); - - device_state = nm_device_get_state (NM_DEVICE (self)); - if ( device_state > NM_DEVICE_STATE_DISCONNECTED - && device_state <= NM_DEVICE_STATE_ACTIVATED) { - /* while we are activated, we rate limit more. */ - ratelimit_duration_msec = 8000; - } else - ratelimit_duration_msec = 1500; - - if (priv->scan_last_request_started_at_msec + ratelimit_duration_msec > now_msec) { - _LOGT_scan ("kickoff: don't scan (rate limited for another %d.%03d sec%s)", - (int) ((priv->scan_last_request_started_at_msec + ratelimit_duration_msec - now_msec) / 1000), - (int) ((priv->scan_last_request_started_at_msec + ratelimit_duration_msec - now_msec) % 1000), - !priv->scan_kickoff_timeout_id ? ", schedule timeout" : ""); - if ( !priv->scan_kickoff_timeout_id - && ( priv->scan_explicit_allowed - || priv->scan_periodic_allowed)) { - priv->scan_kickoff_timeout_id = g_timeout_add (priv->scan_last_request_started_at_msec + ratelimit_duration_msec - now_msec, - _scan_kickoff_timeout_cb, - self); - } - return; - } - - if (priv->scan_explicit_requested) { - if (!priv->scan_explicit_allowed) { - _LOGT_scan ("kickoff: don't scan (explicit scan requested but not allowed)"); - return; - } - priv->scan_explicit_requested = FALSE; - is_explict = TRUE; - } else { - - if (!priv->scan_periodic_allowed) { - _LOGT_scan ("kickoff: don't scan (periodic scan currently not allowed)"); - priv->scan_periodic_next_msec = 0; - priv->scan_periodic_interval_sec = 0; - nm_clear_g_source (&priv->scan_kickoff_timeout_id); - return; - } - - nm_assert (priv->scan_explicit_allowed); - - if (now_msec < priv->scan_periodic_next_msec) { - _LOGT_scan ("kickoff: don't scan (periodic scan waiting for another %d.%03d sec%s)", - (int) ((priv->scan_periodic_next_msec - now_msec) / 1000), - (int) ((priv->scan_periodic_next_msec - now_msec) % 1000), - !priv->scan_kickoff_timeout_id ? ", schedule timeout" : ""); - if (!priv->scan_kickoff_timeout_id) { - priv->scan_kickoff_timeout_id = g_timeout_add_seconds ((priv->scan_periodic_next_msec - now_msec + 999) / 1000, - _scan_kickoff_timeout_cb, - self); - } - return; - } - - priv->scan_periodic_interval_sec = NM_CLAMP (((int) priv->scan_periodic_interval_sec) * 3 / 2, - SCAN_INTERVAL_SEC_MIN, - SCAN_INTERVAL_SEC_MAX); - priv->scan_periodic_next_msec = now_msec + 1000 * priv->scan_periodic_interval_sec; - } - - ssids = _scan_request_ssids_build_hidden (self, now_msec, &has_hidden_profiles); - if (has_hidden_profiles) { - if (priv->hidden_probe_scan_warn) { - priv->hidden_probe_scan_warn = FALSE; - _LOGW (LOGD_WIFI, "wifi-scan: active scanning for networks due to profiles with wifi.hidden=yes. This makes you trackable"); - } - } else if (!is_explict) - priv->hidden_probe_scan_warn = TRUE; - - if (_LOGD_ENABLED (LOGD_WIFI)) { - gs_free char *ssids_str = NULL; - guint ssids_len = 0; - - if (ssids) { - gs_strfreev char **strv = NULL; - guint i; - - strv = g_new (char *, ssids->len + 1u); - for (i = 0; i < ssids->len; i++) - strv[i] = _nm_utils_ssid_to_string (ssids->pdata[i]); - strv[i] = NULL; - - nm_assert (ssids->len > 0); - nm_assert (ssids->len == NM_PTRARRAY_LEN (strv)); - - ssids_str = g_strjoinv (", ", strv); - ssids_len = ssids->len; - } - _LOGD (LOGD_WIFI, "wifi-scan: start %s scan (%u SSIDs to probe scan%s%s%s)", - is_explict ? "explicit" : "periodic", - ssids_len, - NM_PRINT_FMT_QUOTED (ssids_str, " [", ssids_str, "]", "")); - } - - priv->scan_last_request_started_at_msec = now_msec; - - if (is_explict) - _LOGT_scan ("kickoff: explicit scan starting"); - else { - _LOGT_scan ("kickoff: periodic scan starting (next scan is scheduled in %d.%03d sec)", - (int) ((priv->scan_periodic_next_msec - now_msec) / 1000), - (int) ((priv->scan_periodic_next_msec - now_msec) % 1000)); - } - - _hw_addr_set_scanning (self, FALSE); - - priv->scan_request_cancellable = g_cancellable_new (); - nm_supplicant_interface_request_scan (priv->sup_iface, - ssids ? (GBytes *const*) ssids->pdata : NULL, - ssids ? ssids->len : 0u, - priv->scan_request_cancellable, - _scan_supplicant_request_scan_cb, - self); - - /* It's OK to call _scan_notify_is_scanning() again. They mutually call each other, - * but _scan_kickoff() sets "priv->scan_request_cancellable" which will stop - * them from recursing indefinitely. */ - _scan_notify_is_scanning (self); +_scan_kickoff(NMDeviceWifi *self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *ssids = NULL; + gboolean is_explict = FALSE; + NMDeviceState device_state; + gboolean has_hidden_profiles; + gint64 now_msec; + gint64 ratelimit_duration_msec; + + if (!priv->sup_iface) { + _LOGT_scan("kickoff: don't scan (has no supplicant interface)"); + return; + } + + if (priv->scan_request_cancellable) { + _LOGT_scan("kickoff: don't scan (has scan_request_cancellable)"); + /* We are currently waiting for a scan request to complete. Wait longer. */ + return; + } + + now_msec = nm_utils_get_monotonic_timestamp_msec(); + + _scan_request_ssids_remove_all(priv, now_msec, G_MAXUINT); + + device_state = nm_device_get_state(NM_DEVICE(self)); + if (device_state > NM_DEVICE_STATE_DISCONNECTED && device_state <= NM_DEVICE_STATE_ACTIVATED) { + /* while we are activated, we rate limit more. */ + ratelimit_duration_msec = 8000; + } else + ratelimit_duration_msec = 1500; + + if (priv->scan_last_request_started_at_msec + ratelimit_duration_msec > now_msec) { + _LOGT_scan( + "kickoff: don't scan (rate limited for another %d.%03d sec%s)", + (int) ((priv->scan_last_request_started_at_msec + ratelimit_duration_msec - now_msec) + / 1000), + (int) ((priv->scan_last_request_started_at_msec + ratelimit_duration_msec - now_msec) + % 1000), + !priv->scan_kickoff_timeout_id ? ", schedule timeout" : ""); + if (!priv->scan_kickoff_timeout_id + && (priv->scan_explicit_allowed || priv->scan_periodic_allowed)) { + priv->scan_kickoff_timeout_id = g_timeout_add(priv->scan_last_request_started_at_msec + + ratelimit_duration_msec - now_msec, + _scan_kickoff_timeout_cb, + self); + } + return; + } + + if (priv->scan_explicit_requested) { + if (!priv->scan_explicit_allowed) { + _LOGT_scan("kickoff: don't scan (explicit scan requested but not allowed)"); + return; + } + priv->scan_explicit_requested = FALSE; + is_explict = TRUE; + } else { + if (!priv->scan_periodic_allowed) { + _LOGT_scan("kickoff: don't scan (periodic scan currently not allowed)"); + priv->scan_periodic_next_msec = 0; + priv->scan_periodic_interval_sec = 0; + nm_clear_g_source(&priv->scan_kickoff_timeout_id); + return; + } + + nm_assert(priv->scan_explicit_allowed); + + if (now_msec < priv->scan_periodic_next_msec) { + _LOGT_scan("kickoff: don't scan (periodic scan waiting for another %d.%03d sec%s)", + (int) ((priv->scan_periodic_next_msec - now_msec) / 1000), + (int) ((priv->scan_periodic_next_msec - now_msec) % 1000), + !priv->scan_kickoff_timeout_id ? ", schedule timeout" : ""); + if (!priv->scan_kickoff_timeout_id) { + priv->scan_kickoff_timeout_id = + g_timeout_add_seconds((priv->scan_periodic_next_msec - now_msec + 999) / 1000, + _scan_kickoff_timeout_cb, + self); + } + return; + } + + priv->scan_periodic_interval_sec = + NM_CLAMP(((int) priv->scan_periodic_interval_sec) * 3 / 2, + SCAN_INTERVAL_SEC_MIN, + SCAN_INTERVAL_SEC_MAX); + priv->scan_periodic_next_msec = now_msec + 1000 * priv->scan_periodic_interval_sec; + } + + ssids = _scan_request_ssids_build_hidden(self, now_msec, &has_hidden_profiles); + if (has_hidden_profiles) { + if (priv->hidden_probe_scan_warn) { + priv->hidden_probe_scan_warn = FALSE; + _LOGW(LOGD_WIFI, + "wifi-scan: active scanning for networks due to profiles with wifi.hidden=yes. " + "This makes you trackable"); + } + } else if (!is_explict) + priv->hidden_probe_scan_warn = TRUE; + + if (_LOGD_ENABLED(LOGD_WIFI)) { + gs_free char *ssids_str = NULL; + guint ssids_len = 0; + + if (ssids) { + gs_strfreev char **strv = NULL; + guint i; + + strv = g_new(char *, ssids->len + 1u); + for (i = 0; i < ssids->len; i++) + strv[i] = _nm_utils_ssid_to_string(ssids->pdata[i]); + strv[i] = NULL; + + nm_assert(ssids->len > 0); + nm_assert(ssids->len == NM_PTRARRAY_LEN(strv)); + + ssids_str = g_strjoinv(", ", strv); + ssids_len = ssids->len; + } + _LOGD(LOGD_WIFI, + "wifi-scan: start %s scan (%u SSIDs to probe scan%s%s%s)", + is_explict ? "explicit" : "periodic", + ssids_len, + NM_PRINT_FMT_QUOTED(ssids_str, " [", ssids_str, "]", "")); + } + + priv->scan_last_request_started_at_msec = now_msec; + + if (is_explict) + _LOGT_scan("kickoff: explicit scan starting"); + else { + _LOGT_scan("kickoff: periodic scan starting (next scan is scheduled in %d.%03d sec)", + (int) ((priv->scan_periodic_next_msec - now_msec) / 1000), + (int) ((priv->scan_periodic_next_msec - now_msec) % 1000)); + } + + _hw_addr_set_scanning(self, FALSE); + + priv->scan_request_cancellable = g_cancellable_new(); + nm_supplicant_interface_request_scan(priv->sup_iface, + ssids ? (GBytes *const *) ssids->pdata : NULL, + ssids ? ssids->len : 0u, + priv->scan_request_cancellable, + _scan_supplicant_request_scan_cb, + self); + + /* It's OK to call _scan_notify_is_scanning() again. They mutually call each other, + * but _scan_kickoff() sets "priv->scan_request_cancellable" which will stop + * them from recursing indefinitely. */ + _scan_notify_is_scanning(self); } /**************************************************************************** @@ -1832,345 +1852,340 @@ _scan_kickoff (NMDeviceWifi *self) */ static gboolean -ap_list_dump (gpointer user_data) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - priv->ap_dump_id = 0; - - if (_LOGD_ENABLED (LOGD_WIFI_SCAN)) { - NMWifiAP *ap; - gint64 now_msec = nm_utils_get_monotonic_timestamp_msec (); - char str_buf[100]; - - _LOGD (LOGD_WIFI_SCAN, "APs: [now:%u.%03u, last:%s]", - (guint) (now_msec / NM_UTILS_MSEC_PER_SEC), - (guint) (now_msec % NM_UTILS_MSEC_PER_SEC), - priv->scan_last_complete_msec > 0 - ? nm_sprintf_buf (str_buf, - "%u.%03u", - (guint) (priv->scan_last_complete_msec / NM_UTILS_MSEC_PER_SEC), - (guint) (priv->scan_last_complete_msec % NM_UTILS_MSEC_PER_SEC)) - : "-1"); - c_list_for_each_entry (ap, &priv->aps_lst_head, aps_lst) - _ap_dump (self, LOGL_DEBUG, ap, "dump", now_msec); - } - return G_SOURCE_REMOVE; +ap_list_dump(gpointer user_data) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(user_data); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + priv->ap_dump_id = 0; + + if (_LOGD_ENABLED(LOGD_WIFI_SCAN)) { + NMWifiAP *ap; + gint64 now_msec = nm_utils_get_monotonic_timestamp_msec(); + char str_buf[100]; + + _LOGD(LOGD_WIFI_SCAN, + "APs: [now:%u.%03u, last:%s]", + (guint)(now_msec / NM_UTILS_MSEC_PER_SEC), + (guint)(now_msec % NM_UTILS_MSEC_PER_SEC), + priv->scan_last_complete_msec > 0 + ? nm_sprintf_buf(str_buf, + "%u.%03u", + (guint)(priv->scan_last_complete_msec / NM_UTILS_MSEC_PER_SEC), + (guint)(priv->scan_last_complete_msec % NM_UTILS_MSEC_PER_SEC)) + : "-1"); + c_list_for_each_entry (ap, &priv->aps_lst_head, aps_lst) + _ap_dump(self, LOGL_DEBUG, ap, "dump", now_msec); + } + return G_SOURCE_REMOVE; } static void -schedule_ap_list_dump (NMDeviceWifi *self) +schedule_ap_list_dump(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - if ( !priv->ap_dump_id - && _LOGD_ENABLED (LOGD_WIFI_SCAN)) - priv->ap_dump_id = g_timeout_add_seconds (1, ap_list_dump, self); + if (!priv->ap_dump_id && _LOGD_ENABLED(LOGD_WIFI_SCAN)) + priv->ap_dump_id = g_timeout_add_seconds(1, ap_list_dump, self); } static void -try_fill_ssid_for_hidden_ap (NMDeviceWifi *self, - NMWifiAP *ap) +try_fill_ssid_for_hidden_ap(NMDeviceWifi *self, NMWifiAP *ap) { - const char *bssid; - NMSettingsConnection *const*connections; - guint i; + const char * bssid; + NMSettingsConnection *const *connections; + guint i; - g_return_if_fail (nm_wifi_ap_get_ssid (ap) == NULL); + g_return_if_fail(nm_wifi_ap_get_ssid(ap) == NULL); - bssid = nm_wifi_ap_get_address (ap); - g_return_if_fail (bssid); + bssid = nm_wifi_ap_get_address(ap); + g_return_if_fail(bssid); - /* Look for this AP's BSSID in the seen-bssids list of a connection, - * and if a match is found, copy over the SSID */ - connections = nm_settings_get_connections (nm_device_get_settings ((NMDevice *) self), NULL); - for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; - NMSettingWireless *s_wifi; + /* Look for this AP's BSSID in the seen-bssids list of a connection, + * and if a match is found, copy over the SSID */ + connections = nm_settings_get_connections(nm_device_get_settings((NMDevice *) self), NULL); + for (i = 0; connections[i]; i++) { + NMSettingsConnection *sett_conn = connections[i]; + NMSettingWireless * s_wifi; - if (!nm_settings_connection_has_seen_bssid (sett_conn, bssid)) - continue; - s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn)); - if (!s_wifi) - continue; + if (!nm_settings_connection_has_seen_bssid(sett_conn, bssid)) + continue; + s_wifi = + nm_connection_get_setting_wireless(nm_settings_connection_get_connection(sett_conn)); + if (!s_wifi) + continue; - nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); - break; - } + nm_wifi_ap_set_ssid(ap, nm_setting_wireless_get_ssid(s_wifi)); + break; + } } static void -supplicant_iface_bss_changed_cb (NMSupplicantInterface *iface, - NMSupplicantBssInfo *bss_info, - gboolean is_present, - NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMWifiAP *found_ap; - GBytes *ssid; - - found_ap = g_hash_table_lookup (priv->aps_idx_by_supplicant_path, bss_info->bss_path); - - if (!is_present) { - if (!found_ap) - return; - if (found_ap == priv->current_ap) { - /* The current AP cannot be removed (to prevent NM indicating that - * it is connected, but to nothing), but it must be removed later - * when the current AP is changed or cleared. Set 'fake' to - * indicate that this AP is now unknown to the supplicant. - */ - if (nm_wifi_ap_set_fake (found_ap, TRUE)) - _ap_dump (self, LOGL_DEBUG, found_ap, "updated", 0); - } else { - ap_add_remove (self, FALSE, found_ap, TRUE); - schedule_ap_list_dump (self); - } - return; - } - - if (found_ap) { - if (!nm_wifi_ap_update_from_properties (found_ap, bss_info)) - return; - _ap_dump (self, LOGL_DEBUG, found_ap, "updated", 0); - } else { - gs_unref_object NMWifiAP *ap = NULL; - - if (!bss_info->bssid_valid) { - /* We failed to initialize the info about the AP. This can - * happen due to an error in the D-Bus communication. In this case - * we ignore the info. */ - return; - } - - ap = nm_wifi_ap_new_from_properties (bss_info); - - /* Let the manager try to fill in the SSID from seen-bssids lists */ - ssid = nm_wifi_ap_get_ssid (ap); - if (!ssid || _nm_utils_is_empty_ssid (ssid)) { - /* Try to fill the SSID from the AP database */ - try_fill_ssid_for_hidden_ap (self, ap); - - ssid = nm_wifi_ap_get_ssid (ap); - if ( ssid - && !_nm_utils_is_empty_ssid (ssid)) { - gs_free char *s = NULL; - - /* Yay, matched it, no longer treat as hidden */ - _LOGD (LOGD_WIFI, "matched hidden AP %s => %s", - nm_wifi_ap_get_address (ap), - (s = _nm_utils_ssid_to_string (ssid))); - } else { - /* Didn't have an entry for this AP in the database */ - _LOGD (LOGD_WIFI, "failed to match hidden AP %s", - nm_wifi_ap_get_address (ap)); - } - } - - ap_add_remove (self, TRUE, ap, TRUE); - } - - /* Update the current AP if the supplicant notified a current BSS change - * before it sent the current BSS's scan result. - */ - if (nm_supplicant_interface_get_current_bss (iface) == bss_info->bss_path) - supplicant_iface_notify_current_bss (priv->sup_iface, NULL, self); - - schedule_ap_list_dump (self); +supplicant_iface_bss_changed_cb(NMSupplicantInterface *iface, + NMSupplicantBssInfo * bss_info, + gboolean is_present, + NMDeviceWifi * self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMWifiAP * found_ap; + GBytes * ssid; + + found_ap = g_hash_table_lookup(priv->aps_idx_by_supplicant_path, bss_info->bss_path); + + if (!is_present) { + if (!found_ap) + return; + if (found_ap == priv->current_ap) { + /* The current AP cannot be removed (to prevent NM indicating that + * it is connected, but to nothing), but it must be removed later + * when the current AP is changed or cleared. Set 'fake' to + * indicate that this AP is now unknown to the supplicant. + */ + if (nm_wifi_ap_set_fake(found_ap, TRUE)) + _ap_dump(self, LOGL_DEBUG, found_ap, "updated", 0); + } else { + ap_add_remove(self, FALSE, found_ap, TRUE); + schedule_ap_list_dump(self); + } + return; + } + + if (found_ap) { + if (!nm_wifi_ap_update_from_properties(found_ap, bss_info)) + return; + _ap_dump(self, LOGL_DEBUG, found_ap, "updated", 0); + } else { + gs_unref_object NMWifiAP *ap = NULL; + + if (!bss_info->bssid_valid) { + /* We failed to initialize the info about the AP. This can + * happen due to an error in the D-Bus communication. In this case + * we ignore the info. */ + return; + } + + ap = nm_wifi_ap_new_from_properties(bss_info); + + /* Let the manager try to fill in the SSID from seen-bssids lists */ + ssid = nm_wifi_ap_get_ssid(ap); + if (!ssid || _nm_utils_is_empty_ssid(ssid)) { + /* Try to fill the SSID from the AP database */ + try_fill_ssid_for_hidden_ap(self, ap); + + ssid = nm_wifi_ap_get_ssid(ap); + if (ssid && !_nm_utils_is_empty_ssid(ssid)) { + gs_free char *s = NULL; + + /* Yay, matched it, no longer treat as hidden */ + _LOGD(LOGD_WIFI, + "matched hidden AP %s => %s", + nm_wifi_ap_get_address(ap), + (s = _nm_utils_ssid_to_string(ssid))); + } else { + /* Didn't have an entry for this AP in the database */ + _LOGD(LOGD_WIFI, "failed to match hidden AP %s", nm_wifi_ap_get_address(ap)); + } + } + + ap_add_remove(self, TRUE, ap, TRUE); + } + + /* Update the current AP if the supplicant notified a current BSS change + * before it sent the current BSS's scan result. + */ + if (nm_supplicant_interface_get_current_bss(iface) == bss_info->bss_path) + supplicant_iface_notify_current_bss(priv->sup_iface, NULL, self); + + schedule_ap_list_dump(self); } static void -cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) +cleanup_association_attempt(NMDeviceWifi *self, gboolean disconnect) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_clear_g_source (&priv->sup_timeout_id); - nm_clear_g_source (&priv->link_timeout_id); - nm_clear_g_source (&priv->wps_timeout_id); - if (disconnect && priv->sup_iface) - nm_supplicant_interface_disconnect (priv->sup_iface); + nm_clear_g_source(&priv->sup_timeout_id); + nm_clear_g_source(&priv->link_timeout_id); + nm_clear_g_source(&priv->wps_timeout_id); + if (disconnect && priv->sup_iface) + nm_supplicant_interface_disconnect(priv->sup_iface); } static void -cleanup_supplicant_failures (NMDeviceWifi *self) +cleanup_supplicant_failures(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_clear_g_source (&priv->reacquire_iface_id); - priv->failed_iface_count = 0; + nm_clear_g_source(&priv->reacquire_iface_id); + priv->failed_iface_count = 0; } static void -wifi_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *connection, - GError *error, - gpointer user_data) -{ - NMDevice *device = user_data; - NMDeviceWifi *self = user_data; - NMDeviceWifiPrivate *priv; - - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - - g_return_if_fail (priv->wifi_secrets_id == call_id); - - priv->wifi_secrets_id = NULL; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - 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); - g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); - - if (error) { - _LOGW (LOGD_WIFI, "no secrets: %s", error->message); - - /* Even if WPS is still pending, let's abort the activation when the secret - * request returns. - * - * This means, a user can only effectively use WPS when also running a secret - * agent, and pressing the push button while being prompted for the password. - * Note, that in the secret prompt the user can see that WPS is in progress - * (via the NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE flag). - * - * Previously, WPS was not cancelled when the secret request returns. - * Note that in common use-cases WPS is enabled in the connection profile - * but it won't succeed (because it's disabled in the AP or because the - * user is not prepared to press the push button). - * That means for example, during boot we would try to autoconnect with WPS. - * At that point, there is no secret-agent running, and WPS is pending for - * full 30 seconds. If in the meantime a secret agent registers (because - * of logging into the DE), the profile is still busy waiting for WPS to time - * out. Only after that delay, autoconnect starts again (note that autoconnect gets - * not blocked in this case, because a secret agent registered in the meantime). - * - * It seems wrong to continue doing WPS if the user is not aware - * that WPS is ongoing. The user is required to perform an action (push button), - * and must be told via the secret prompt. - * If no secret-agent is running, if the user cancels the secret-request, or any - * other error to obtain secrets, the user apparently does not want WPS either. - */ - nm_clear_g_source (&priv->wps_timeout_id); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } - - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); +wifi_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * connection, + GError * error, + gpointer user_data) +{ + NMDevice * device = user_data; + NMDeviceWifi * self = user_data; + NMDeviceWifiPrivate *priv; + + g_return_if_fail(NM_IS_DEVICE_WIFI(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + + priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + + g_return_if_fail(priv->wifi_secrets_id == call_id); + + priv->wifi_secrets_id = NULL; + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + 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); + g_return_if_fail(nm_act_request_get_settings_connection(req) == connection); + + if (error) { + _LOGW(LOGD_WIFI, "no secrets: %s", error->message); + + /* Even if WPS is still pending, let's abort the activation when the secret + * request returns. + * + * This means, a user can only effectively use WPS when also running a secret + * agent, and pressing the push button while being prompted for the password. + * Note, that in the secret prompt the user can see that WPS is in progress + * (via the NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE flag). + * + * Previously, WPS was not cancelled when the secret request returns. + * Note that in common use-cases WPS is enabled in the connection profile + * but it won't succeed (because it's disabled in the AP or because the + * user is not prepared to press the push button). + * That means for example, during boot we would try to autoconnect with WPS. + * At that point, there is no secret-agent running, and WPS is pending for + * full 30 seconds. If in the meantime a secret agent registers (because + * of logging into the DE), the profile is still busy waiting for WPS to time + * out. Only after that delay, autoconnect starts again (note that autoconnect gets + * not blocked in this case, because a secret agent registered in the meantime). + * + * It seems wrong to continue doing WPS if the user is not aware + * that WPS is ongoing. The user is required to perform an action (push button), + * and must be told via the secret prompt. + * If no secret-agent is running, if the user cancels the secret-request, or any + * other error to obtain secrets, the user apparently does not want WPS either. + */ + nm_clear_g_source(&priv->wps_timeout_id); + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } + + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -wifi_secrets_cancel (NMDeviceWifi *self) +wifi_secrets_cancel(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - if (priv->wifi_secrets_id) - nm_act_request_cancel_secrets (NULL, priv->wifi_secrets_id); - nm_assert (!priv->wifi_secrets_id); + if (priv->wifi_secrets_id) + nm_act_request_cancel_secrets(NULL, priv->wifi_secrets_id); + nm_assert(!priv->wifi_secrets_id); } static void -supplicant_iface_wps_credentials_cb (NMSupplicantInterface *iface, - GVariant *credentials, - NMDeviceWifi *self) -{ - NMActRequest *req; - gs_unref_variant GVariant *val_key = NULL; - gs_unref_variant GVariant *secrets = NULL; - gs_free_error GError *error = NULL; - const char *array; - gsize psk_len = 0; - - if (nm_device_get_state (NM_DEVICE (self)) != NM_DEVICE_STATE_NEED_AUTH) { - _LOGI (LOGD_DEVICE | LOGD_WIFI, "WPS: The connection can't be updated with credentials"); - return; - } - - _LOGI (LOGD_DEVICE | LOGD_WIFI, "WPS: Updating the connection with credentials"); - - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - val_key = g_variant_lookup_value (credentials, "Key", G_VARIANT_TYPE_BYTESTRING); - if (val_key) { - char psk[64]; - - array = g_variant_get_fixed_array (val_key, &psk_len, 1); - if (psk_len >= 8 && psk_len <= 63) { - memcpy (psk, array, psk_len); - psk[psk_len] = '\0'; - if (g_utf8_validate (psk, psk_len, NULL)) { - secrets = g_variant_new_parsed ("[{%s, [{%s, <%s>}]}]", - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PSK, psk); - g_variant_ref_sink (secrets); - } - } - if (!secrets) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "WPS: ignore invalid PSK"); - } - - if (!secrets) - return; - - if (!nm_settings_connection_new_secrets (nm_act_request_get_settings_connection (req), - nm_act_request_get_applied_connection (req), - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - secrets, - &error)) { - _LOGW (LOGD_DEVICE | LOGD_WIFI, "WPS: Could not update the connection with credentials: %s", error->message); - return; - } - - wifi_secrets_cancel (self); - nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self), FALSE); +supplicant_iface_wps_credentials_cb(NMSupplicantInterface *iface, + GVariant * credentials, + NMDeviceWifi * self) +{ + NMActRequest * req; + gs_unref_variant GVariant *val_key = NULL; + gs_unref_variant GVariant *secrets = NULL; + gs_free_error GError *error = NULL; + const char * array; + gsize psk_len = 0; + + if (nm_device_get_state(NM_DEVICE(self)) != NM_DEVICE_STATE_NEED_AUTH) { + _LOGI(LOGD_DEVICE | LOGD_WIFI, "WPS: The connection can't be updated with credentials"); + return; + } + + _LOGI(LOGD_DEVICE | LOGD_WIFI, "WPS: Updating the connection with credentials"); + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); + + val_key = g_variant_lookup_value(credentials, "Key", G_VARIANT_TYPE_BYTESTRING); + if (val_key) { + char psk[64]; + + array = g_variant_get_fixed_array(val_key, &psk_len, 1); + if (psk_len >= 8 && psk_len <= 63) { + memcpy(psk, array, psk_len); + psk[psk_len] = '\0'; + if (g_utf8_validate(psk, psk_len, NULL)) { + secrets = g_variant_new_parsed("[{%s, [{%s, <%s>}]}]", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK, + psk); + g_variant_ref_sink(secrets); + } + } + if (!secrets) + _LOGW(LOGD_DEVICE | LOGD_WIFI, "WPS: ignore invalid PSK"); + } + + if (!secrets) + return; + + if (!nm_settings_connection_new_secrets(nm_act_request_get_settings_connection(req), + nm_act_request_get_applied_connection(req), + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error)) { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "WPS: Could not update the connection with credentials: %s", + error->message); + return; + } + + wifi_secrets_cancel(self); + nm_device_activate_schedule_stage1_device_prepare(NM_DEVICE(self), FALSE); } static gboolean -wps_timeout_cb (gpointer user_data) +wps_timeout_cb(gpointer user_data) { - NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = NM_DEVICE_WIFI(user_data); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - priv->wps_timeout_id = 0; - if (!priv->wifi_secrets_id) { - /* Fail only if the secrets are not being requested. */ - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - } + priv->wps_timeout_id = 0; + if (!priv->wifi_secrets_id) { + /* Fail only if the secrets are not being requested. */ + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -wifi_secrets_get_secrets (NMDeviceWifi *self, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags) +wifi_secrets_get_secrets(NMDeviceWifi * self, + const char * setting_name, + NMSecretAgentGetSecretsFlags flags) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMActRequest *req; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMActRequest * req; - wifi_secrets_cancel (self); + wifi_secrets_cancel(self); - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(NM_IS_ACT_REQUEST(req)); - priv->wifi_secrets_id = nm_act_request_get_secrets (req, - TRUE, - setting_name, - flags, - NULL, - wifi_secrets_cb, - self); - g_return_if_fail (priv->wifi_secrets_id); + priv->wifi_secrets_id = + nm_act_request_get_secrets(req, TRUE, setting_name, flags, NULL, wifi_secrets_cb, self); + g_return_if_fail(priv->wifi_secrets_id); } /* @@ -2180,399 +2195,406 @@ wifi_secrets_get_secrets (NMDeviceWifi *self, * period of time. */ static gboolean -link_timeout_cb (gpointer user_data) +link_timeout_cb(gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - _LOGW (LOGD_WIFI, "link timed out."); + _LOGW(LOGD_WIFI, "link timed out."); - priv->link_timeout_id = 0; + priv->link_timeout_id = 0; - /* Disconnect event while activated; the supplicant hasn't been able - * to reassociate within the timeout period, so the connection must - * fail. - */ - if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) - return FALSE; + /* Disconnect event while activated; the supplicant hasn't been able + * to reassociate within the timeout period, so the connection must + * fail. + */ + if (nm_device_get_state(device) != NM_DEVICE_STATE_ACTIVATED) + return FALSE; - set_current_ap (self, NULL, TRUE); + set_current_ap(self, NULL, TRUE); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : - NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); - return FALSE; + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT + : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); + return FALSE; } static gboolean -need_new_8021x_secrets (NMDeviceWifi *self, - NMSupplicantInterfaceState old_state, - const char **setting_name) -{ - NMSetting8021x *s_8021x; - NMSettingWirelessSecurity *s_wsec; - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - NMConnection *connection; - - g_return_val_if_fail (setting_name, FALSE); - - connection = nm_device_get_applied_connection (NM_DEVICE (self)); - - g_return_val_if_fail (connection != NULL, FALSE); - - /* 802.1x stuff only happens in the supplicant's ASSOCIATED state when it's - * attempting to authenticate with the AP. - */ - if (old_state != NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED) - return FALSE; - - /* If it's an 802.1x or LEAP connection with "always ask"/unsaved secrets - * then we need to ask again because it might be an OTP token and the PIN - * may have changed. - */ - - s_8021x = nm_connection_get_setting_802_1x (connection); - if (s_8021x) { - if (!nm_setting_get_secret_flags (NM_SETTING (s_8021x), - NM_SETTING_802_1X_PASSWORD, - &secret_flags, - NULL)) - g_assert_not_reached (); - if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) - *setting_name = NM_SETTING_802_1X_SETTING_NAME; - return *setting_name ? TRUE : FALSE; - } - - s_wsec = nm_connection_get_setting_wireless_security (connection); - if (s_wsec) { - if (!nm_setting_get_secret_flags (NM_SETTING (s_wsec), - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - &secret_flags, - NULL)) - g_assert_not_reached (); - if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) - *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - return *setting_name ? TRUE : FALSE; - } - - /* Not a LEAP or 802.1x connection */ - return FALSE; +need_new_8021x_secrets(NMDeviceWifi * self, + NMSupplicantInterfaceState old_state, + const char ** setting_name) +{ + NMSetting8021x * s_8021x; + NMSettingWirelessSecurity *s_wsec; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + NMConnection * connection; + + g_return_val_if_fail(setting_name, FALSE); + + connection = nm_device_get_applied_connection(NM_DEVICE(self)); + + g_return_val_if_fail(connection != NULL, FALSE); + + /* 802.1x stuff only happens in the supplicant's ASSOCIATED state when it's + * attempting to authenticate with the AP. + */ + if (old_state != NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED) + return FALSE; + + /* If it's an 802.1x or LEAP connection with "always ask"/unsaved secrets + * then we need to ask again because it might be an OTP token and the PIN + * may have changed. + */ + + s_8021x = nm_connection_get_setting_802_1x(connection); + if (s_8021x) { + if (!nm_setting_get_secret_flags(NM_SETTING(s_8021x), + NM_SETTING_802_1X_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached(); + if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) + *setting_name = NM_SETTING_802_1X_SETTING_NAME; + return *setting_name ? TRUE : FALSE; + } + + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (s_wsec) { + if (!nm_setting_get_secret_flags(NM_SETTING(s_wsec), + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached(); + if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) + *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + return *setting_name ? TRUE : FALSE; + } + + /* Not a LEAP or 802.1x connection */ + return FALSE; } static gboolean -need_new_wpa_psk (NMDeviceWifi *self, - NMSupplicantInterfaceState old_state, - int disconnect_reason, - const char **setting_name) +need_new_wpa_psk(NMDeviceWifi * self, + NMSupplicantInterfaceState old_state, + int disconnect_reason, + const char ** setting_name) { - NMSettingWirelessSecurity *s_wsec; - NMConnection *connection; - const char *key_mgmt = NULL; + NMSettingWirelessSecurity *s_wsec; + NMConnection * connection; + const char * key_mgmt = NULL; - g_return_val_if_fail (setting_name, FALSE); + g_return_val_if_fail(setting_name, FALSE); - connection = nm_device_get_applied_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection(NM_DEVICE(self)); - g_return_val_if_fail (connection, FALSE); + g_return_val_if_fail(connection, FALSE); - /* A bad PSK will cause the supplicant to disconnect during the 4-way handshake */ - if (old_state != NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE) - return FALSE; + /* A bad PSK will cause the supplicant to disconnect during the 4-way handshake */ + if (old_state != NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE) + return FALSE; - s_wsec = nm_connection_get_setting_wireless_security (connection); - if (s_wsec) - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (s_wsec) + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); - if (g_strcmp0 (key_mgmt, "wpa-psk") == 0) { - /* -4 (locally-generated WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY) usually - * means the driver missed beacons from the AP. This usually happens - * due to driver bugs or faulty power-save management. It doesn't - * indicate that the PSK is wrong. - */ - #define LOCAL_WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY -4 - if (disconnect_reason == LOCAL_WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY) - return FALSE; + if (g_strcmp0(key_mgmt, "wpa-psk") == 0) { +/* -4 (locally-generated WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY) usually + * means the driver missed beacons from the AP. This usually happens + * due to driver bugs or faulty power-save management. It doesn't + * indicate that the PSK is wrong. + */ +#define LOCAL_WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY -4 + if (disconnect_reason == LOCAL_WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY) + return FALSE; - *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; - return TRUE; - } + *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + return TRUE; + } - /* Not a WPA-PSK connection */ - return FALSE; + /* Not a WPA-PSK connection */ + return FALSE; } static gboolean -handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, - NMSupplicantInterfaceState new_state, - NMSupplicantInterfaceState old_state, - int disconnect_reason) +handle_8021x_or_psk_auth_fail(NMDeviceWifi * self, + NMSupplicantInterfaceState new_state, + NMSupplicantInterfaceState old_state, + int disconnect_reason) { - NMDevice *device = NM_DEVICE (self); - NMActRequest *req; - const char *setting_name = NULL; - gboolean handled = FALSE; + NMDevice * device = NM_DEVICE(self); + NMActRequest *req; + const char * setting_name = NULL; + gboolean handled = FALSE; - g_return_val_if_fail (new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE); + g_return_val_if_fail(new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE); - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_val_if_fail (req != NULL, FALSE); + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_val_if_fail(req != NULL, FALSE); - if ( need_new_8021x_secrets (self, old_state, &setting_name) - || need_new_wpa_psk (self, old_state, disconnect_reason, &setting_name)) { + if (need_new_8021x_secrets(self, old_state, &setting_name) + || need_new_wpa_psk(self, old_state, disconnect_reason, &setting_name)) { + nm_act_request_clear_secrets(req); - nm_act_request_clear_secrets (req); + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) disconnected during association, asking for new key"); - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) disconnected during association, asking for new key"); + cleanup_association_attempt(self, TRUE); + nm_device_state_changed(device, + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + wifi_secrets_get_secrets(self, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + handled = TRUE; + } - cleanup_association_attempt (self, TRUE); - nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); - wifi_secrets_get_secrets (self, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION - | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); - handled = TRUE; - } - - return handled; + return handled; } static gboolean -reacquire_interface_cb (gpointer user_data) +reacquire_interface_cb(gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - priv->reacquire_iface_id = 0; - priv->failed_iface_count++; + priv->reacquire_iface_id = 0; + priv->failed_iface_count++; - _LOGW (LOGD_WIFI, "re-acquiring supplicant interface (#%d).", priv->failed_iface_count); + _LOGW(LOGD_WIFI, "re-acquiring supplicant interface (#%d).", priv->failed_iface_count); - if (!priv->sup_iface) - supplicant_interface_acquire (self); + if (!priv->sup_iface) + supplicant_interface_acquire(self); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -supplicant_iface_state_down (NMDeviceWifi *self) +supplicant_iface_state_down(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - cleanup_association_attempt (self, FALSE); + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + cleanup_association_attempt(self, FALSE); - /* If the device is already in UNAVAILABLE state then the state change - * is a NOP and the interface won't be re-acquired in the device state - * change handler. So ensure we have a new one here so that we're - * ready if the supplicant comes back. - */ - supplicant_interface_release (self); - if (priv->failed_iface_count < 5) - priv->reacquire_iface_id = g_timeout_add_seconds (10, reacquire_interface_cb, self); - else - _LOGI (LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up"); + /* If the device is already in UNAVAILABLE state then the state change + * is a NOP and the interface won't be re-acquired in the device state + * change handler. So ensure we have a new one here so that we're + * ready if the supplicant comes back. + */ + supplicant_interface_release(self); + if (priv->failed_iface_count < 5) + priv->reacquire_iface_id = g_timeout_add_seconds(10, reacquire_interface_cb, self); + else + _LOGI(LOGD_DEVICE | LOGD_WIFI, "supplicant interface keeps failing, giving up"); } static void -supplicant_iface_state (NMDeviceWifi *self, - NMSupplicantInterfaceState new_state, - NMSupplicantInterfaceState old_state, - int disconnect_reason, - gboolean is_real_signal) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMDeviceState devstate; - gboolean scanning; - gboolean scan_changed; - - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "supplicant interface state: %s -> %s%s", - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state), - is_real_signal ? "" : " (simulated signal)"); - - if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { - supplicant_iface_state_down (self); - goto out; - } - - devstate = nm_device_get_state (device); - scanning = nm_supplicant_interface_get_scanning (priv->sup_iface); - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { - _LOGD (LOGD_WIFI, "supplicant ready"); - nm_device_queue_recheck_available (NM_DEVICE (device), - NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - priv->scan_periodic_interval_sec = 0; - priv->scan_periodic_next_msec = 0; - } - - /* In these states we know the supplicant is actually talking to something */ - if ( new_state >= NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING - && new_state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) - priv->ssid_found = TRUE; - - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) - recheck_p2p_availability (self); - - switch (new_state) { - case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED: - nm_clear_g_source (&priv->sup_timeout_id); - nm_clear_g_source (&priv->link_timeout_id); - nm_clear_g_source (&priv->wps_timeout_id); - - /* If this is the initial association during device activation, - * schedule the next activation stage. - */ - if (devstate == NM_DEVICE_STATE_CONFIG) { - NMSettingWireless *s_wifi; - GBytes *ssid; - gs_free char *ssid_str = NULL; - - s_wifi = nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_WIRELESS); - - g_return_if_fail (s_wifi); - - ssid = nm_setting_wireless_get_ssid (s_wifi); - g_return_if_fail (ssid); - - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s %s", - priv->mode == NM_802_11_MODE_AP - ? "Started Wi-Fi Hotspot" - : "Connected to wireless network", - (ssid_str = _nm_utils_ssid_to_string (ssid))); - nm_device_activate_schedule_stage3_ip_config_start (device); - } else if (devstate == NM_DEVICE_STATE_ACTIVATED) - periodic_update (self); - break; - case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED: - if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) { - /* Disconnect of an 802.1x/LEAP connection during authentication, - * or disconnect of a WPA-PSK connection during the 4-way handshake, - * often means secrets are wrong. Not always the case, but until we - * have more information from wpa_supplicant about why the - * disconnect happened this is the best we can do. - */ - if (handle_8021x_or_psk_auth_fail (self, new_state, old_state, disconnect_reason)) - break; - } - - /* Otherwise it might be a stupid driver or some transient error, so - * let the supplicant try to reconnect a few more times. Give it more - * time if a scan is in progress since the link might be dropped during - * the scan but will be re-established when the scan is done. - */ - if (devstate == NM_DEVICE_STATE_ACTIVATED) { - if (priv->link_timeout_id == 0) { - priv->link_timeout_id = g_timeout_add_seconds (scanning ? 30 : 15, link_timeout_cb, self); - priv->ssid_found = FALSE; - } - } - break; - case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE: - /* we would clear _scan_has_pending_action_set() and trigger a new scan. - * However, we don't want to cancel the current pending action, so force - * a new scan request. */ - break; - default: - break; - } +supplicant_iface_state(NMDeviceWifi * self, + NMSupplicantInterfaceState new_state, + NMSupplicantInterfaceState old_state, + int disconnect_reason, + gboolean is_real_signal) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMDeviceState devstate; + gboolean scanning; + gboolean scan_changed; + + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "supplicant interface state: %s -> %s%s", + nm_supplicant_interface_state_to_string(old_state), + nm_supplicant_interface_state_to_string(new_state), + is_real_signal ? "" : " (simulated signal)"); + + if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { + supplicant_iface_state_down(self); + goto out; + } + + devstate = nm_device_get_state(device); + scanning = nm_supplicant_interface_get_scanning(priv->sup_iface); + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) { + _LOGD(LOGD_WIFI, "supplicant ready"); + nm_device_queue_recheck_available(NM_DEVICE(device), + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + priv->scan_periodic_interval_sec = 0; + priv->scan_periodic_next_msec = 0; + } + + /* In these states we know the supplicant is actually talking to something */ + if (new_state >= NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING + && new_state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) + priv->ssid_found = TRUE; + + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) + recheck_p2p_availability(self); + + switch (new_state) { + case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED: + nm_clear_g_source(&priv->sup_timeout_id); + nm_clear_g_source(&priv->link_timeout_id); + nm_clear_g_source(&priv->wps_timeout_id); + + /* If this is the initial association during device activation, + * schedule the next activation stage. + */ + if (devstate == NM_DEVICE_STATE_CONFIG) { + NMSettingWireless *s_wifi; + GBytes * ssid; + gs_free char * ssid_str = NULL; + + s_wifi = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_WIRELESS); + + g_return_if_fail(s_wifi); + + ssid = nm_setting_wireless_get_ssid(s_wifi); + g_return_if_fail(ssid); + + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s %s", + priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" + : "Connected to wireless network", + (ssid_str = _nm_utils_ssid_to_string(ssid))); + nm_device_activate_schedule_stage3_ip_config_start(device); + } else if (devstate == NM_DEVICE_STATE_ACTIVATED) + periodic_update(self); + break; + case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED: + if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating(device)) { + /* Disconnect of an 802.1x/LEAP connection during authentication, + * or disconnect of a WPA-PSK connection during the 4-way handshake, + * often means secrets are wrong. Not always the case, but until we + * have more information from wpa_supplicant about why the + * disconnect happened this is the best we can do. + */ + if (handle_8021x_or_psk_auth_fail(self, new_state, old_state, disconnect_reason)) + break; + } + + /* Otherwise, it might be a stupid driver or some transient error, so + * let the supplicant try to reconnect a few more times. Give it more + * time if a scan is in progress since the link might be dropped during + * the scan but will be re-established when the scan is done. + */ + if (devstate == NM_DEVICE_STATE_ACTIVATED) { + if (priv->link_timeout_id == 0) { + priv->link_timeout_id = + g_timeout_add_seconds(scanning ? 30 : 15, link_timeout_cb, self); + priv->ssid_found = FALSE; + } + } + break; + case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE: + /* we would clear _scan_has_pending_action_set() and trigger a new scan. + * However, we don't want to cancel the current pending action, so force + * a new scan request. */ + break; + default: + break; + } out: - scan_changed = _scan_notify_allowed (self, NM_TERNARY_FALSE); - scan_changed |= _scan_notify_is_scanning (self); - if (scan_changed) - _scan_kickoff (self); + scan_changed = _scan_notify_allowed(self, NM_TERNARY_FALSE); + scan_changed |= _scan_notify_is_scanning(self); + if (scan_changed) + _scan_kickoff(self); - if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) - nm_device_remove_pending_action (device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); + if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) + nm_device_remove_pending_action(device, NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT, TRUE); } static void -supplicant_iface_state_cb (NMSupplicantInterface *iface, - int new_state_i, - int old_state_i, - int disconnect_reason, - gpointer user_data) +supplicant_iface_state_cb(NMSupplicantInterface *iface, + int new_state_i, + int old_state_i, + int disconnect_reason, + gpointer user_data) { - supplicant_iface_state (user_data, - new_state_i, - old_state_i, - disconnect_reason, - TRUE); + supplicant_iface_state(user_data, new_state_i, old_state_i, disconnect_reason, TRUE); } static void -supplicant_iface_assoc_cb (NMSupplicantInterface *iface, - GError *error, - gpointer user_data) +supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data) { - NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); - NMDevice *device = NM_DEVICE (self); + NMDeviceWifi *self = NM_DEVICE_WIFI(user_data); + NMDevice * device = NM_DEVICE(self); - if ( error && !nm_utils_error_is_cancelled_or_disposing (error) - && nm_device_is_activating (device)) { - cleanup_association_attempt (self, TRUE); - nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - } + if (error && !nm_utils_error_is_cancelled_or_disposing(error) + && nm_device_is_activating(device)) { + cleanup_association_attempt(self, TRUE); + nm_device_queue_state(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + } } static void -supplicant_iface_notify_current_bss (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMRefString *current_bss; - NMWifiAP *new_ap = NULL; - - current_bss = nm_supplicant_interface_get_current_bss (iface); - if (current_bss) - new_ap = g_hash_table_lookup (priv->aps_idx_by_supplicant_path, current_bss); - - if (new_ap != priv->current_ap) { - const char *new_bssid = NULL; - GBytes *new_ssid = NULL; - const char *old_bssid = NULL; - GBytes *old_ssid = NULL; - gs_free char *new_ssid_s = NULL; - gs_free char *old_ssid_s = NULL; - - /* Don't ever replace a "fake" current AP if we don't know about the - * supplicant's current BSS yet. It'll get replaced when we receive - * the current BSS's scan result. - */ - if (new_ap == NULL && nm_wifi_ap_get_fake (priv->current_ap)) - return; - - if (new_ap) { - new_bssid = nm_wifi_ap_get_address (new_ap); - new_ssid = nm_wifi_ap_get_ssid (new_ap); - } - - if (priv->current_ap) { - old_bssid = nm_wifi_ap_get_address (priv->current_ap); - old_ssid = nm_wifi_ap_get_ssid (priv->current_ap); - } - - _LOGD (LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", - old_bssid ?: "(none)", - (old_ssid_s = _nm_utils_ssid_to_string (old_ssid)), - new_bssid ?: "(none)", - (new_ssid_s = _nm_utils_ssid_to_string (new_ssid))); - - set_current_ap (self, new_ap, TRUE); - } +supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceWifi * self) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMRefString * current_bss; + NMWifiAP * new_ap = NULL; + + current_bss = nm_supplicant_interface_get_current_bss(iface); + if (current_bss) + new_ap = g_hash_table_lookup(priv->aps_idx_by_supplicant_path, current_bss); + + if (new_ap != priv->current_ap) { + const char * new_bssid = NULL; + GBytes * new_ssid = NULL; + const char * old_bssid = NULL; + GBytes * old_ssid = NULL; + gs_free char *new_ssid_s = NULL; + gs_free char *old_ssid_s = NULL; + + /* Don't ever replace a "fake" current AP if we don't know about the + * supplicant's current BSS yet. It'll get replaced when we receive + * the current BSS's scan result. + */ + if (new_ap == NULL && nm_wifi_ap_get_fake(priv->current_ap)) + return; + + if (new_ap) { + new_bssid = nm_wifi_ap_get_address(new_ap); + new_ssid = nm_wifi_ap_get_ssid(new_ap); + } + + if (priv->current_ap) { + old_bssid = nm_wifi_ap_get_address(priv->current_ap); + old_ssid = nm_wifi_ap_get_ssid(priv->current_ap); + } + + _LOGD(LOGD_WIFI, + "roamed from BSSID %s (%s) to %s (%s)", + old_bssid ?: "(none)", + (old_ssid_s = _nm_utils_ssid_to_string(old_ssid)), + new_bssid ?: "(none)", + (new_ssid_s = _nm_utils_ssid_to_string(new_ssid))); + + if (new_bssid) { + /* The new AP could be in a different layer 3 network + * and so the old DHCP lease could be no longer valid. + * Also, some APs (e.g. Cisco) can be configured to drop + * all traffic until DHCP completes. To support such + * cases, renew the lease when roaming to a new AP. */ + nm_device_update_dynamic_ip_setup(NM_DEVICE(self)); + } + + set_current_ap(self, new_ap, TRUE); + } } /* We bind the existence of the P2P device to a wifi device that is being @@ -2584,132 +2606,130 @@ supplicant_iface_notify_current_bss (NMSupplicantInterface *iface, * is detected and the supplicant interface has been initialised. */ static void -recheck_p2p_availability (NMDeviceWifi *self) +recheck_p2p_availability(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gboolean p2p_available; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gboolean p2p_available; - g_object_get (priv->sup_iface, - NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, &p2p_available, - NULL); + g_object_get(priv->sup_iface, NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, &p2p_available, NULL); - if (p2p_available && !priv->p2p_device) { - gs_free char *iface_name = NULL; + if (p2p_available && !priv->p2p_device) { + gs_free char *iface_name = NULL; - /* Create a P2P device. "p2p-dev-" is the same prefix as chosen by - * wpa_supplicant internally. - */ - iface_name = g_strconcat ("p2p-dev-", nm_device_get_iface (NM_DEVICE (self)), NULL); + /* Create a P2P device. "p2p-dev-" is the same prefix as chosen by + * wpa_supplicant internally. + */ + iface_name = g_strconcat("p2p-dev-", nm_device_get_iface(NM_DEVICE(self)), NULL); - priv->p2p_device = nm_device_wifi_p2p_new (iface_name); + priv->p2p_device = nm_device_wifi_p2p_new(iface_name); - nm_device_wifi_p2p_set_mgmt_iface (priv->p2p_device, priv->sup_iface); + nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, priv->sup_iface); - g_signal_emit (self, signals[P2P_DEVICE_CREATED], 0, priv->p2p_device); - g_object_add_weak_pointer (G_OBJECT (priv->p2p_device), (gpointer*) &priv->p2p_device); - g_object_unref (priv->p2p_device); - return; - } + g_signal_emit(self, signals[P2P_DEVICE_CREATED], 0, priv->p2p_device); + g_object_add_weak_pointer(G_OBJECT(priv->p2p_device), (gpointer *) &priv->p2p_device); + g_object_unref(priv->p2p_device); + return; + } - if (p2p_available && priv->p2p_device) { - nm_device_wifi_p2p_set_mgmt_iface (priv->p2p_device, priv->sup_iface); - return; - } + if (p2p_available && priv->p2p_device) { + nm_device_wifi_p2p_set_mgmt_iface(priv->p2p_device, priv->sup_iface); + return; + } - if (!p2p_available && priv->p2p_device) { - /* Destroy the P2P device. */ - g_object_remove_weak_pointer (G_OBJECT (priv->p2p_device), (gpointer*) &priv->p2p_device); - nm_device_wifi_p2p_remove (g_steal_pointer (&priv->p2p_device)); - return; - } + if (!p2p_available && priv->p2p_device) { + /* Destroy the P2P device. */ + g_object_remove_weak_pointer(G_OBJECT(priv->p2p_device), (gpointer *) &priv->p2p_device); + nm_device_wifi_p2p_remove(g_steal_pointer(&priv->p2p_device)); + return; + } } static void -supplicant_iface_notify_p2p_available (NMSupplicantInterface *iface, - GParamSpec *pspec, - NMDeviceWifi *self) +supplicant_iface_notify_p2p_available(NMSupplicantInterface *iface, + GParamSpec * pspec, + NMDeviceWifi * self) { - if (nm_supplicant_interface_get_state (iface) > NM_SUPPLICANT_INTERFACE_STATE_STARTING) - recheck_p2p_availability (self); + if (nm_supplicant_interface_get_state(iface) > NM_SUPPLICANT_INTERFACE_STATE_STARTING) + recheck_p2p_availability(self); } static gboolean -handle_auth_or_fail (NMDeviceWifi *self, - NMActRequest *req, - gboolean new_secrets) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - const char *setting_name; - NMConnection *applied_connection; - NMSettingWirelessSecurity *s_wsec; - const char *bssid = NULL; - NM80211ApFlags ap_flags; - NMSettingWirelessSecurityWpsMethod wps_method; - const char *type; - NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - - g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), FALSE); - - if (!req) { - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_val_if_fail (req, FALSE); - } - - if (!nm_device_auth_retries_try_next (NM_DEVICE (self))) - return FALSE; - - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - - applied_connection = nm_act_request_get_applied_connection (req); - s_wsec = nm_connection_get_setting_wireless_security (applied_connection); - wps_method = nm_setting_wireless_security_get_wps_method (s_wsec); - - /* Negotiate the WPS method */ - if (wps_method == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT) - wps_method = NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO; - - if ( wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO - && priv->current_ap) { - /* Determine the method to use from AP capabilities. */ - ap_flags = nm_wifi_ap_get_flags (priv->current_ap); - if (ap_flags & NM_802_11_AP_FLAGS_WPS_PBC) - wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC; - if (ap_flags & NM_802_11_AP_FLAGS_WPS_PIN) - wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN; - if ( ap_flags & NM_802_11_AP_FLAGS_WPS - && wps_method == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO) { - /* The AP doesn't specify which methods are supported. Allow all. */ - wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC; - wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN; - } - } - - if (wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC) { - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE; - type = "pbc"; - } else if (wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN) { - type = "pin"; - } else - type = NULL; - - if (type) { - priv->wps_timeout_id = g_timeout_add_seconds (30, wps_timeout_cb, self); - if (priv->current_ap) - bssid = nm_wifi_ap_get_address (priv->current_ap); - nm_supplicant_interface_enroll_wps (priv->sup_iface, type, bssid, NULL); - } - - nm_act_request_clear_secrets (req); - setting_name = nm_connection_need_secrets (applied_connection, NULL); - if (!setting_name) { - _LOGW (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - return FALSE; - } - - if (new_secrets) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - wifi_secrets_get_secrets (self, setting_name, get_secret_flags); - return TRUE; +handle_auth_or_fail(NMDeviceWifi *self, NMActRequest *req, gboolean new_secrets) +{ + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + const char * setting_name; + NMConnection * applied_connection; + NMSettingWirelessSecurity * s_wsec; + const char * bssid = NULL; + NM80211ApFlags ap_flags; + NMSettingWirelessSecurityWpsMethod wps_method; + const char * type; + NMSecretAgentGetSecretsFlags get_secret_flags = + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + + g_return_val_if_fail(NM_IS_DEVICE_WIFI(self), FALSE); + + if (!req) { + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_val_if_fail(req, FALSE); + } + + if (!nm_device_auth_retries_try_next(NM_DEVICE(self))) + return FALSE; + + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); + + applied_connection = nm_act_request_get_applied_connection(req); + s_wsec = nm_connection_get_setting_wireless_security(applied_connection); + wps_method = nm_setting_wireless_security_get_wps_method(s_wsec); + + /* Negotiate the WPS method */ + if (wps_method == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_DEFAULT) + wps_method = NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO; + + if (wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO && priv->current_ap) { + /* Determine the method to use from AP capabilities. */ + ap_flags = nm_wifi_ap_get_flags(priv->current_ap); + if (ap_flags & NM_802_11_AP_FLAGS_WPS_PBC) + wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC; + if (ap_flags & NM_802_11_AP_FLAGS_WPS_PIN) + wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN; + if (ap_flags & NM_802_11_AP_FLAGS_WPS + && wps_method == NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_AUTO) { + /* The AP doesn't specify which methods are supported. Allow all. */ + wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC; + wps_method |= NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN; + } + } + + if (wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PBC) { + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_WPS_PBC_ACTIVE; + type = "pbc"; + } else if (wps_method & NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN) { + type = "pin"; + } else + type = NULL; + + if (type) { + priv->wps_timeout_id = g_timeout_add_seconds(30, wps_timeout_cb, self); + if (priv->current_ap) + bssid = nm_wifi_ap_get_address(priv->current_ap); + nm_supplicant_interface_enroll_wps(priv->sup_iface, type, bssid, NULL); + } + + nm_act_request_clear_secrets(req); + setting_name = nm_connection_need_secrets(applied_connection, NULL); + if (!setting_name) { + _LOGW(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + return FALSE; + } + + if (new_secrets) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + wifi_secrets_get_secrets(self, setting_name, get_secret_flags); + return TRUE; } /* @@ -2719,1080 +2739,1109 @@ handle_auth_or_fail (NMDeviceWifi *self, * within a specified period of time. */ static gboolean -supplicant_connection_timeout_cb (gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMActRequest *req; - NMConnection *connection; - - cleanup_association_attempt (self, TRUE); - - if (!nm_device_is_activating (device)) - return FALSE; - - /* Timed out waiting for a successful connection to the AP; if the AP's - * security requires network-side authentication (like WPA or 802.1x) - * and the connection attempt timed out then it's likely the authentication - * information (passwords, pin codes, etc) are wrong. - */ - - req = nm_device_get_act_request (device); - g_assert (req); - - connection = nm_act_request_get_applied_connection (req); - g_assert (connection); - - if (NM_IN_SET (priv->mode, NM_802_11_MODE_ADHOC, - NM_802_11_MODE_MESH, - NM_802_11_MODE_AP)) { - /* In Ad-Hoc and AP modes there's nothing to check the encryption key - * (if any), so supplicant timeouts here are almost certainly the wifi - * driver being really stupid. - */ - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) %s network creation took too long, failing activation", - priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); - return FALSE; - } - - g_assert (priv->mode == NM_802_11_MODE_INFRA); - - if (priv->ssid_found && nm_connection_get_setting_wireless_security (connection)) { - guint64 timestamp = 0; - gboolean new_secrets = TRUE; - - /* Connection failed; either driver problems, the encryption key is - * wrong, or the passwords or certificates were wrong. - */ - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) association took too long"); - - /* 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. - */ - if (nm_settings_connection_get_timestamp (nm_act_request_get_settings_connection (req), ×tamp)) - new_secrets = !timestamp; - - if (handle_auth_or_fail (self, req, new_secrets)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) asking for new secrets"); - else { - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - } - } else { - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) association took too long, failing activation"); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, - priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : - NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); - } - - return FALSE; +supplicant_connection_timeout_cb(gpointer user_data) +{ + NMDevice * device = NM_DEVICE(user_data); + NMDeviceWifi * self = NM_DEVICE_WIFI(user_data); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMActRequest * req; + NMConnection * connection; + + cleanup_association_attempt(self, TRUE); + + if (!nm_device_is_activating(device)) + return FALSE; + + /* Timed out waiting for a successful connection to the AP; if the AP's + * security requires network-side authentication (like WPA or 802.1x) + * and the connection attempt timed out then it's likely the authentication + * information (passwords, pin codes, etc) are wrong. + */ + + req = nm_device_get_act_request(device); + g_assert(req); + + connection = nm_act_request_get_applied_connection(req); + g_assert(connection); + + if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH, NM_802_11_MODE_AP)) { + /* In Ad-Hoc and AP modes there's nothing to check the encryption key + * (if any), so supplicant timeouts here are almost certainly the wifi + * driver being really stupid. + */ + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) %s network creation took too long, failing activation", + priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); + return FALSE; + } + + g_assert(priv->mode == NM_802_11_MODE_INFRA); + + if (priv->ssid_found && nm_connection_get_setting_wireless_security(connection)) { + guint64 timestamp = 0; + gboolean new_secrets = TRUE; + + /* Connection failed; either driver problems, the encryption key is + * wrong, or the passwords or certificates were wrong. + */ + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) association took too long"); + + /* 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. + */ + if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), + ×tamp)) + new_secrets = !timestamp; + + if (handle_auth_or_fail(self, req, new_secrets)) + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) asking for new secrets"); + else { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } + } else { + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) association took too long, failing activation"); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT + : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); + } + + return FALSE; } static NMSupplicantConfig * -build_supplicant_config (NMDeviceWifi *self, - NMConnection *connection, - guint32 fixed_freq, - GError **error) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSupplicantConfig *config = NULL; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wireless_sec; - NMSettingWirelessSecurityPmf pmf; - NMSettingWirelessSecurityFils fils; - - g_return_val_if_fail (priv->sup_iface, NULL); - - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wireless != NULL, NULL); - - config = nm_supplicant_config_new (nm_supplicant_interface_get_capabilities (priv->sup_iface)); - - /* Warn if AP mode may not be supported */ - if ( nm_streq0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) - && nm_supplicant_interface_get_capability (priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) != NM_TERNARY_TRUE) { - _LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); - } - - if (!nm_supplicant_config_add_setting_wireless (config, - s_wireless, - fixed_freq, - error)) { - g_prefix_error (error, "802-11-wireless: "); - goto error; - } - - if (!nm_supplicant_config_add_bgscan (config, connection, error)) { - g_prefix_error (error, "bgscan: "); - goto error; - } - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - if (s_wireless_sec) { - NMSetting8021x *s_8021x; - const char *con_uuid = nm_connection_get_uuid (connection); - guint32 mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - - g_assert (con_uuid); - - /* Configure PMF (802.11w) */ - pmf = nm_setting_wireless_security_get_pmf (s_wireless_sec); - if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { - pmf = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi-sec.pmf", - NM_DEVICE (self), - NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, - NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, - NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL); - } - - /* Configure FILS (802.11ai) */ - fils = nm_setting_wireless_security_get_fils (s_wireless_sec); - if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) { - fils = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi-sec.fils", - NM_DEVICE (self), - NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE, - NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, - NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL); - } - - s_8021x = nm_connection_get_setting_802_1x (connection); - if (!nm_supplicant_config_add_setting_wireless_security (config, - s_wireless_sec, - s_8021x, - con_uuid, - mtu, - pmf, - fils, - error)) { - g_prefix_error (error, "802-11-wireless-security: "); - goto error; - } - } else { - if (!nm_supplicant_config_add_no_security (config, error)) { - g_prefix_error (error, "unsecured-option: "); - goto error; - } - } - - return config; +build_supplicant_config(NMDeviceWifi *self, + NMConnection *connection, + guint32 fixed_freq, + GError ** error) +{ + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSupplicantConfig * config = NULL; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity * s_wireless_sec; + NMSettingWirelessSecurityPmf pmf; + NMSettingWirelessSecurityFils fils; + NMTernary ap_isolation; + + g_return_val_if_fail(priv->sup_iface, NULL); + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wireless != NULL, NULL); + + config = nm_supplicant_config_new(nm_supplicant_interface_get_capabilities(priv->sup_iface)); + + /* Warn if AP mode may not be supported */ + if (nm_streq0(nm_setting_wireless_get_mode(s_wireless), NM_SETTING_WIRELESS_MODE_AP) + && nm_supplicant_interface_get_capability(priv->sup_iface, NM_SUPPL_CAP_TYPE_AP) + != NM_TERNARY_TRUE) { + _LOGW(LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); + } + + if (!nm_supplicant_config_add_setting_wireless(config, s_wireless, fixed_freq, error)) { + g_prefix_error(error, "802-11-wireless: "); + goto error; + } + + if (!nm_supplicant_config_add_bgscan(config, connection, error)) { + g_prefix_error(error, "bgscan: "); + goto error; + } + + ap_isolation = nm_setting_wireless_get_ap_isolation(s_wireless); + if (ap_isolation == NM_TERNARY_DEFAULT) { + ap_isolation = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + "wifi.ap-isolation", + NM_DEVICE(self), + NM_TERNARY_FALSE, + NM_TERNARY_TRUE, + NM_TERNARY_FALSE); + } + nm_supplicant_config_set_ap_isolation(config, ap_isolation == NM_TERNARY_TRUE); + + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + if (s_wireless_sec) { + NMSetting8021x *s_8021x; + const char * con_uuid = nm_connection_get_uuid(connection); + guint32 mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)), + nm_device_get_ifindex(NM_DEVICE(self))); + + g_assert(con_uuid); + + /* Configure PMF (802.11w) */ + pmf = nm_setting_wireless_security_get_pmf(s_wireless_sec); + if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { + pmf = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + "wifi-sec.pmf", + NM_DEVICE(self), + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL); + } + + /* Configure FILS (802.11ai) */ + fils = nm_setting_wireless_security_get_fils(s_wireless_sec); + if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) { + fils = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + "wifi-sec.fils", + NM_DEVICE(self), + NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE, + NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, + NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL); + } + + s_8021x = nm_connection_get_setting_802_1x(connection); + if (!nm_supplicant_config_add_setting_wireless_security(config, + s_wireless_sec, + s_8021x, + con_uuid, + mtu, + pmf, + fils, + error)) { + g_prefix_error(error, "802-11-wireless-security: "); + goto error; + } + } else { + if (!nm_supplicant_config_add_no_security(config, error)) { + g_prefix_error(error, "unsecured-option: "); + goto error; + } + } + + return config; error: - g_object_unref (config); - return NULL; + g_object_unref(config); + return NULL; } /*****************************************************************************/ static gboolean -wake_on_wlan_enable (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWirelessWakeOnWLan wowl; - NMSettingWireless *s_wireless; - - s_wireless = nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_WIRELESS); - if (s_wireless) { - wowl = nm_setting_wireless_get_wake_on_wlan (s_wireless); - if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) - goto found; - } - - wowl = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi.wake-on-wlan", - NM_DEVICE (self), - NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE, - G_MAXINT32, - NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT); - - if (NM_FLAGS_ANY (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) { - if (!nm_utils_is_power_of_two (wowl)) { - _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan: " - "'default' and 'ignore' are exclusive flags", (guint) wowl); - wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; - } - } else if (NM_FLAGS_ANY (wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) { - _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan", (guint) wowl); - wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; - } - if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) - goto found; - - wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; +wake_on_wlan_enable(NMDeviceWifi *self) +{ + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWirelessWakeOnWLan wowl; + NMSettingWireless * s_wireless; + + s_wireless = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_WIRELESS); + if (s_wireless) { + wowl = nm_setting_wireless_get_wake_on_wlan(s_wireless); + if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) + goto found; + } + + wowl = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + "wifi.wake-on-wlan", + NM_DEVICE(self), + NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE, + G_MAXINT32, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT); + + if (NM_FLAGS_ANY(wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) { + if (!nm_utils_is_power_of_two(wowl)) { + _LOGD(LOGD_WIFI, + "invalid default value %u for wake-on-wlan: " + "'default' and 'ignore' are exclusive flags", + (guint) wowl); + wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + } + } else if (NM_FLAGS_ANY(wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) { + _LOGD(LOGD_WIFI, "invalid default value %u for wake-on-wlan", (guint) wowl); + wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + } + if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) + goto found; + + wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; found: - if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { - priv->wowlan_restore = wowl; - return TRUE; - } + if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { + priv->wowlan_restore = wowl; + return TRUE; + } - priv->wowlan_restore = nm_platform_wifi_get_wake_on_wlan (NM_PLATFORM_GET, - nm_device_get_ifindex (NM_DEVICE (self))); + priv->wowlan_restore = + nm_platform_wifi_get_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self))); - return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET, - nm_device_get_ifindex (NM_DEVICE (self)), - wowl); + return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, + nm_device_get_ifindex(NM_DEVICE(self)), + wowl); } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMWifiAP *ap = NULL; - gs_unref_object NMWifiAP *ap_fake = NULL; - NMActRequest *req; - NMConnection *connection; - NMSettingWireless *s_wireless; - const char *mode; - const char *ap_path; - - req = nm_device_get_act_request (NM_DEVICE (self)); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - connection = nm_act_request_get_applied_connection (req); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wireless, NM_ACT_STAGE_RETURN_FAILURE); - - nm_supplicant_interface_cancel_wps (priv->sup_iface); - - mode = nm_setting_wireless_get_mode (s_wireless); - if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) == 0) - priv->mode = NM_802_11_MODE_INFRA; - else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) - priv->mode = NM_802_11_MODE_ADHOC; - else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - priv->mode = NM_802_11_MODE_AP; - - /* Scanning not done in AP mode; clear the scan list */ - remove_all_aps (self); - } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) - priv->mode = NM_802_11_MODE_MESH; - _notify (self, PROP_MODE); - - /* expire the temporary MAC address used during scanning */ - priv->hw_addr_scan_expire = 0; - - /* Set spoof MAC to the interface */ - if (!nm_device_hw_addr_set_cloned (device, connection, TRUE)) { - *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; - return NM_ACT_STAGE_RETURN_FAILURE; - } - - /* AP and Mesh modes never use a specific object or existing scanned AP */ - if (!NM_IN_SET (priv->mode, NM_802_11_MODE_AP, - NM_802_11_MODE_MESH)) { - ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); - ap = ap_path - ? nm_wifi_ap_lookup_for_device (NM_DEVICE (self), ap_path) - : NULL; - } - if (!ap) - ap = nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); - - if (!ap) { - /* If the user is trying to connect to an AP that NM doesn't yet know about - * (hidden network or something), starting a Hotspot or joining a Mesh, - * create a fake APfrom the security settings in the connection. This "fake" - * AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden), - * or until the device is deactivated (Hotspot). - */ - ap_fake = nm_wifi_ap_new_fake_from_connection (connection); - if (!ap_fake) - g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - - if (nm_wifi_ap_is_hotspot (ap_fake)) - nm_wifi_ap_set_address (ap_fake, nm_device_get_hw_address (device)); - - g_object_freeze_notify (G_OBJECT (self)); - ap_add_remove (self, TRUE, ap_fake, TRUE); - g_object_thaw_notify (G_OBJECT (self)); - ap = ap_fake; - } - - _scan_notify_allowed (self, NM_TERNARY_DEFAULT); - - set_current_ap (self, ap, FALSE); - nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); - return NM_ACT_STAGE_RETURN_SUCCESS; +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMWifiAP * ap = NULL; + gs_unref_object NMWifiAP *ap_fake = NULL; + NMActRequest * req; + NMConnection * connection; + NMSettingWireless * s_wireless; + const char * mode; + const char * ap_path; + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection(req); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wireless, NM_ACT_STAGE_RETURN_FAILURE); + + nm_supplicant_interface_cancel_wps(priv->sup_iface); + + mode = nm_setting_wireless_get_mode(s_wireless); + if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_INFRA) == 0) + priv->mode = NM_802_11_MODE_INFRA; + else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) + priv->mode = NM_802_11_MODE_ADHOC; + else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { + priv->mode = NM_802_11_MODE_AP; + + /* Scanning not done in AP mode; clear the scan list */ + remove_all_aps(self); + } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) + priv->mode = NM_802_11_MODE_MESH; + _notify(self, PROP_MODE); + + /* expire the temporary MAC address used during scanning */ + priv->hw_addr_scan_expire = 0; + + /* Set spoof MAC to the interface */ + if (!nm_device_hw_addr_set_cloned(device, connection, TRUE)) { + *out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + /* AP and Mesh modes never use a specific object or existing scanned AP */ + if (!NM_IN_SET(priv->mode, NM_802_11_MODE_AP, NM_802_11_MODE_MESH)) { + ap_path = nm_active_connection_get_specific_object(NM_ACTIVE_CONNECTION(req)); + ap = ap_path ? nm_wifi_ap_lookup_for_device(NM_DEVICE(self), ap_path) : NULL; + } + if (!ap) + ap = nm_wifi_aps_find_first_compatible(&priv->aps_lst_head, connection); + + if (!ap) { + /* If the user is trying to connect to an AP that NM doesn't yet know about + * (hidden network or something), starting a Hotspot or joining a Mesh, + * create a fake APfrom the security settings in the connection. This "fake" + * AP gets used until the real one is found in the scan list (Ad-Hoc or Hidden), + * or until the device is deactivated (Hotspot). + */ + ap_fake = nm_wifi_ap_new_fake_from_connection(connection); + if (!ap_fake) + g_return_val_if_reached(NM_ACT_STAGE_RETURN_FAILURE); + + if (nm_wifi_ap_is_hotspot(ap_fake)) + nm_wifi_ap_set_address(ap_fake, nm_device_get_hw_address(device)); + + g_object_freeze_notify(G_OBJECT(self)); + ap_add_remove(self, TRUE, ap_fake, TRUE); + g_object_thaw_notify(G_OBJECT(self)); + ap = ap_fake; + } + + _scan_notify_allowed(self, NM_TERNARY_DEFAULT); + + set_current_ap(self, ap, FALSE); + nm_active_connection_set_specific_object(NM_ACTIVE_CONNECTION(req), + nm_dbus_object_get_path(NM_DBUS_OBJECT(ap))); + return NM_ACT_STAGE_RETURN_SUCCESS; } static void -ensure_hotspot_frequency (NMDeviceWifi *self, - NMSettingWireless *s_wifi, - NMWifiAP *ap) +ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP *ap) { - NMDevice *device = NM_DEVICE (self); - const char *band = nm_setting_wireless_get_band (s_wifi); - const guint32 a_freqs[] = { 5180, 5200, 5220, 5745, 5765, 5785, 5805, 0 }; - const guint32 bg_freqs[] = { 2412, 2437, 2462, 2472, 0 }; - guint32 freq = 0; + NMDevice * device = NM_DEVICE(self); + const char * band = nm_setting_wireless_get_band(s_wifi); + const guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0}; + const guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0}; + guint32 freq = 0; - g_assert (ap); + g_assert(ap); - if (nm_wifi_ap_get_freq (ap)) - return; + if (nm_wifi_ap_get_freq(ap)) + return; - if (g_strcmp0 (band, "a") == 0) - freq = nm_platform_wifi_find_frequency (nm_device_get_platform (device), nm_device_get_ifindex (device), a_freqs); - else - freq = nm_platform_wifi_find_frequency (nm_device_get_platform (device), nm_device_get_ifindex (device), bg_freqs); + if (g_strcmp0(band, "a") == 0) + freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device), + nm_device_get_ifindex(device), + a_freqs); + else + freq = nm_platform_wifi_find_frequency(nm_device_get_platform(device), + nm_device_get_ifindex(device), + bg_freqs); - if (!freq) - freq = (g_strcmp0 (band, "a") == 0) ? 5180 : 2462; + if (!freq) + freq = (g_strcmp0(band, "a") == 0) ? 5180 : 2462; - if (nm_wifi_ap_set_freq (ap, freq)) - _ap_dump (self, LOGL_DEBUG, ap, "updated", 0); + if (nm_wifi_ap_set_freq(ap, freq)) + _ap_dump(self, LOGL_DEBUG, ap, "updated", 0); } static void -set_powersave (NMDevice *device) +set_powersave(NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMSettingWireless *s_wireless; - NMSettingWirelessPowersave val; + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMSettingWireless * s_wireless; + NMSettingWirelessPowersave val; - s_wireless = nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); + s_wireless = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS); - g_return_if_fail (s_wireless); + g_return_if_fail(s_wireless); - val = nm_setting_wireless_get_powersave (s_wireless); - if (val == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) { - val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi.powersave", - device, - NM_SETTING_WIRELESS_POWERSAVE_IGNORE, - NM_SETTING_WIRELESS_POWERSAVE_ENABLE, - NM_SETTING_WIRELESS_POWERSAVE_IGNORE); - } + val = nm_setting_wireless_get_powersave(s_wireless); + if (val == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) { + val = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + "wifi.powersave", + device, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE, + NM_SETTING_WIRELESS_POWERSAVE_ENABLE, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE); + } - _LOGT (LOGD_WIFI, "powersave is set to %u", (unsigned) val); + _LOGT(LOGD_WIFI, "powersave is set to %u", (unsigned) val); - if (val == NM_SETTING_WIRELESS_POWERSAVE_IGNORE) - return; + if (val == NM_SETTING_WIRELESS_POWERSAVE_IGNORE) + return; - nm_platform_wifi_set_powersave (nm_device_get_platform (device), - nm_device_get_ifindex (device), - val == NM_SETTING_WIRELESS_POWERSAVE_ENABLE); + nm_platform_wifi_set_powersave(nm_device_get_platform(device), + nm_device_get_ifindex(device), + val == NM_SETTING_WIRELESS_POWERSAVE_ENABLE); } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gs_unref_object NMSupplicantConfig *config = NULL; - NM80211Mode ap_mode; - NMActRequest *req; - NMWifiAP *ap; - NMConnection *connection; - const char *setting_name; - NMSettingWireless *s_wireless; - GError *error = NULL; - guint timeout; - - nm_clear_g_source (&priv->sup_timeout_id); - nm_clear_g_source (&priv->link_timeout_id); - nm_clear_g_source (&priv->wps_timeout_id); - - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - ap = priv->current_ap; - if (!ap) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - goto out_fail; - } - - ap_mode = nm_wifi_ap_get_mode (ap); - - connection = nm_act_request_get_applied_connection (req); - s_wireless = nm_connection_get_setting_wireless (connection); - nm_assert (s_wireless); - - /* If we need secrets, get them */ - setting_name = nm_connection_need_secrets (connection, NULL); - if (setting_name) { - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) access point '%s' has security, but secrets are required.", - nm_connection_get_id (connection)); - - if (!handle_auth_or_fail (self, req, FALSE)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - goto out_fail; - } - - return NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (!wake_on_wlan_enable (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); - - /* have secrets, or no secrets required */ - if (nm_connection_get_setting_wireless_security (connection)) { - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) connection '%s' has security, and secrets exist. No new secrets needed.", - nm_connection_get_id (connection)); - } else { - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) connection '%s' requires no security. No secrets needed.", - nm_connection_get_id (connection)); - } - - priv->ssid_found = FALSE; - - /* Supplicant requires an initial frequency for Ad-Hoc, Hotspot and Mesh; - * if the user didn't specify one and we didn't find an AP that matched - * the connection, just pick a frequency the device supports. - */ - if ( NM_IN_SET (ap_mode, NM_802_11_MODE_ADHOC, - NM_802_11_MODE_MESH) - || nm_wifi_ap_is_hotspot (ap)) - ensure_hotspot_frequency (self, s_wireless, ap); - - if (ap_mode == NM_802_11_MODE_INFRA) - set_powersave (device); - - /* Build up the supplicant configuration */ - config = build_supplicant_config (self, connection, nm_wifi_ap_get_freq (ap), &error); - if (!config) { - _LOGE (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) couldn't build wireless configuration: %s", - error->message); - g_clear_error (&error); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); - goto out_fail; - } - - nm_supplicant_interface_assoc (priv->sup_iface, - config, - supplicant_iface_assoc_cb, - self); - - /* Set up a timeout on the association attempt */ - timeout = nm_device_get_supplicant_timeout (NM_DEVICE (self)); - priv->sup_timeout_id = g_timeout_add_seconds (timeout, - supplicant_connection_timeout_cb, - self); - - if (!priv->periodic_update_id) - priv->periodic_update_id = g_timeout_add_seconds (6, periodic_update_cb, self); - - /* We'll get stage3 started when the supplicant connects */ - return NM_ACT_STAGE_RETURN_POSTPONE; +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gs_unref_object NMSupplicantConfig *config = NULL; + NM80211Mode ap_mode; + NMActRequest * req; + NMWifiAP * ap; + NMConnection * connection; + const char * setting_name; + NMSettingWireless * s_wireless; + GError * error = NULL; + guint timeout; + + nm_clear_g_source(&priv->sup_timeout_id); + nm_clear_g_source(&priv->link_timeout_id); + nm_clear_g_source(&priv->wps_timeout_id); + + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + ap = priv->current_ap; + if (!ap) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + goto out_fail; + } + + ap_mode = nm_wifi_ap_get_mode(ap); + + connection = nm_act_request_get_applied_connection(req); + s_wireless = nm_connection_get_setting_wireless(connection); + nm_assert(s_wireless); + + /* If we need secrets, get them */ + setting_name = nm_connection_need_secrets(connection, NULL); + if (setting_name) { + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) access point '%s' has security, but secrets are required.", + nm_connection_get_id(connection)); + + if (!handle_auth_or_fail(self, req, FALSE)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + goto out_fail; + } + + return NM_ACT_STAGE_RETURN_POSTPONE; + } + + if (!wake_on_wlan_enable(self)) + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); + + /* have secrets, or no secrets required */ + if (nm_connection_get_setting_wireless_security(connection)) { + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' has security, and secrets exist. No new secrets " + "needed.", + nm_connection_get_id(connection)); + } else { + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id(connection)); + } + + priv->ssid_found = FALSE; + + /* Supplicant requires an initial frequency for Ad-Hoc, Hotspot and Mesh; + * if the user didn't specify one and we didn't find an AP that matched + * the connection, just pick a frequency the device supports. + */ + if (NM_IN_SET(ap_mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH) || nm_wifi_ap_is_hotspot(ap)) + ensure_hotspot_frequency(self, s_wireless, ap); + + if (ap_mode == NM_802_11_MODE_INFRA) + set_powersave(device); + + /* Build up the supplicant configuration */ + config = build_supplicant_config(self, connection, nm_wifi_ap_get_freq(ap), &error); + if (!config) { + _LOGE(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) couldn't build wireless configuration: %s", + error->message); + g_clear_error(&error); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED); + goto out_fail; + } + + nm_supplicant_interface_assoc(priv->sup_iface, config, supplicant_iface_assoc_cb, self); + + /* Set up a timeout on the association attempt */ + timeout = nm_device_get_supplicant_timeout(NM_DEVICE(self)); + priv->sup_timeout_id = g_timeout_add_seconds(timeout, supplicant_connection_timeout_cb, self); + + if (!priv->periodic_update_id) + priv->periodic_update_id = g_timeout_add_seconds(6, periodic_update_cb, self); + + /* We'll get stage3 started when the supplicant connects */ + return NM_ACT_STAGE_RETURN_POSTPONE; out_fail: - cleanup_association_attempt (self, TRUE); - wake_on_wlan_restore (self); - return NM_ACT_STAGE_RETURN_FAILURE; + cleanup_association_attempt(self, TRUE); + wake_on_wlan_restore(self); + return NM_ACT_STAGE_RETURN_FAILURE; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - gboolean indicate_addressing_running; - NMConnection *connection; - const char *method; + gboolean indicate_addressing_running; + NMConnection *connection; + const char * method; - connection = nm_device_get_applied_connection (device); + connection = nm_device_get_applied_connection(device); - method = nm_utils_get_ip_config_method (connection, addr_family); - if (addr_family == AF_INET) - indicate_addressing_running = NM_IN_STRSET (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - else { - indicate_addressing_running = NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_DHCP); - } + method = nm_utils_get_ip_config_method(connection, addr_family); + if (addr_family == AF_INET) + indicate_addressing_running = NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + else { + indicate_addressing_running = NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP); + } - if (indicate_addressing_running) - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), TRUE); + if (indicate_addressing_running) + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + TRUE); - return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_wifi_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static guint32 -get_configured_mtu (NMDevice *device, - NMDeviceMtuSource *out_source, - gboolean *out_force) +get_configured_mtu(NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { - return nm_device_get_configured_mtu_from_connection (device, - NM_TYPE_SETTING_WIRELESS, - out_source); + return nm_device_get_configured_mtu_from_connection(device, + NM_TYPE_SETTING_WIRELESS, + out_source); } static gboolean -is_static_wep (NMConnection *connection) +is_static_wep(NMConnection *connection) { - NMSettingWirelessSecurity *s_wsec; - const char *str; + NMSettingWirelessSecurity *s_wsec; + const char * str; - g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail(connection != NULL, FALSE); - s_wsec = nm_connection_get_setting_wireless_security (connection); - if (!s_wsec) - return FALSE; + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (!s_wsec) + return FALSE; - str = nm_setting_wireless_security_get_key_mgmt (s_wsec); - if (g_strcmp0 (str, "none") != 0) - return FALSE; + str = nm_setting_wireless_security_get_key_mgmt(s_wsec); + if (g_strcmp0(str, "none") != 0) + return FALSE; - str = nm_setting_wireless_security_get_auth_alg (s_wsec); - if (g_strcmp0 (str, "leap") == 0) - return FALSE; + str = nm_setting_wireless_security_get_auth_alg(s_wsec); + if (g_strcmp0(str, "leap") == 0) + return FALSE; - return TRUE; + return TRUE; } static NMActStageReturn -act_stage4_ip_config_timeout (NMDevice *device, - int addr_family, - NMDeviceStateReason *out_failure_reason) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMConnection *connection; - NMSettingIPConfig *s_ip; - gboolean may_fail; - - connection = nm_device_get_applied_connection (device); - s_ip = nm_connection_get_setting_ip_config (connection, addr_family); - may_fail = nm_setting_ip_config_get_may_fail (s_ip); - - if (priv->mode == NM_802_11_MODE_AP) - goto call_parent; - - if ( may_fail - || !is_static_wep (connection)) { - /* Not static WEP or failure allowed; let superclass handle it */ - goto call_parent; - } - - /* If IP configuration times out and it's a static WEP connection, that - * usually means the WEP key is wrong. WEP's Open System auth mode has - * no provision for figuring out if the WEP key is wrong, so you just have - * to wait for DHCP to fail to figure it out. For all other Wi-Fi security - * types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the - * connection would have failed before IP configuration. - * - * Activation failed, we must have bad encryption key */ - _LOGW (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) could not get IP configuration for connection '%s'.", - nm_connection_get_id (connection)); - - if (!handle_auth_or_fail (self, NULL, TRUE)) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - _LOGI (LOGD_DEVICE | LOGD_WIFI, - "Activation: (wifi) asking for new secrets"); - return NM_ACT_STAGE_RETURN_POSTPONE; +act_stage4_ip_config_timeout(NMDevice * device, + int addr_family, + NMDeviceStateReason *out_failure_reason) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMConnection * connection; + NMSettingIPConfig * s_ip; + gboolean may_fail; + + connection = nm_device_get_applied_connection(device); + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + may_fail = nm_setting_ip_config_get_may_fail(s_ip); + + if (priv->mode == NM_802_11_MODE_AP) + goto call_parent; + + if (may_fail || !is_static_wep(connection)) { + /* Not static WEP or failure allowed; let superclass handle it */ + goto call_parent; + } + + /* If IP configuration times out and it's a static WEP connection, that + * usually means the WEP key is wrong. WEP's Open System auth mode has + * no provision for figuring out if the WEP key is wrong, so you just have + * to wait for DHCP to fail to figure it out. For all other Wi-Fi security + * types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the + * connection would have failed before IP configuration. + * + * Activation failed, we must have bad encryption key */ + _LOGW(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) could not get IP configuration for connection '%s'.", + nm_connection_get_id(connection)); + + if (!handle_auth_or_fail(self, NULL, TRUE)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + _LOGI(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) asking for new secrets"); + return NM_ACT_STAGE_RETURN_POSTPONE; call_parent: - return NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip_config_timeout (device, addr_family, out_failure_reason); + return NM_DEVICE_CLASS(nm_device_wifi_parent_class) + ->act_stage4_ip_config_timeout(device, addr_family, out_failure_reason); } static void -activation_success_handler (NMDevice *device) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (device); - NMActRequest *req; - - req = nm_device_get_act_request (device); - g_assert (req); - - /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE); - - /* There should always be a current AP, either a fake one because we haven't - * seen a scan result for the activated AP yet, or a real one from the - * supplicant's scan list. - */ - g_warn_if_fail (priv->current_ap); - if (priv->current_ap) { - if (nm_wifi_ap_get_fake (priv->current_ap)) { - gboolean ap_changed = FALSE; - - /* If the activation AP hasn't been seen by the supplicant in a scan - * yet, it will be "fake". This usually happens for Ad-Hoc and - * AP-mode connections. Fill in the details from the device itself - * until the supplicant sends the scan result. - */ - if (!nm_wifi_ap_get_address (priv->current_ap)) { - guint8 bssid[ETH_ALEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; - gs_free char *bssid_str = NULL; - - if ( nm_platform_wifi_get_bssid (nm_device_get_platform (device), ifindex, bssid) - && nm_ethernet_address_is_valid (bssid, ETH_ALEN)) { - bssid_str = nm_utils_hwaddr_ntoa (bssid, ETH_ALEN); - ap_changed |= nm_wifi_ap_set_address (priv->current_ap, bssid_str); - } - } - if (!nm_wifi_ap_get_freq (priv->current_ap)) - ap_changed |= nm_wifi_ap_set_freq (priv->current_ap, nm_platform_wifi_get_frequency (nm_device_get_platform (device), ifindex)); - if (!nm_wifi_ap_get_max_bitrate (priv->current_ap)) - ap_changed |= nm_wifi_ap_set_max_bitrate (priv->current_ap, nm_platform_wifi_get_rate (nm_device_get_platform (device), ifindex)); - - if (ap_changed) - _ap_dump (self, LOGL_DEBUG, priv->current_ap, "updated", 0); - } - - nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_dbus_object_get_path (NM_DBUS_OBJECT (priv->current_ap))); - } - - periodic_update (self); - - update_seen_bssids_cache (self, priv->current_ap); - - priv->scan_periodic_interval_sec = 0; - priv->scan_periodic_next_msec = 0; +activation_success_handler(NMDevice *device) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + int ifindex = nm_device_get_ifindex(device); + NMActRequest * req; + + req = nm_device_get_act_request(device); + g_assert(req); + + /* Clear any critical protocol notification in the wifi stack */ + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), ifindex, FALSE); + + /* There should always be a current AP, either a fake one because we haven't + * seen a scan result for the activated AP yet, or a real one from the + * supplicant's scan list. + */ + g_warn_if_fail(priv->current_ap); + if (priv->current_ap) { + if (nm_wifi_ap_get_fake(priv->current_ap)) { + gboolean ap_changed = FALSE; + + /* If the activation AP hasn't been seen by the supplicant in a scan + * yet, it will be "fake". This usually happens for Ad-Hoc and + * AP-mode connections. Fill in the details from the device itself + * until the supplicant sends the scan result. + */ + if (!nm_wifi_ap_get_address(priv->current_ap)) { + guint8 bssid[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + gs_free char *bssid_str = NULL; + + if (nm_platform_wifi_get_bssid(nm_device_get_platform(device), ifindex, bssid) + && nm_ethernet_address_is_valid(bssid, ETH_ALEN)) { + bssid_str = nm_utils_hwaddr_ntoa(bssid, ETH_ALEN); + ap_changed |= nm_wifi_ap_set_address(priv->current_ap, bssid_str); + } + } + if (!nm_wifi_ap_get_freq(priv->current_ap)) + ap_changed |= nm_wifi_ap_set_freq( + priv->current_ap, + nm_platform_wifi_get_frequency(nm_device_get_platform(device), ifindex)); + if (!nm_wifi_ap_get_max_bitrate(priv->current_ap)) + ap_changed |= nm_wifi_ap_set_max_bitrate( + priv->current_ap, + nm_platform_wifi_get_rate(nm_device_get_platform(device), ifindex)); + + if (ap_changed) + _ap_dump(self, LOGL_DEBUG, priv->current_ap, "updated", 0); + } + + nm_active_connection_set_specific_object( + NM_ACTIVE_CONNECTION(req), + nm_dbus_object_get_path(NM_DBUS_OBJECT(priv->current_ap))); + } + + periodic_update(self); + + update_seen_bssids_cache(self, priv->current_ap); + + priv->scan_periodic_interval_sec = 0; + priv->scan_periodic_next_msec = 0; } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gboolean clear_aps = FALSE; - - if (new_state > NM_DEVICE_STATE_ACTIVATED) - wifi_secrets_cancel (self); - - if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) { - /* Clean up the supplicant interface because in these states the - * device cannot be used. - */ - supplicant_interface_release (self); - - nm_clear_g_source (&priv->periodic_update_id); - - cleanup_association_attempt (self, TRUE); - cleanup_supplicant_failures (self); - remove_all_aps (self); - } - - switch (new_state) { - case NM_DEVICE_STATE_UNMANAGED: - clear_aps = TRUE; - break; - case NM_DEVICE_STATE_UNAVAILABLE: - /* If the device is enabled and the supplicant manager is ready, - * acquire a supplicant interface and transition to DISCONNECTED because - * the device is now ready to use. - */ - if (priv->enabled && (nm_device_get_firmware_missing (device) == FALSE)) { - if (!priv->sup_iface) - supplicant_interface_acquire (self); - } - clear_aps = TRUE; - break; - case NM_DEVICE_STATE_NEED_AUTH: - if (priv->sup_iface) - nm_supplicant_interface_disconnect (priv->sup_iface); - break; - case NM_DEVICE_STATE_IP_CHECK: - /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ifindex (device), FALSE); - break; - case NM_DEVICE_STATE_ACTIVATED: - activation_success_handler (device); - break; - case NM_DEVICE_STATE_FAILED: - /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), nm_device_get_ifindex (device), FALSE); - break; - case NM_DEVICE_STATE_DISCONNECTED: - break; - default: - break; - } - - if (clear_aps) - remove_all_aps (self); - - _scan_notify_allowed (self, NM_TERNARY_DEFAULT); +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + gboolean clear_aps = FALSE; + + if (new_state > NM_DEVICE_STATE_ACTIVATED) + wifi_secrets_cancel(self); + + if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) { + /* Clean up the supplicant interface because in these states the + * device cannot be used. + */ + supplicant_interface_release(self); + + nm_clear_g_source(&priv->periodic_update_id); + + cleanup_association_attempt(self, TRUE); + cleanup_supplicant_failures(self); + remove_all_aps(self); + } + + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + clear_aps = TRUE; + break; + case NM_DEVICE_STATE_UNAVAILABLE: + /* If the device is enabled and the supplicant manager is ready, + * acquire a supplicant interface and transition to DISCONNECTED because + * the device is now ready to use. + */ + if (priv->enabled && (nm_device_get_firmware_missing(device) == FALSE)) { + if (!priv->sup_iface) + supplicant_interface_acquire(self); + } + clear_aps = TRUE; + break; + case NM_DEVICE_STATE_NEED_AUTH: + if (priv->sup_iface) + nm_supplicant_interface_disconnect(priv->sup_iface); + break; + case NM_DEVICE_STATE_IP_CHECK: + /* Clear any critical protocol notification in the wifi stack */ + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ifindex(device), + FALSE); + break; + case NM_DEVICE_STATE_ACTIVATED: + activation_success_handler(device); + break; + case NM_DEVICE_STATE_FAILED: + /* Clear any critical protocol notification in the wifi stack */ + nm_platform_wifi_indicate_addressing_running(nm_device_get_platform(device), + nm_device_get_ifindex(device), + FALSE); + break; + case NM_DEVICE_STATE_DISCONNECTED: + break; + default: + break; + } + + if (clear_aps) + remove_all_aps(self); + + _scan_notify_allowed(self, NM_TERNARY_DEFAULT); } static gboolean -get_enabled (NMDevice *device) +get_enabled(NMDevice *device) { - return NM_DEVICE_WIFI_GET_PRIVATE (device)->enabled; + return NM_DEVICE_WIFI_GET_PRIVATE(device)->enabled; } static void -set_enabled (NMDevice *device, gboolean enabled) +set_enabled(NMDevice *device, gboolean enabled) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMDeviceState state; + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMDeviceState state; - enabled = !!enabled; + enabled = !!enabled; - if (priv->enabled == enabled) - return; + if (priv->enabled == enabled) + return; - priv->enabled = enabled; + priv->enabled = enabled; - _LOGD (LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); + _LOGD(LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); - state = nm_device_get_state (NM_DEVICE (self)); - if (state < NM_DEVICE_STATE_UNAVAILABLE) { - _LOGD (LOGD_WIFI, "(%s): device blocked by UNMANAGED state", - enabled ? "enable" : "disable"); - return; - } + state = nm_device_get_state(NM_DEVICE(self)); + if (state < NM_DEVICE_STATE_UNAVAILABLE) { + _LOGD(LOGD_WIFI, "(%s): device blocked by UNMANAGED state", enabled ? "enable" : "disable"); + return; + } - if (enabled) { - gboolean no_firmware = FALSE; + if (enabled) { + gboolean no_firmware = FALSE; - if (state != NM_DEVICE_STATE_UNAVAILABLE) - _LOGW (LOGD_CORE, "not in expected unavailable state!"); + if (state != NM_DEVICE_STATE_UNAVAILABLE) + _LOGW(LOGD_CORE, "not in expected unavailable state!"); - if (!nm_device_bring_up (NM_DEVICE (self), TRUE, &no_firmware)) { - _LOGD (LOGD_WIFI, "enable blocked by failure to bring device up"); + if (!nm_device_bring_up(NM_DEVICE(self), TRUE, &no_firmware)) { + _LOGD(LOGD_WIFI, "enable blocked by failure to bring device up"); - if (no_firmware) - nm_device_set_firmware_missing (NM_DEVICE (device), TRUE); - else { - /* The device sucks, or the kernel was lying to us about the killswitch state */ - priv->enabled = FALSE; - } - return; - } + if (no_firmware) + nm_device_set_firmware_missing(NM_DEVICE(device), TRUE); + else { + /* The device sucks, or the kernel was lying to us about the killswitch state */ + priv->enabled = FALSE; + } + return; + } - /* Re-initialize the supplicant interface and wait for it to be ready */ - cleanup_supplicant_failures (self); - supplicant_interface_release (self); - supplicant_interface_acquire (self); + /* Re-initialize the supplicant interface and wait for it to be ready */ + cleanup_supplicant_failures(self); + supplicant_interface_release(self); + supplicant_interface_acquire(self); - _LOGD (LOGD_WIFI, "enable waiting on supplicant state"); - } else { - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_NONE); - nm_device_take_down (NM_DEVICE (self), TRUE); - } + _LOGD(LOGD_WIFI, "enable waiting on supplicant state"); + } else { + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_NONE); + nm_device_take_down(NM_DEVICE(self), TRUE); + } } static gboolean -get_guessed_metered (NMDevice *device) +get_guessed_metered(NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = NM_DEVICE_WIFI(device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - return priv->current_ap && nm_wifi_ap_get_metered (priv->current_ap); + return priv->current_ap && nm_wifi_ap_get_metered(priv->current_ap); } static gboolean -can_reapply_change (NMDevice *device, - const char *setting_name, - NMSetting *s_old, - NMSetting *s_new, - GHashTable *diffs, - GError **error) -{ - NMDeviceClass *device_class; - - /* Only handle wireless setting here, delegate other settings to parent class */ - if (nm_streq (setting_name, NM_SETTING_WIRELESS_SETTING_NAME)) { - return nm_device_hash_check_invalid_keys (diffs, - NM_SETTING_WIRELESS_SETTING_NAME, - error, - NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ - NM_SETTING_WIRELESS_MTU, /* reapplied with IP config */ - NM_SETTING_WIRELESS_WAKE_ON_WLAN); - } - - device_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class); - return device_class->can_reapply_change (device, - setting_name, - s_old, - s_new, - diffs, - error); +can_reapply_change(NMDevice * device, + const char *setting_name, + NMSetting * s_old, + NMSetting * s_new, + GHashTable *diffs, + GError ** error) +{ + NMDeviceClass *device_class; + + /* Only handle wireless setting here, delegate other settings to parent class */ + if (nm_streq(setting_name, NM_SETTING_WIRELESS_SETTING_NAME)) { + return nm_device_hash_check_invalid_keys( + diffs, + NM_SETTING_WIRELESS_SETTING_NAME, + error, + NM_SETTING_WIRELESS_SEEN_BSSIDS, /* ignored */ + NM_SETTING_WIRELESS_MTU, /* reapplied with IP config */ + NM_SETTING_WIRELESS_WAKE_ON_WLAN); + } + + device_class = NM_DEVICE_CLASS(nm_device_wifi_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) +reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new) { - NMDeviceWifi *self = NM_DEVICE_WIFI (device); - NMDeviceState state = nm_device_get_state (device); + NMDeviceWifi *self = NM_DEVICE_WIFI(device); + NMDeviceState state = nm_device_get_state(device); - NM_DEVICE_CLASS (nm_device_wifi_parent_class)->reapply_connection (device, - con_old, - con_new); + NM_DEVICE_CLASS(nm_device_wifi_parent_class)->reapply_connection(device, con_old, con_new); - _LOGD (LOGD_DEVICE, "reapplying wireless settings"); + _LOGD(LOGD_DEVICE, "reapplying wireless settings"); - if ( state >= NM_DEVICE_STATE_CONFIG - && !wake_on_wlan_enable (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); + if (state >= NM_DEVICE_STATE_CONFIG && !wake_on_wlan_enable(self)) + _LOGW(LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDeviceWifi *self = NM_DEVICE_WIFI (object); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - const char **list; - - switch (prop_id) { - case PROP_MODE: - g_value_set_uint (value, priv->mode); - break; - case PROP_BITRATE: - g_value_set_uint (value, priv->rate); - break; - case PROP_CAPABILITIES: - g_value_set_uint (value, priv->capabilities); - break; - case PROP_ACCESS_POINTS: - list = nm_wifi_aps_get_paths (&priv->aps_lst_head, TRUE); - g_value_take_boxed (value, nm_utils_strv_make_deep_copied (list)); - break; - case PROP_ACTIVE_ACCESS_POINT: - nm_dbus_utils_g_value_set_object_path (value, priv->current_ap); - break; - case PROP_SCANNING: - g_value_set_boolean (value, nm_device_wifi_get_scanning (self)); - break; - case PROP_LAST_SCAN: - g_value_set_int64 (value, - priv->scan_last_complete_msec > 0 - ? nm_utils_monotonic_timestamp_as_boottime (priv->scan_last_complete_msec, NM_UTILS_NSEC_PER_MSEC) - : (gint64) -1); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceWifi * self = NM_DEVICE_WIFI(object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + const char ** list; + + switch (prop_id) { + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_BITRATE: + g_value_set_uint(value, priv->rate); + break; + case PROP_CAPABILITIES: + g_value_set_uint(value, priv->capabilities); + break; + case PROP_ACCESS_POINTS: + list = nm_wifi_aps_get_paths(&priv->aps_lst_head, TRUE); + g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + break; + case PROP_ACTIVE_ACCESS_POINT: + nm_dbus_utils_g_value_set_object_path(value, priv->current_ap); + break; + case PROP_SCANNING: + g_value_set_boolean(value, nm_device_wifi_get_scanning(self)); + break; + case PROP_LAST_SCAN: + g_value_set_int64( + value, + priv->scan_last_complete_msec > 0 + ? nm_utils_monotonic_timestamp_as_boottime(priv->scan_last_complete_msec, + NM_UTILS_NSEC_PER_MSEC) + : (gint64) -1); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDeviceWifi *device = NM_DEVICE_WIFI (object); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + NMDeviceWifi * device = NM_DEVICE_WIFI(object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(device); - switch (prop_id) { - case PROP_CAPABILITIES: - /* construct-only */ - priv->capabilities = g_value_get_uint (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_CAPABILITIES: + /* construct-only */ + priv->capabilities = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_wifi_init (NMDeviceWifi *self) +nm_device_wifi_init(NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - c_list_init (&priv->aps_lst_head); - c_list_init (&priv->scanning_prohibited_lst_head); - c_list_init (&priv->scan_request_ssids_lst_head); - priv->aps_idx_by_supplicant_path = g_hash_table_new (nm_direct_hash, NULL); + c_list_init(&priv->aps_lst_head); + c_list_init(&priv->scanning_prohibited_lst_head); + c_list_init(&priv->scan_request_ssids_lst_head); + priv->aps_idx_by_supplicant_path = g_hash_table_new(nm_direct_hash, NULL); - priv->scan_last_request_started_at_msec = G_MININT64; - priv->hidden_probe_scan_warn = TRUE; - priv->mode = NM_802_11_MODE_INFRA; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + priv->scan_last_request_started_at_msec = G_MININT64; + priv->hidden_probe_scan_warn = TRUE; + priv->mode = NM_802_11_MODE_INFRA; + priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; } static void -constructed (GObject *object) +constructed(GObject *object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (object); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = NM_DEVICE_WIFI(object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_device_wifi_parent_class)->constructed(object); - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) - _LOGI (LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); + if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + _LOGI(LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); - /* Connect to the supplicant manager */ - priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ()); + /* Connect to the supplicant manager */ + priv->sup_mgr = g_object_ref(nm_supplicant_manager_get()); } NMDevice * -nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities) -{ - return g_object_new (NM_TYPE_DEVICE_WIFI, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "802.11 Wi-Fi", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIFI, - NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WLAN, - NM_DEVICE_WIFI_CAPABILITIES, (guint) capabilities, - NULL); +nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities) +{ + return g_object_new(NM_TYPE_DEVICE_WIFI, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "802.11 Wi-Fi", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_WIFI, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_WIFI, + NM_DEVICE_RFKILL_TYPE, + RFKILL_TYPE_WLAN, + NM_DEVICE_WIFI_CAPABILITIES, + (guint) capabilities, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (object); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = NM_DEVICE_WIFI(object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_assert (c_list_is_empty (&priv->scanning_prohibited_lst_head)); + nm_assert(c_list_is_empty(&priv->scanning_prohibited_lst_head)); - nm_clear_g_source (&priv->periodic_update_id); + nm_clear_g_source(&priv->periodic_update_id); - wifi_secrets_cancel (self); + wifi_secrets_cancel(self); - cleanup_association_attempt (self, TRUE); - supplicant_interface_release (self); - cleanup_supplicant_failures (self); + cleanup_association_attempt(self, TRUE); + supplicant_interface_release(self); + cleanup_supplicant_failures(self); - g_clear_object (&priv->sup_mgr); + g_clear_object(&priv->sup_mgr); - remove_all_aps (self); + remove_all_aps(self); - if (priv->p2p_device) { - /* Destroy the P2P device. */ - g_object_remove_weak_pointer (G_OBJECT (priv->p2p_device), (gpointer*) &priv->p2p_device); - nm_device_wifi_p2p_remove (g_steal_pointer (&priv->p2p_device)); - } + if (priv->p2p_device) { + /* Destroy the P2P device. */ + g_object_remove_weak_pointer(G_OBJECT(priv->p2p_device), (gpointer *) &priv->p2p_device); + nm_device_wifi_p2p_remove(g_steal_pointer(&priv->p2p_device)); + } - G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_wifi_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (object); - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMDeviceWifi * self = NM_DEVICE_WIFI(object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - nm_assert (c_list_is_empty (&priv->aps_lst_head)); - nm_assert (g_hash_table_size (priv->aps_idx_by_supplicant_path) == 0); + nm_assert(c_list_is_empty(&priv->aps_lst_head)); + nm_assert(g_hash_table_size(priv->aps_idx_by_supplicant_path) == 0); - g_hash_table_unref (priv->aps_idx_by_supplicant_path); + g_hash_table_unref(priv->aps_idx_by_supplicant_path); - G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_device_wifi_parent_class)->finalize(object); } static void -nm_device_wifi_class_init (NMDeviceWifiClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); - - device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIFI); - - device_class->can_auto_connect = can_auto_connect; - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->is_available = is_available; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->get_enabled = get_enabled; - device_class->get_guessed_metered = get_guessed_metered; - device_class->set_enabled = set_enabled; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->get_configured_mtu = get_configured_mtu; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout; - device_class->deactivate_async = deactivate_async; - device_class->deactivate = deactivate; - device_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; - device_class->unmanaged_on_quit = unmanaged_on_quit; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; - - device_class->state_changed = device_state_changed; - - obj_properties[PROP_MODE] = - g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_BITRATE] = - g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ACCESS_POINTS] = - g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", - G_TYPE_STRV, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_ACTIVE_ACCESS_POINT] = - g_param_spec_string (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SCANNING] = - g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LAST_SCAN] = - g_param_spec_int64 (NM_DEVICE_WIFI_LAST_SCAN, "", "", - -1, G_MAXINT64, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[P2P_DEVICE_CREATED] = - g_signal_new (NM_DEVICE_WIFI_P2P_DEVICE_CREATED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_DEVICE); +nm_device_wifi_class_init(NMDeviceWifiClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + dbus_object_class->interface_infos = + NM_DBUS_INTERFACE_INFOS(&nm_interface_info_device_wireless); + + device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_WIFI); + + device_class->can_auto_connect = can_auto_connect; + device_class->get_autoconnect_allowed = get_autoconnect_allowed; + device_class->is_available = is_available; + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + device_class->get_enabled = get_enabled; + device_class->get_guessed_metered = get_guessed_metered; + device_class->set_enabled = set_enabled; + + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->get_configured_mtu = get_configured_mtu; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->act_stage4_ip_config_timeout = act_stage4_ip_config_timeout; + device_class->deactivate_async = deactivate_async; + device_class->deactivate = deactivate; + device_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; + device_class->unmanaged_on_quit = unmanaged_on_quit; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = reapply_connection; + + device_class->state_changed = device_state_changed; + + obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_WIFI_MODE, + "", + "", + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_AP, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_WIFI_BITRATE, + "", + "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACCESS_POINTS] = + g_param_spec_boxed(NM_DEVICE_WIFI_ACCESS_POINTS, + "", + "", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_ACTIVE_ACCESS_POINT] = + g_param_spec_string(NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_WIFI_CAPABILITIES, + "", + "", + 0, + G_MAXUINT32, + NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_WIFI_SCANNING, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LAST_SCAN] = g_param_spec_int64(NM_DEVICE_WIFI_LAST_SCAN, + "", + "", + -1, + G_MAXINT64, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[P2P_DEVICE_CREATED] = g_signal_new(NM_DEVICE_WIFI_P2P_DEVICE_CREATED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + NM_TYPE_DEVICE); } diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index c9fce4e2..713c1480 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2005 - 2016 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -9,12 +9,14 @@ #include "devices/nm-device.h" -#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type ()) -#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) -#define NM_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIFI)) -#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) -#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type()) +#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) +#define NM_DEVICE_WIFI_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_WIFI)) +#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_WIFI)) +#define NM_DEVICE_WIFI_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) #define NM_DEVICE_WIFI_MODE "mode" #define NM_DEVICE_WIFI_BITRATE "bitrate" @@ -24,27 +26,27 @@ #define NM_DEVICE_WIFI_SCANNING "scanning" #define NM_DEVICE_WIFI_LAST_SCAN "last-scan" -#define NM_DEVICE_WIFI_P2P_DEVICE_CREATED "p2p-device-created" +#define NM_DEVICE_WIFI_P2P_DEVICE_CREATED "p2p-device-created" -typedef struct _NMDeviceWifi NMDeviceWifi; +typedef struct _NMDeviceWifi NMDeviceWifi; typedef struct _NMDeviceWifiClass NMDeviceWifiClass; -GType nm_device_wifi_get_type (void); +GType nm_device_wifi_get_type(void); -NMDevice * nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities); +NMDevice *nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities); -const CList *_nm_device_wifi_get_aps (NMDeviceWifi *self); +const CList *_nm_device_wifi_get_aps(NMDeviceWifi *self); -void _nm_device_wifi_request_scan (NMDeviceWifi *self, - GVariant *options, - GDBusMethodInvocation *invocation); +void _nm_device_wifi_request_scan(NMDeviceWifi * self, + GVariant * options, + GDBusMethodInvocation *invocation); -GPtrArray *nmtst_ssids_options_to_ptrarray (GVariant *value, GError **error); +GPtrArray *nmtst_ssids_options_to_ptrarray(GVariant *value, GError **error); -gboolean nm_device_wifi_get_scanning (NMDeviceWifi *self); +gboolean nm_device_wifi_get_scanning(NMDeviceWifi *self); -void nm_device_wifi_scanning_prohibited_track (NMDeviceWifi *self, - gpointer tag, - gboolean temporarily_prohibited); +void nm_device_wifi_scanning_prohibited_track(NMDeviceWifi *self, + gpointer tag, + gboolean temporarily_prohibited); #endif /* __NETWORKMANAGER_DEVICE_WIFI_H__ */ diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 39c863a3..bdff20ac 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Intel Corporation */ @@ -20,354 +20,353 @@ /*****************************************************************************/ typedef struct { - const char *name; - NMIwdNetworkSecurity security; - char buf[0]; + const char * name; + NMIwdNetworkSecurity security; + char buf[0]; } KnownNetworkId; typedef struct { - GDBusProxy *known_network; - NMSettingsConnection *mirror_connection; + GDBusProxy * known_network; + NMSettingsConnection *mirror_connection; } KnownNetworkData; typedef struct { - NMManager *manager; - NMSettings *settings; - GCancellable *cancellable; - gboolean running; - GDBusObjectManager *object_manager; - guint agent_id; - char *agent_path; - GHashTable *known_networks; + NMManager * manager; + NMSettings * settings; + GCancellable * cancellable; + gboolean running; + GDBusObjectManager *object_manager; + guint agent_id; + char * agent_path; + GHashTable * known_networks; } NMIwdManagerPrivate; struct _NMIwdManager { - GObject parent; - NMIwdManagerPrivate _priv; + GObject parent; + NMIwdManagerPrivate _priv; }; struct _NMIwdManagerClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMIwdManager, nm_iwd_manager, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMIwdManager, nm_iwd_manager, G_TYPE_OBJECT) -#define NM_IWD_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMIwdManager, NM_IS_IWD_MANAGER) +#define NM_IWD_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIwdManager, NM_IS_IWD_MANAGER) /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "iwd-manager" -#define _NMLOG_DOMAIN LOGD_WIFI - -#define _NMLOG(level, ...) \ - G_STMT_START { \ - if (nm_logging_enabled (level, _NMLOG_DOMAIN)) { \ - char __prefix[32]; \ - \ - if (self) \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", ""_NMLOG_PREFIX_NAME"", (self)); \ - else \ - g_strlcpy (__prefix, _NMLOG_PREFIX_NAME, sizeof (__prefix)); \ - _nm_log ((level), (_NMLOG_DOMAIN), 0, NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG_PREFIX_NAME "iwd-manager" +#define _NMLOG_DOMAIN LOGD_WIFI + +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled(level, _NMLOG_DOMAIN)) { \ + char __prefix[32]; \ + \ + if (self) \ + g_snprintf(__prefix, \ + sizeof(__prefix), \ + "%s[%p]", \ + ""_NMLOG_PREFIX_NAME \ + "", \ + (self)); \ + else \ + g_strlcpy(__prefix, _NMLOG_PREFIX_NAME, sizeof(__prefix)); \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -static void mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn); +static void mirror_8021x_connection_take_and_delete(NMSettingsConnection *sett_conn); /*****************************************************************************/ static const char * -get_variant_string_or_null (GVariant *v) +get_variant_string_or_null(GVariant *v) { - if (!v) - return NULL; + if (!v) + return NULL; - if ( !g_variant_is_of_type (v, G_VARIANT_TYPE_STRING) - && !g_variant_is_of_type (v, G_VARIANT_TYPE_OBJECT_PATH)) - return NULL; + if (!g_variant_is_of_type(v, G_VARIANT_TYPE_STRING) + && !g_variant_is_of_type(v, G_VARIANT_TYPE_OBJECT_PATH)) + return NULL; - return g_variant_get_string (v, NULL); + return g_variant_get_string(v, NULL); } static const char * -get_property_string_or_null (GDBusProxy *proxy, const char *property) +get_property_string_or_null(GDBusProxy *proxy, const char *property) { - gs_unref_variant GVariant *value = NULL; + gs_unref_variant GVariant *value = NULL; - if (!proxy || !property) - return NULL; + if (!proxy || !property) + return NULL; - value = g_dbus_proxy_get_cached_property (proxy, property); + value = g_dbus_proxy_get_cached_property(proxy, property); - return get_variant_string_or_null (value); + return get_variant_string_or_null(value); } static void -agent_dbus_method_cb (GDBusConnection *connection, - const char *sender, const char *object_path, - const char *interface_name, const char *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) +agent_dbus_method_cb(GDBusConnection * connection, + const char * sender, + const char * object_path, + const char * interface_name, + const char * method_name, + GVariant * parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - const char *network_path, *device_path, *ifname; - gs_unref_object GDBusInterface *network = NULL, *device_obj = NULL; - int ifindex; - NMDevice *device; - gs_free char *name_owner = NULL; - int errsv; - - /* Be paranoid and check the sender address */ - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); - if (!nm_streq0 (name_owner, sender)) - goto return_error; - - if (!strcmp (method_name, "RequestUserPassword")) - g_variant_get (parameters, "(&os)", &network_path, NULL); - else - g_variant_get (parameters, "(&o)", &network_path); - - network = g_dbus_object_manager_get_interface (priv->object_manager, - network_path, - NM_IWD_NETWORK_INTERFACE); - if (!network) { - _LOGE ("unable to find the network object"); - return; - } - - - device_path = get_property_string_or_null (G_DBUS_PROXY (network), "Device"); - if (!device_path) { - _LOGD ("agent-request: device not cached for network %s in IWD Agent request", - network_path); - goto return_error; - } - - device_obj = g_dbus_object_manager_get_interface (priv->object_manager, - device_path, - NM_IWD_DEVICE_INTERFACE); - - ifname = get_property_string_or_null (G_DBUS_PROXY (device_obj), "Name"); - if (!ifname) { - _LOGD ("agent-request: name not cached for device %s in IWD Agent request", - device_path); - goto return_error; - } - - ifindex = if_nametoindex (ifname); - if (!ifindex) { - errsv = errno; - _LOGD ("agent-request: if_nametoindex failed for Name %s for Device at %s: %i", - ifname, device_path, errsv); - goto return_error; - } - - device = nm_manager_get_device_by_ifindex (priv->manager, ifindex); - if (!NM_IS_DEVICE_IWD (device)) { - _LOGD ("agent-request: IWD device named %s is not a Wifi device in IWD Agent request", - ifname); - goto return_error; - } - - if (nm_device_iwd_agent_query (NM_DEVICE_IWD (device), invocation)) - return; - - _LOGD ("agent-request: device %s did not handle the IWD Agent request", ifname); + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + const char * network_path, *device_path, *ifname; + gs_unref_object GDBusInterface *network = NULL, *device_obj = NULL; + int ifindex; + NMDevice * device; + gs_free char * name_owner = NULL; + int errsv; + + /* Be paranoid and check the sender address */ + name_owner = g_dbus_object_manager_client_get_name_owner( + G_DBUS_OBJECT_MANAGER_CLIENT(priv->object_manager)); + if (!nm_streq0(name_owner, sender)) + goto return_error; + + if (!strcmp(method_name, "RequestUserPassword")) + g_variant_get(parameters, "(&os)", &network_path, NULL); + else + g_variant_get(parameters, "(&o)", &network_path); + + network = g_dbus_object_manager_get_interface(priv->object_manager, + network_path, + NM_IWD_NETWORK_INTERFACE); + if (!network) { + _LOGE("unable to find the network object"); + return; + } + + device_path = get_property_string_or_null(G_DBUS_PROXY(network), "Device"); + if (!device_path) { + _LOGD("agent-request: device not cached for network %s in IWD Agent request", network_path); + goto return_error; + } + + device_obj = g_dbus_object_manager_get_interface(priv->object_manager, + device_path, + NM_IWD_DEVICE_INTERFACE); + + ifname = get_property_string_or_null(G_DBUS_PROXY(device_obj), "Name"); + if (!ifname) { + _LOGD("agent-request: name not cached for device %s in IWD Agent request", device_path); + goto return_error; + } + + ifindex = if_nametoindex(ifname); + if (!ifindex) { + errsv = errno; + _LOGD("agent-request: if_nametoindex failed for Name %s for Device at %s: %i", + ifname, + device_path, + errsv); + goto return_error; + } + + device = nm_manager_get_device_by_ifindex(priv->manager, ifindex); + if (!NM_IS_DEVICE_IWD(device)) { + _LOGD("agent-request: IWD device named %s is not a Wifi device in IWD Agent request", + ifname); + goto return_error; + } + + if (nm_device_iwd_agent_query(NM_DEVICE_IWD(device), invocation)) + return; + + _LOGD("agent-request: device %s did not handle the IWD Agent request", ifname); return_error: - /* IWD doesn't look at the specific error */ - g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "Secrets not available for this connection"); + /* IWD doesn't look at the specific error */ + g_dbus_method_invocation_return_error_literal(invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "Secrets not available for this connection"); } -static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - "net.connman.iwd.Agent", - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_GDBUS_METHOD_INFO ( - "RequestPassphrase", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("passphrase", "s"), - ), - ), - NM_DEFINE_GDBUS_METHOD_INFO ( - "RequestPrivateKeyPassphrase", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("passphrase", "s"), - ), - ), - NM_DEFINE_GDBUS_METHOD_INFO ( - "RequestUserNameAndPassword", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("user", "s"), - NM_DEFINE_GDBUS_ARG_INFO ("password", "s"), - ), - ), - NM_DEFINE_GDBUS_METHOD_INFO ( - "RequestUserPassword", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("network", "o"), - NM_DEFINE_GDBUS_ARG_INFO ("user", "s"), - ), - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("password", "s"), - ), - ), - ), -); +static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + "net.connman.iwd.Agent", + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_GDBUS_METHOD_INFO( + "RequestPassphrase", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO( + "RequestPrivateKeyPassphrase", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("passphrase", "s"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO( + "RequestUserNameAndPassword", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("user", "s"), + NM_DEFINE_GDBUS_ARG_INFO("password", "s"), ), ), + NM_DEFINE_GDBUS_METHOD_INFO( + "RequestUserPassword", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("network", "o"), + NM_DEFINE_GDBUS_ARG_INFO("user", "s"), ), + .out_args = + NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("password", "s"), ), ), ), ); static guint -iwd_agent_export (GDBusConnection *connection, gpointer user_data, - char **agent_path, GError **error) +iwd_agent_export(GDBusConnection *connection, gpointer user_data, char **agent_path, GError **error) { - static const GDBusInterfaceVTable vtable = { - .method_call = agent_dbus_method_cb, - }; - char path[50]; - unsigned int rnd; - guint id; - - nm_utils_random_bytes (&rnd, sizeof (rnd)); - - nm_sprintf_buf (path, "/agent/%u", rnd); - - id = g_dbus_connection_register_object (connection, path, - NM_UNCONST_PTR (GDBusInterfaceInfo, &iwd_agent_iface_info), - &vtable, user_data, NULL, error); - - if (id) - *agent_path = g_strdup (path); - return id; + static const GDBusInterfaceVTable vtable = { + .method_call = agent_dbus_method_cb, + }; + char path[50]; + unsigned int rnd; + guint id; + + nm_utils_random_bytes(&rnd, sizeof(rnd)); + + nm_sprintf_buf(path, "/agent/%u", rnd); + + id = + g_dbus_connection_register_object(connection, + path, + NM_UNCONST_PTR(GDBusInterfaceInfo, &iwd_agent_iface_info), + &vtable, + user_data, + NULL, + error); + + if (id) + *agent_path = g_strdup(path); + return id; } static void -register_agent (NMIwdManager *self) +register_agent(NMIwdManager *self) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusInterface *agent_manager; - - agent_manager = g_dbus_object_manager_get_interface (priv->object_manager, - "/net/connman/iwd", - NM_IWD_AGENT_MANAGER_INTERFACE); - - if (!agent_manager) { - /* IWD prior to 1.0 dated 30 October, 2019 has the agent manager on a - * different path. */ - agent_manager = g_dbus_object_manager_get_interface (priv->object_manager, - "/", - NM_IWD_AGENT_MANAGER_INTERFACE); - } - - if (!agent_manager) { - _LOGE ("unable to register the IWD Agent: PSK/8021x Wi-Fi networks may not work"); - return; - } - - /* Register our agent */ - g_dbus_proxy_call (G_DBUS_PROXY (agent_manager), - "RegisterAgent", - g_variant_new ("(o)", priv->agent_path), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, NULL, NULL); - - g_object_unref (agent_manager); + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GDBusInterface * agent_manager; + + agent_manager = g_dbus_object_manager_get_interface(priv->object_manager, + "/net/connman/iwd", + NM_IWD_AGENT_MANAGER_INTERFACE); + + if (!agent_manager) { + /* IWD prior to 1.0 dated 30 October, 2019 has the agent manager on a + * different path. */ + agent_manager = g_dbus_object_manager_get_interface(priv->object_manager, + "/", + NM_IWD_AGENT_MANAGER_INTERFACE); + } + + if (!agent_manager) { + _LOGE("unable to register the IWD Agent: PSK/8021x Wi-Fi networks may not work"); + return; + } + + /* Register our agent */ + g_dbus_proxy_call(G_DBUS_PROXY(agent_manager), + "RegisterAgent", + g_variant_new("(o)", priv->agent_path), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); + + g_object_unref(agent_manager); } /*****************************************************************************/ static KnownNetworkId * -known_network_id_new (const char *name, NMIwdNetworkSecurity security) +known_network_id_new(const char *name, NMIwdNetworkSecurity security) { - KnownNetworkId *id; - gsize strsize = strlen (name) + 1; + KnownNetworkId *id; + gsize strsize = strlen(name) + 1; - id = g_malloc (sizeof (KnownNetworkId) + strsize); - id->name = id->buf; - id->security = security; - memcpy (id->buf, name, strsize); + id = g_malloc(sizeof(KnownNetworkId) + strsize); + id->name = id->buf; + id->security = security; + memcpy(id->buf, name, strsize); - return id; + return id; } static guint -known_network_id_hash (KnownNetworkId *id) +known_network_id_hash(KnownNetworkId *id) { - NMHashState h; + NMHashState h; - nm_hash_init (&h, 1947951703u); - nm_hash_update_val (&h, id->security); - nm_hash_update_str (&h, id->name); - return nm_hash_complete (&h); + nm_hash_init(&h, 1947951703u); + nm_hash_update_val(&h, id->security); + nm_hash_update_str(&h, id->name); + return nm_hash_complete(&h); } static gboolean -known_network_id_equal (KnownNetworkId *a, KnownNetworkId *b) +known_network_id_equal(KnownNetworkId *a, KnownNetworkId *b) { - return a->security == b->security - && nm_streq (a->name, b->name); + return a->security == b->security && nm_streq(a->name, b->name); } static void -known_network_data_free (KnownNetworkData *network) +known_network_data_free(KnownNetworkData *network) { - if (!network) - return; + if (!network) + return; - g_object_unref (network->known_network); - mirror_8021x_connection_take_and_delete (network->mirror_connection); - g_slice_free (KnownNetworkData, network); + g_object_unref(network->known_network); + mirror_8021x_connection_take_and_delete(network->mirror_connection); + g_slice_free(KnownNetworkData, network); } /*****************************************************************************/ static void -set_device_dbus_object (NMIwdManager *self, GDBusProxy *proxy, - GDBusObject *object) +set_device_dbus_object(NMIwdManager *self, GDBusProxy *proxy, GDBusObject *object) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - const char *ifname; - int ifindex; - NMDevice *device; - int errsv; - - ifname = get_property_string_or_null (proxy, "Name"); - if (!ifname) { - _LOGE ("Name not cached for Device at %s", - g_dbus_proxy_get_object_path (proxy)); - return; - } - - ifindex = if_nametoindex (ifname); - - if (!ifindex) { - errsv = errno; - _LOGE ("if_nametoindex failed for Name %s for Device at %s: %i", - ifname, g_dbus_proxy_get_object_path (proxy), errsv); - return; - } - - device = nm_manager_get_device_by_ifindex (priv->manager, ifindex); - if (!NM_IS_DEVICE_IWD (device)) { - _LOGE ("IWD device named %s is not a Wifi device", ifname); - return; - } - - nm_device_iwd_set_dbus_object (NM_DEVICE_IWD (device), object); + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + const char * ifname; + int ifindex; + NMDevice * device; + int errsv; + + ifname = get_property_string_or_null(proxy, "Name"); + if (!ifname) { + _LOGE("Name not cached for Device at %s", g_dbus_proxy_get_object_path(proxy)); + return; + } + + ifindex = if_nametoindex(ifname); + + if (!ifindex) { + errsv = errno; + _LOGE("if_nametoindex failed for Name %s for Device at %s: %i", + ifname, + g_dbus_proxy_get_object_path(proxy), + errsv); + return; + } + + device = nm_manager_get_device_by_ifindex(priv->manager, ifindex); + if (!NM_IS_DEVICE_IWD(device)) { + _LOGE("IWD device named %s is not a Wifi device", ifname); + return; + } + + nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), object); } /* Look up an existing NMSettingsConnection for a WPA2-Enterprise network @@ -377,578 +376,596 @@ set_device_dbus_object (NMIwdManager *self, GDBusProxy *proxy, * the user. */ static NMSettingsConnection * -mirror_8021x_connection (NMIwdManager *self, - const char *name, - gboolean create_new) +mirror_8021x_connection(NMIwdManager *self, const char *name, gboolean create_new) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - NMSettingsConnection *const*iter; - gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *settings_connection = NULL; - char uuid[37]; - NMSetting *setting; - GError *error = NULL; - gs_unref_bytes GBytes *new_ssid = NULL; - - for (iter = nm_settings_get_connections (priv->settings, NULL); *iter; iter++) { - NMSettingsConnection *sett_conn = *iter; - NMConnection *conn = nm_settings_connection_get_connection (sett_conn); - NMIwdNetworkSecurity security; - gs_free char *ssid_name = NULL; - NMSettingWireless *s_wifi; - NMSetting8021x *s_8021x; - gboolean external = FALSE; - guint i; - - security = nm_wifi_connection_get_iwd_security (conn, NULL); - if (security != NM_IWD_NETWORK_SECURITY_8021X) - continue; - - s_wifi = nm_connection_get_setting_wireless (conn); - if (!s_wifi) - continue; - - ssid_name = _nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wifi)); - - if (!nm_streq (ssid_name, name)) - continue; - - s_8021x = nm_connection_get_setting_802_1x (conn); - for (i = 0; i < nm_setting_802_1x_get_num_eap_methods (s_8021x); i++) { - if (nm_streq (nm_setting_802_1x_get_eap_method (s_8021x, i), "external")) { - external = TRUE; - break; - } - } - - /* Prefer returning connections for EAP method "external" */ - if (!settings_connection || external) - settings_connection = sett_conn; - } - - /* If we already have an NMSettingsConnection matching this - * KnownNetwork, whether it's saved or an in-memory connection - * potentially created by ourselves then we have nothing left to - * do here. - */ - if (settings_connection || !create_new) - return settings_connection; - - connection = nm_simple_connection_new (); - - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_CONNECTION, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_CONNECTION_ID, name, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf (uuid), - NULL)); - nm_connection_add_setting (connection, setting); - - new_ssid = g_bytes_new (name, strlen (name)); - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_WIRELESS, - NM_SETTING_WIRELESS_SSID, new_ssid, - NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, - NULL)); - nm_connection_add_setting (connection, setting); - - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", - NULL)); - nm_connection_add_setting (connection, setting); - - /* "password" and "private-key-password" may be requested by the IWD agent - * from NM and IWD will implement a specific secret cache policy so by - * default respect that policy and don't save copies of those secrets in - * NM settings. The saved values can not be used anyway because of our - * use of NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW. - */ - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_802_1X, - NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED, - NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED, - NULL)); - nm_setting_802_1x_add_eap_method (NM_SETTING_802_1X (setting), "external"); - nm_connection_add_setting (connection, setting); - - if (!nm_connection_normalize (connection, NULL, NULL, NULL)) - return NULL; - - if (!nm_settings_add_connection (priv->settings, - connection, - NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, - NM_SETTINGS_CONNECTION_ADD_REASON_NONE, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, - &settings_connection, - &error)) { - _LOGW ("failed to add a mirror NMConnection for IWD's Known Network '%s': %s", - name, error->message); - g_error_free (error); - return NULL; - } - - return settings_connection; + NMIwdManagerPrivate * priv = NM_IWD_MANAGER_GET_PRIVATE(self); + NMSettingsConnection *const *iter; + gs_unref_object NMConnection *connection = NULL; + NMSettingsConnection * settings_connection = NULL; + char uuid[37]; + NMSetting * setting; + GError * error = NULL; + gs_unref_bytes GBytes *new_ssid = NULL; + + for (iter = nm_settings_get_connections(priv->settings, NULL); *iter; iter++) { + NMSettingsConnection *sett_conn = *iter; + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMIwdNetworkSecurity security; + gs_free char * ssid_name = NULL; + NMSettingWireless * s_wifi; + NMSetting8021x * s_8021x; + gboolean external = FALSE; + guint i; + + security = nm_wifi_connection_get_iwd_security(conn, NULL); + if (security != NM_IWD_NETWORK_SECURITY_8021X) + continue; + + s_wifi = nm_connection_get_setting_wireless(conn); + if (!s_wifi) + continue; + + ssid_name = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wifi)); + + if (!nm_streq(ssid_name, name)) + continue; + + s_8021x = nm_connection_get_setting_802_1x(conn); + for (i = 0; i < nm_setting_802_1x_get_num_eap_methods(s_8021x); i++) { + if (nm_streq(nm_setting_802_1x_get_eap_method(s_8021x, i), "external")) { + external = TRUE; + break; + } + } + + /* Prefer returning connections for EAP method "external" */ + if (!settings_connection || external) + settings_connection = sett_conn; + } + + /* If we already have an NMSettingsConnection matching this + * KnownNetwork, whether it's saved or an in-memory connection + * potentially created by ourselves then we have nothing left to + * do here. + */ + if (settings_connection || !create_new) + return settings_connection; + + connection = nm_simple_connection_new(); + + setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_CONNECTION, + NM_SETTING_CONNECTION_TYPE, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_CONNECTION_ID, + name, + NM_SETTING_CONNECTION_UUID, + nm_utils_uuid_generate_buf(uuid), + NULL)); + nm_connection_add_setting(connection, setting); + + new_ssid = g_bytes_new(name, strlen(name)); + setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_WIRELESS, + NM_SETTING_WIRELESS_SSID, + new_ssid, + NM_SETTING_WIRELESS_MODE, + NM_SETTING_WIRELESS_MODE_INFRA, + NULL)); + nm_connection_add_setting(connection, setting); + + setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_WIRELESS_SECURITY, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-eap", + NULL)); + nm_connection_add_setting(connection, setting); + + /* "password" and "private-key-password" may be requested by the IWD agent + * from NM and IWD will implement a specific secret cache policy so by + * default respect that policy and don't save copies of those secrets in + * NM settings. The saved values can not be used anyway because of our + * use of NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW. + */ + setting = NM_SETTING(g_object_new(NM_TYPE_SETTING_802_1X, + NM_SETTING_802_1X_PASSWORD_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, + NM_SETTING_SECRET_FLAG_NOT_SAVED, + NULL)); + nm_setting_802_1x_add_eap_method(NM_SETTING_802_1X(setting), "external"); + nm_connection_add_setting(connection, setting); + + if (!nm_connection_normalize(connection, NULL, NULL, NULL)) + return NULL; + + if (!nm_settings_add_connection(priv->settings, + connection, + NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY, + NM_SETTINGS_CONNECTION_ADD_REASON_NONE, + NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, + &settings_connection, + &error)) { + _LOGW("failed to add a mirror NMConnection for IWD's Known Network '%s': %s", + name, + error->message); + g_error_free(error); + return NULL; + } + + return settings_connection; } static void -mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn) +mirror_8021x_connection_take_and_delete(NMSettingsConnection *sett_conn) { - NMSettingsConnectionIntFlags flags; + NMSettingsConnectionIntFlags flags; - if (!sett_conn) - return; + if (!sett_conn) + return; - flags = nm_settings_connection_get_flags (sett_conn); + flags = nm_settings_connection_get_flags(sett_conn); - /* If connection has not been saved since we created it - * in interface_added it too can be removed now. */ - if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) - nm_settings_connection_delete (sett_conn, FALSE); + /* If connection has not been saved since we created it + * in interface_added it too can be removed now. */ + if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) + nm_settings_connection_delete(sett_conn, FALSE); - g_object_unref (sett_conn); + g_object_unref(sett_conn); } static void -interface_added (GDBusObjectManager *object_manager, GDBusObject *object, - GDBusInterface *interface, gpointer user_data) +interface_added(GDBusObjectManager *object_manager, + GDBusObject * object, + GDBusInterface * interface, + gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusProxy *proxy; - const char *iface_name; - - if (!priv->running) - return; - - g_return_if_fail (G_IS_DBUS_PROXY (interface)); - - proxy = G_DBUS_PROXY (interface); - iface_name = g_dbus_proxy_get_interface_name (proxy); - - if (nm_streq (iface_name, NM_IWD_DEVICE_INTERFACE)) { - set_device_dbus_object (self, proxy, object); - return; - } - - if (nm_streq (iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { - KnownNetworkId *id; - KnownNetworkData *data; - NMIwdNetworkSecurity security; - const char *type_str, *name; - NMSettingsConnection *sett_conn = NULL; - - type_str = get_property_string_or_null (proxy, "Type"); - name = get_property_string_or_null (proxy, "Name"); - if (!type_str || !name) - return; - - if (nm_streq (type_str, "open")) - security = NM_IWD_NETWORK_SECURITY_NONE; - else if (nm_streq (type_str, "psk")) - security = NM_IWD_NETWORK_SECURITY_PSK; - else if (nm_streq (type_str, "8021x")) - security = NM_IWD_NETWORK_SECURITY_8021X; - else - return; - - id = known_network_id_new (name, security); - - data = g_hash_table_lookup (priv->known_networks, id); - if (data) { - _LOGW ("DBus error: KnownNetwork already exists ('%s', %s)", - name, type_str); - g_free (id); - nm_g_object_ref_set (&data->known_network, proxy); - } else { - data = g_slice_new0 (KnownNetworkData); - data->known_network = g_object_ref (proxy); - g_hash_table_insert (priv->known_networks, id, data); - } - - if (security == NM_IWD_NETWORK_SECURITY_8021X) { - sett_conn = mirror_8021x_connection (self, name, TRUE); - - if ( sett_conn - && sett_conn != data->mirror_connection) { - NMSettingsConnection *sett_conn_old = data->mirror_connection; - - data->mirror_connection = nm_g_object_ref (sett_conn); - mirror_8021x_connection_take_and_delete (sett_conn_old); - } - } else - mirror_8021x_connection_take_and_delete (g_steal_pointer (&data->mirror_connection)); - - return; - } + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GDBusProxy * proxy; + const char * iface_name; + + if (!priv->running) + return; + + g_return_if_fail(G_IS_DBUS_PROXY(interface)); + + proxy = G_DBUS_PROXY(interface); + iface_name = g_dbus_proxy_get_interface_name(proxy); + + if (nm_streq(iface_name, NM_IWD_DEVICE_INTERFACE)) { + set_device_dbus_object(self, proxy, object); + return; + } + + if (nm_streq(iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { + KnownNetworkId * id; + KnownNetworkData * data; + NMIwdNetworkSecurity security; + const char * type_str, *name; + NMSettingsConnection *sett_conn = NULL; + + type_str = get_property_string_or_null(proxy, "Type"); + name = get_property_string_or_null(proxy, "Name"); + if (!type_str || !name) + return; + + if (nm_streq(type_str, "open")) + security = NM_IWD_NETWORK_SECURITY_NONE; + else if (nm_streq(type_str, "psk")) + security = NM_IWD_NETWORK_SECURITY_PSK; + else if (nm_streq(type_str, "8021x")) + security = NM_IWD_NETWORK_SECURITY_8021X; + else + return; + + id = known_network_id_new(name, security); + + data = g_hash_table_lookup(priv->known_networks, id); + if (data) { + _LOGW("DBus error: KnownNetwork already exists ('%s', %s)", name, type_str); + g_free(id); + nm_g_object_ref_set(&data->known_network, proxy); + } else { + data = g_slice_new0(KnownNetworkData); + data->known_network = g_object_ref(proxy); + g_hash_table_insert(priv->known_networks, id, data); + } + + if (security == NM_IWD_NETWORK_SECURITY_8021X) { + sett_conn = mirror_8021x_connection(self, name, TRUE); + + if (sett_conn && sett_conn != data->mirror_connection) { + NMSettingsConnection *sett_conn_old = data->mirror_connection; + + data->mirror_connection = nm_g_object_ref(sett_conn); + mirror_8021x_connection_take_and_delete(sett_conn_old); + } + } else + mirror_8021x_connection_take_and_delete(g_steal_pointer(&data->mirror_connection)); + + return; + } } static void -interface_removed (GDBusObjectManager *object_manager, GDBusObject *object, - GDBusInterface *interface, gpointer user_data) +interface_removed(GDBusObjectManager *object_manager, + GDBusObject * object, + GDBusInterface * interface, + gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusProxy *proxy; - const char *iface_name; - - g_return_if_fail (G_IS_DBUS_PROXY (interface)); - - proxy = G_DBUS_PROXY (interface); - iface_name = g_dbus_proxy_get_interface_name (proxy); - - if (nm_streq (iface_name, NM_IWD_DEVICE_INTERFACE)) { - set_device_dbus_object (self, proxy, NULL); - return; - } - - if (nm_streq (iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { - KnownNetworkId id; - const char *type_str; - - type_str = get_property_string_or_null (proxy, "Type"); - id.name = get_property_string_or_null (proxy, "Name"); - if (!type_str || !id.name) - return; - - if (nm_streq (type_str, "open")) - id.security = NM_IWD_NETWORK_SECURITY_NONE; - else if (nm_streq (type_str, "psk")) - id.security = NM_IWD_NETWORK_SECURITY_PSK; - else if (nm_streq (type_str, "8021x")) - id.security = NM_IWD_NETWORK_SECURITY_8021X; - else - return; - - g_hash_table_remove (priv->known_networks, &id); - return; - } + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GDBusProxy * proxy; + const char * iface_name; + + g_return_if_fail(G_IS_DBUS_PROXY(interface)); + + proxy = G_DBUS_PROXY(interface); + iface_name = g_dbus_proxy_get_interface_name(proxy); + + if (nm_streq(iface_name, NM_IWD_DEVICE_INTERFACE)) { + set_device_dbus_object(self, proxy, NULL); + return; + } + + if (nm_streq(iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { + KnownNetworkId id; + const char * type_str; + + type_str = get_property_string_or_null(proxy, "Type"); + id.name = get_property_string_or_null(proxy, "Name"); + if (!type_str || !id.name) + return; + + if (nm_streq(type_str, "open")) + id.security = NM_IWD_NETWORK_SECURITY_NONE; + else if (nm_streq(type_str, "psk")) + id.security = NM_IWD_NETWORK_SECURITY_PSK; + else if (nm_streq(type_str, "8021x")) + id.security = NM_IWD_NETWORK_SECURITY_8021X; + else + return; + + g_hash_table_remove(priv->known_networks, &id); + return; + } } static void -connection_removed (NMSettings *settings, - NMSettingsConnection *sett_conn, - gpointer user_data) +connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - NMConnection *conn = nm_settings_connection_get_connection (sett_conn); - NMSettingWireless *s_wireless; - gboolean mapped; - KnownNetworkData *data; - KnownNetworkId id; - - id.security = nm_wifi_connection_get_iwd_security (conn, &mapped); - if (!mapped) - return; - - s_wireless = nm_connection_get_setting_wireless (conn); - id.name = _nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wireless)); - data = g_hash_table_lookup (priv->known_networks, &id); - g_free ((char *) id.name); - if (!data) - return; - - if (id.security == NM_IWD_NETWORK_SECURITY_8021X) { - NMSettingsConnection *new_mirror_conn; - - if (data->mirror_connection != sett_conn) - return; - - g_clear_object (&data->mirror_connection); - - /* Don't call Forget for an 8021x network until there's no - * longer *any* matching NMSettingsConnection (debatable) - */ - new_mirror_conn = mirror_8021x_connection (self, id.name, FALSE); - if (new_mirror_conn) { - data->mirror_connection = g_object_ref (new_mirror_conn); - return; - } - } - - if (!priv->running) - return; - - g_dbus_proxy_call (data->known_network, "Forget", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingWireless * s_wireless; + gboolean mapped; + KnownNetworkData * data; + KnownNetworkId id; + + id.security = nm_wifi_connection_get_iwd_security(conn, &mapped); + if (!mapped) + return; + + s_wireless = nm_connection_get_setting_wireless(conn); + id.name = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless)); + data = g_hash_table_lookup(priv->known_networks, &id); + g_free((char *) id.name); + if (!data) + return; + + if (id.security == NM_IWD_NETWORK_SECURITY_8021X) { + NMSettingsConnection *new_mirror_conn; + + if (data->mirror_connection != sett_conn) + return; + + g_clear_object(&data->mirror_connection); + + /* Don't call Forget for an 8021x network until there's no + * longer *any* matching NMSettingsConnection (debatable) + */ + new_mirror_conn = mirror_8021x_connection(self, id.name, FALSE); + if (new_mirror_conn) { + data->mirror_connection = g_object_ref(new_mirror_conn); + return; + } + } + + if (!priv->running) + return; + + g_dbus_proxy_call(data->known_network, + "Forget", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); } static gboolean -_om_has_name_owner (GDBusObjectManager *object_manager) +_om_has_name_owner(GDBusObjectManager *object_manager) { - gs_free char *name_owner = NULL; + gs_free char *name_owner = NULL; - nm_assert (G_IS_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); + nm_assert(G_IS_DBUS_OBJECT_MANAGER_CLIENT(object_manager)); - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); - return !!name_owner; + name_owner = + g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(object_manager)); + return !!name_owner; } static void -object_added (NMIwdManager *self, GDBusObject *object) +object_added(NMIwdManager *self, GDBusObject *object) { - GList *interfaces, *iter; + GList *interfaces, *iter; - interfaces = g_dbus_object_get_interfaces (object); + interfaces = g_dbus_object_get_interfaces(object); - for (iter = interfaces; iter; iter = iter->next) { - GDBusInterface *interface = G_DBUS_INTERFACE (iter->data); + for (iter = interfaces; iter; iter = iter->next) { + GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); - interface_added (NULL, object, interface, self); - } + interface_added(NULL, object, interface, self); + } - g_list_free_full (interfaces, g_object_unref); + g_list_free_full(interfaces, g_object_unref); } static void -release_object_manager (NMIwdManager *self) +release_object_manager(NMIwdManager *self) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); - if (!priv->object_manager) - return; + if (!priv->object_manager) + return; - g_signal_handlers_disconnect_by_data (priv->object_manager, self); + g_signal_handlers_disconnect_by_data(priv->object_manager, self); - if (priv->agent_id) { - GDBusConnection *agent_connection; - GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager); + if (priv->agent_id) { + GDBusConnection * agent_connection; + GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT(priv->object_manager); - agent_connection = g_dbus_object_manager_client_get_connection (omc); + agent_connection = g_dbus_object_manager_client_get_connection(omc); - /* We're is called when we're shutting down (i.e. our DBus connection - * is being closed, and IWD will detect this) or IWD was stopped so - * in either case calling UnregisterAgent will not do anything. - */ - g_dbus_connection_unregister_object (agent_connection, priv->agent_id); - priv->agent_id = 0; - nm_clear_g_free (&priv->agent_path); - } + /* We're is called when we're shutting down (i.e. our DBus connection + * is being closed, and IWD will detect this) or IWD was stopped so + * in either case calling UnregisterAgent will not do anything. + */ + g_dbus_connection_unregister_object(agent_connection, priv->agent_id); + priv->agent_id = 0; + nm_clear_g_free(&priv->agent_path); + } - g_clear_object (&priv->object_manager); + g_clear_object(&priv->object_manager); } -static void prepare_object_manager (NMIwdManager *self); +static void prepare_object_manager(NMIwdManager *self); static void -name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +name_owner_changed(GObject *object, GParamSpec *pspec, gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object); - - nm_assert (object_manager == priv->object_manager); - - if (_om_has_name_owner (object_manager)) { - release_object_manager (self); - prepare_object_manager (self); - } else { - const CList *tmp_lst; - NMDevice *device; - - if (!priv->running) - return; - - priv->running = false; - - nm_manager_for_each_device (priv->manager, device, tmp_lst) { - if (NM_IS_DEVICE_IWD (device)) { - nm_device_iwd_set_dbus_object (NM_DEVICE_IWD (device), - NULL); - } - } - } + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GDBusObjectManager * object_manager = G_DBUS_OBJECT_MANAGER(object); + + nm_assert(object_manager == priv->object_manager); + + if (_om_has_name_owner(object_manager)) { + release_object_manager(self); + prepare_object_manager(self); + } else { + const CList *tmp_lst; + NMDevice * device; + + if (!priv->running) + return; + + priv->running = false; + + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + if (NM_IS_DEVICE_IWD(device)) { + nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), NULL); + } + } + } } static void -device_added (NMManager *manager, NMDevice *device, gpointer user_data) +device_added(NMManager *manager, NMDevice *device, gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GList *objects, *iter; + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GList * objects, *iter; - if (!NM_IS_DEVICE_IWD (device)) - return; + if (!NM_IS_DEVICE_IWD(device)) + return; - if (!priv->running) - return; + if (!priv->running) + return; - objects = g_dbus_object_manager_get_objects (priv->object_manager); - for (iter = objects; iter; iter = iter->next) { - GDBusObject *object = G_DBUS_OBJECT (iter->data); - gs_unref_object GDBusInterface *interface = NULL; - const char *obj_ifname; + objects = g_dbus_object_manager_get_objects(priv->object_manager); + for (iter = objects; iter; iter = iter->next) { + GDBusObject * object = G_DBUS_OBJECT(iter->data); + gs_unref_object GDBusInterface *interface = NULL; + const char * obj_ifname; - interface = g_dbus_object_get_interface (object, - NM_IWD_DEVICE_INTERFACE); - obj_ifname = get_property_string_or_null ((GDBusProxy *) interface, "Name"); + interface = g_dbus_object_get_interface(object, NM_IWD_DEVICE_INTERFACE); + obj_ifname = get_property_string_or_null((GDBusProxy *) interface, "Name"); - if (!obj_ifname || strcmp (nm_device_get_iface (device), obj_ifname)) - continue; + if (!obj_ifname || strcmp(nm_device_get_iface(device), obj_ifname)) + continue; - nm_device_iwd_set_dbus_object (NM_DEVICE_IWD (device), object); - break; - } + nm_device_iwd_set_dbus_object(NM_DEVICE_IWD(device), object); + break; + } - g_list_free_full (objects, g_object_unref); + g_list_free_full(objects, g_object_unref); } static void -got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) +got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) { - NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GError *error = NULL; - GDBusObjectManager *object_manager; - GDBusConnection *connection; - - object_manager = g_dbus_object_manager_client_new_for_bus_finish (result, &error); - if (object_manager == NULL) { - _LOGE ("failed to acquire IWD Object Manager: Wi-Fi will not be available (%s)", - error->message); - g_clear_error (&error); - return; - } - - priv->object_manager = object_manager; - - g_signal_connect (priv->object_manager, "notify::name-owner", - G_CALLBACK (name_owner_changed), self); - - nm_assert (G_IS_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); - - connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); - - priv->agent_id = iwd_agent_export (connection, - self, - &priv->agent_path, - &error); - if (!priv->agent_id) { - _LOGE ("failed to export the IWD Agent: PSK/8021x Wi-Fi networks may not work: %s", - error->message); - g_clear_error (&error); - } - - if (_om_has_name_owner (object_manager)) { - GList *objects, *iter; - - priv->running = true; - - g_signal_connect (priv->object_manager, "interface-added", - G_CALLBACK (interface_added), self); - g_signal_connect (priv->object_manager, "interface-removed", - G_CALLBACK (interface_removed), self); - - g_hash_table_remove_all (priv->known_networks); - - objects = g_dbus_object_manager_get_objects (object_manager); - for (iter = objects; iter; iter = iter->next) - object_added (self, G_DBUS_OBJECT (iter->data)); - - g_list_free_full (objects, g_object_unref); - - if (priv->agent_id) - register_agent (self); - } + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GError * error = NULL; + GDBusObjectManager * object_manager; + GDBusConnection * connection; + + object_manager = g_dbus_object_manager_client_new_for_bus_finish(result, &error); + if (object_manager == NULL) { + _LOGE("failed to acquire IWD Object Manager: Wi-Fi will not be available (%s)", + error->message); + g_clear_error(&error); + return; + } + + priv->object_manager = object_manager; + + g_signal_connect(priv->object_manager, + "notify::name-owner", + G_CALLBACK(name_owner_changed), + self); + + nm_assert(G_IS_DBUS_OBJECT_MANAGER_CLIENT(object_manager)); + + connection = + g_dbus_object_manager_client_get_connection(G_DBUS_OBJECT_MANAGER_CLIENT(object_manager)); + + priv->agent_id = iwd_agent_export(connection, self, &priv->agent_path, &error); + if (!priv->agent_id) { + _LOGE("failed to export the IWD Agent: PSK/8021x Wi-Fi networks may not work: %s", + error->message); + g_clear_error(&error); + } + + if (_om_has_name_owner(object_manager)) { + GList *objects, *iter; + + priv->running = true; + + g_signal_connect(priv->object_manager, + "interface-added", + G_CALLBACK(interface_added), + self); + g_signal_connect(priv->object_manager, + "interface-removed", + G_CALLBACK(interface_removed), + self); + + g_hash_table_remove_all(priv->known_networks); + + objects = g_dbus_object_manager_get_objects(object_manager); + for (iter = objects; iter; iter = iter->next) + object_added(self, G_DBUS_OBJECT(iter->data)); + + g_list_free_full(objects, g_object_unref); + + if (priv->agent_id) + register_agent(self); + } } static void -prepare_object_manager (NMIwdManager *self) +prepare_object_manager(NMIwdManager *self) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - - g_dbus_object_manager_client_new_for_bus (NM_IWD_BUS_TYPE, - G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, - NM_IWD_SERVICE, "/", - NULL, NULL, NULL, - priv->cancellable, - got_object_manager, self); + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + + g_dbus_object_manager_client_new_for_bus(NM_IWD_BUS_TYPE, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + NM_IWD_SERVICE, + "/", + NULL, + NULL, + NULL, + priv->cancellable, + got_object_manager, + self); } gboolean -nm_iwd_manager_is_known_network (NMIwdManager *self, const char *name, - NMIwdNetworkSecurity security) +nm_iwd_manager_is_known_network(NMIwdManager *self, const char *name, NMIwdNetworkSecurity security) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - KnownNetworkId kn_id = { name, security }; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + KnownNetworkId kn_id = {name, security}; - return g_hash_table_contains (priv->known_networks, &kn_id); + return g_hash_table_contains(priv->known_networks, &kn_id); } GDBusProxy * -nm_iwd_manager_get_dbus_interface (NMIwdManager *self, - const char *path, - const char *name) +nm_iwd_manager_get_dbus_interface(NMIwdManager *self, const char *path, const char *name) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusInterface *interface; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + GDBusInterface * interface; - if (!priv->object_manager) - return NULL; + if (!priv->object_manager) + return NULL; - interface = g_dbus_object_manager_get_interface (priv->object_manager, path, name); + interface = g_dbus_object_manager_get_interface(priv->object_manager, path, name); - return interface ? G_DBUS_PROXY (interface) : NULL; + return interface ? G_DBUS_PROXY(interface) : NULL; } /*****************************************************************************/ -NM_DEFINE_SINGLETON_GETTER (NMIwdManager, nm_iwd_manager_get, - NM_TYPE_IWD_MANAGER); +NM_DEFINE_SINGLETON_GETTER(NMIwdManager, nm_iwd_manager_get, NM_TYPE_IWD_MANAGER); static void -nm_iwd_manager_init (NMIwdManager *self) +nm_iwd_manager_init(NMIwdManager *self) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); - priv->manager = g_object_ref (NM_MANAGER_GET); - g_signal_connect (priv->manager, NM_MANAGER_DEVICE_ADDED, - G_CALLBACK (device_added), self); + priv->manager = g_object_ref(NM_MANAGER_GET); + g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added), self); - priv->settings = g_object_ref (NM_SETTINGS_GET); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, - G_CALLBACK (connection_removed), self); + priv->settings = g_object_ref(NM_SETTINGS_GET); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + G_CALLBACK(connection_removed), + self); - priv->cancellable = g_cancellable_new (); + priv->cancellable = g_cancellable_new(); - priv->known_networks = g_hash_table_new_full ((GHashFunc) known_network_id_hash, - (GEqualFunc) known_network_id_equal, - g_free, - (GDestroyNotify) known_network_data_free); + priv->known_networks = g_hash_table_new_full((GHashFunc) known_network_id_hash, + (GEqualFunc) known_network_id_equal, + g_free, + (GDestroyNotify) known_network_data_free); - prepare_object_manager (self); + prepare_object_manager(self); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMIwdManager *self = (NMIwdManager *) object; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + NMIwdManager * self = (NMIwdManager *) object; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); - release_object_manager (self); + release_object_manager(self); - nm_clear_g_cancellable (&priv->cancellable); + nm_clear_g_cancellable(&priv->cancellable); - if (priv->settings) { - g_signal_handlers_disconnect_by_data (priv->settings, self); - g_clear_object (&priv->settings); - } + if (priv->settings) { + g_signal_handlers_disconnect_by_data(priv->settings, self); + g_clear_object(&priv->settings); + } - /* This may trigger mirror connection removals so it happens - * after the g_signal_handlers_disconnect_by_data above. - */ - nm_clear_pointer (&priv->known_networks, g_hash_table_destroy); + /* This may trigger mirror connection removals so it happens + * after the g_signal_handlers_disconnect_by_data above. + */ + nm_clear_pointer(&priv->known_networks, g_hash_table_destroy); - if (priv->manager) { - g_signal_handlers_disconnect_by_data (priv->manager, self); - g_clear_object (&priv->manager); - } + if (priv->manager) { + g_signal_handlers_disconnect_by_data(priv->manager, self); + g_clear_object(&priv->manager); + } - G_OBJECT_CLASS (nm_iwd_manager_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_iwd_manager_parent_class)->dispose(object); } static void -nm_iwd_manager_class_init (NMIwdManagerClass *klass) +nm_iwd_manager_class_init(NMIwdManagerClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; } diff --git a/src/devices/wifi/nm-iwd-manager.h b/src/devices/wifi/nm-iwd-manager.h index c50963fe..00f0c304 100644 --- a/src/devices/wifi/nm-iwd-manager.h +++ b/src/devices/wifi/nm-iwd-manager.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2017 Intel Corporation */ @@ -9,40 +9,42 @@ #include "devices/nm-device.h" #include "nm-wifi-utils.h" -#define NM_IWD_BUS_TYPE G_BUS_TYPE_SYSTEM -#define NM_IWD_SERVICE "net.connman.iwd" - -#define NM_IWD_AGENT_MANAGER_INTERFACE "net.connman.iwd.AgentManager" -#define NM_IWD_WIPHY_INTERFACE "net.connman.iwd.Adapter" -#define NM_IWD_DEVICE_INTERFACE "net.connman.iwd.Device" -#define NM_IWD_NETWORK_INTERFACE "net.connman.iwd.Network" -#define NM_IWD_AGENT_INTERFACE "net.connman.iwd.Agent" -#define NM_IWD_WSC_INTERFACE \ - "net.connman.iwd.WiFiSimpleConfiguration" -#define NM_IWD_KNOWN_NETWORK_INTERFACE "net.connman.iwd.KnownNetwork" -#define NM_IWD_SIGNAL_AGENT_INTERFACE "net.connman.iwd.SignalLevelAgent" -#define NM_IWD_AP_INTERFACE "net.connman.iwd.AccessPoint" -#define NM_IWD_ADHOC_INTERFACE "net.connman.iwd.AdHoc" -#define NM_IWD_STATION_INTERFACE "net.connman.iwd.Station" - -#define NM_TYPE_IWD_MANAGER (nm_iwd_manager_get_type ()) -#define NM_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IWD_MANAGER, NMIwdManager)) -#define NM_IWD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IWD_MANAGER, NMIwdManagerClass)) -#define NM_IS_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IWD_MANAGER)) -#define NM_IS_IWD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IWD_MANAGER)) -#define NM_IWD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IWD_MANAGER, NMIwdManagerClass)) - -typedef struct _NMIwdManager NMIwdManager; +#define NM_IWD_BUS_TYPE G_BUS_TYPE_SYSTEM +#define NM_IWD_SERVICE "net.connman.iwd" + +#define NM_IWD_AGENT_MANAGER_INTERFACE "net.connman.iwd.AgentManager" +#define NM_IWD_WIPHY_INTERFACE "net.connman.iwd.Adapter" +#define NM_IWD_DEVICE_INTERFACE "net.connman.iwd.Device" +#define NM_IWD_NETWORK_INTERFACE "net.connman.iwd.Network" +#define NM_IWD_AGENT_INTERFACE "net.connman.iwd.Agent" +#define NM_IWD_WSC_INTERFACE "net.connman.iwd.WiFiSimpleConfiguration" +#define NM_IWD_KNOWN_NETWORK_INTERFACE "net.connman.iwd.KnownNetwork" +#define NM_IWD_SIGNAL_AGENT_INTERFACE "net.connman.iwd.SignalLevelAgent" +#define NM_IWD_AP_INTERFACE "net.connman.iwd.AccessPoint" +#define NM_IWD_ADHOC_INTERFACE "net.connman.iwd.AdHoc" +#define NM_IWD_STATION_INTERFACE "net.connman.iwd.Station" + +#define NM_TYPE_IWD_MANAGER (nm_iwd_manager_get_type()) +#define NM_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IWD_MANAGER, NMIwdManager)) +#define NM_IWD_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_IWD_MANAGER, NMIwdManagerClass)) +#define NM_IS_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_IWD_MANAGER)) +#define NM_IS_IWD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_IWD_MANAGER)) +#define NM_IWD_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_IWD_MANAGER, NMIwdManagerClass)) + +typedef struct _NMIwdManager NMIwdManager; typedef struct _NMIwdManagerClass NMIwdManagerClass; -GType nm_iwd_manager_get_type (void); +GType nm_iwd_manager_get_type(void); -NMIwdManager *nm_iwd_manager_get (void); +NMIwdManager *nm_iwd_manager_get(void); -gboolean nm_iwd_manager_is_known_network (NMIwdManager *self, const char *name, - NMIwdNetworkSecurity security); +gboolean nm_iwd_manager_is_known_network(NMIwdManager * self, + const char * name, + NMIwdNetworkSecurity security); -GDBusProxy *nm_iwd_manager_get_dbus_interface (NMIwdManager *self, const char *path, - const char *name); +GDBusProxy * +nm_iwd_manager_get_dbus_interface(NMIwdManager *self, const char *path, const char *name); #endif /* __NETWORKMANAGER_IWD_MANAGER_H__ */ diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index b0aaf3e9..fe26421d 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2004 - 2017 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -26,1030 +26,1026 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMWifiAP, - PROP_FLAGS, - PROP_WPA_FLAGS, - PROP_RSN_FLAGS, - PROP_SSID, - PROP_FREQUENCY, - PROP_HW_ADDRESS, - PROP_MODE, - PROP_MAX_BITRATE, - PROP_STRENGTH, - PROP_LAST_SEEN, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMWifiAP, + PROP_FLAGS, + PROP_WPA_FLAGS, + PROP_RSN_FLAGS, + PROP_SSID, + PROP_FREQUENCY, + PROP_HW_ADDRESS, + PROP_MODE, + PROP_MAX_BITRATE, + PROP_STRENGTH, + PROP_LAST_SEEN, ); struct _NMWifiAPPrivate { - /* Scanned or cached values */ - GBytes * ssid; - char * address; - NM80211Mode mode; - guint8 strength; - guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ - guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ - - gint64 last_seen_msec; /* Timestamp when the AP was seen lastly (in nm_utils_get_monotonic_timestamp_*() scale). - * Note that this value might be negative! */ - - NM80211ApFlags flags; /* General flags */ - NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */ - NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */ - - bool metered:1; - - /* Non-scanned attributes */ - bool fake:1; /* Whether or not the AP is from a scan */ - bool hotspot:1; /* Whether the AP is a local device's hotspot network */ + /* Scanned or cached values */ + GBytes * ssid; + char * address; + NM80211Mode mode; + guint8 strength; + guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ + guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ + + gint64 + last_seen_msec; /* Timestamp when the AP was seen lastly (in nm_utils_get_monotonic_timestamp_*() scale). + * Note that this value might be negative! */ + + NM80211ApFlags flags; /* General flags */ + NM80211ApSecurityFlags wpa_flags; /* WPA-related flags */ + NM80211ApSecurityFlags rsn_flags; /* RSN (WPA2) -related flags */ + + bool metered : 1; + + /* Non-scanned attributes */ + bool fake : 1; /* Whether or not the AP is from a scan */ + bool hotspot : 1; /* Whether the AP is a local device's hotspot network */ }; typedef struct _NMWifiAPPrivate NMWifiAPPrivate; struct _NMWifiAPClass { - NMDBusObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMWifiAP, nm_wifi_ap, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE(NMWifiAP, nm_wifi_ap, NM_TYPE_DBUS_OBJECT) #define NM_WIFI_AP_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMWifiAP, NM_IS_WIFI_AP) /*****************************************************************************/ GBytes * -nm_wifi_ap_get_ssid (const NMWifiAP *ap) +nm_wifi_ap_get_ssid(const NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), NULL); - return NM_WIFI_AP_GET_PRIVATE (ap)->ssid; + return NM_WIFI_AP_GET_PRIVATE(ap)->ssid; } gboolean -nm_wifi_ap_set_ssid_arr (NMWifiAP *ap, - const guint8 *ssid, - gsize ssid_len) +nm_wifi_ap_set_ssid_arr(NMWifiAP *ap, const guint8 *ssid, gsize ssid_len) { - NMWifiAPPrivate *priv; + NMWifiAPPrivate *priv; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - if (ssid_len > 32) - g_return_val_if_reached (FALSE); + if (ssid_len > 32) + g_return_val_if_reached(FALSE); - priv = NM_WIFI_AP_GET_PRIVATE (ap); + priv = NM_WIFI_AP_GET_PRIVATE(ap); - if (nm_utils_gbytes_equal_mem (priv->ssid, ssid, ssid_len)) - return FALSE; + if (nm_utils_gbytes_equal_mem(priv->ssid, ssid, ssid_len)) + return FALSE; - nm_clear_pointer (&priv->ssid, g_bytes_unref); - if (ssid_len > 0) - priv->ssid = g_bytes_new (ssid, ssid_len); + nm_clear_pointer(&priv->ssid, g_bytes_unref); + if (ssid_len > 0) + priv->ssid = g_bytes_new(ssid, ssid_len); - _notify (ap, PROP_SSID); - return TRUE; + _notify(ap, PROP_SSID); + return TRUE; } gboolean -nm_wifi_ap_set_ssid (NMWifiAP *ap, GBytes *ssid) +nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid) { - NMWifiAPPrivate *priv; - gsize l; + NMWifiAPPrivate *priv; + gsize l; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - if (ssid) { - l = g_bytes_get_size (ssid); - if (l == 0 || l > 32) - g_return_val_if_reached (FALSE); - } + if (ssid) { + l = g_bytes_get_size(ssid); + if (l == 0 || l > 32) + g_return_val_if_reached(FALSE); + } - priv = NM_WIFI_AP_GET_PRIVATE (ap); + priv = NM_WIFI_AP_GET_PRIVATE(ap); - if (ssid == priv->ssid) - return FALSE; - if ( ssid - && priv->ssid - && g_bytes_equal (ssid, priv->ssid)) - return FALSE; + if (ssid == priv->ssid) + return FALSE; + if (ssid && priv->ssid && g_bytes_equal(ssid, priv->ssid)) + return FALSE; - nm_clear_pointer (&priv->ssid, g_bytes_unref); - if (ssid) - priv->ssid = g_bytes_ref (ssid); + nm_clear_pointer(&priv->ssid, g_bytes_unref); + if (ssid) + priv->ssid = g_bytes_ref(ssid); - _notify (ap, PROP_SSID); - return TRUE; + _notify(ap, PROP_SSID); + return TRUE; } static gboolean -nm_wifi_ap_set_flags (NMWifiAP *ap, NM80211ApFlags flags) +nm_wifi_ap_set_flags(NMWifiAP *ap, NM80211ApFlags flags) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->flags != flags) { - priv->flags = flags; - _notify (ap, PROP_FLAGS); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->flags != flags) { + priv->flags = flags; + _notify(ap, PROP_FLAGS); + return TRUE; + } + return FALSE; } static gboolean -nm_wifi_ap_set_wpa_flags (NMWifiAP *ap, NM80211ApSecurityFlags flags) +nm_wifi_ap_set_wpa_flags(NMWifiAP *ap, NM80211ApSecurityFlags flags) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->wpa_flags != flags) { - priv->wpa_flags = flags; - _notify (ap, PROP_WPA_FLAGS); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->wpa_flags != flags) { + priv->wpa_flags = flags; + _notify(ap, PROP_WPA_FLAGS); + return TRUE; + } + return FALSE; } static gboolean -nm_wifi_ap_set_rsn_flags (NMWifiAP *ap, NM80211ApSecurityFlags flags) +nm_wifi_ap_set_rsn_flags(NMWifiAP *ap, NM80211ApSecurityFlags flags) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->rsn_flags != flags) { - priv->rsn_flags = flags; - _notify (ap, PROP_RSN_FLAGS); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->rsn_flags != flags) { + priv->rsn_flags = flags; + _notify(ap, PROP_RSN_FLAGS); + return TRUE; + } + return FALSE; } const char * -nm_wifi_ap_get_address (const NMWifiAP *ap) +nm_wifi_ap_get_address(const NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), NULL); - return NM_WIFI_AP_GET_PRIVATE (ap)->address; + return NM_WIFI_AP_GET_PRIVATE(ap)->address; } static gboolean -nm_wifi_ap_set_address_bin (NMWifiAP *ap, const guint8 addr[static 6 /* ETH_ALEN */]) +nm_wifi_ap_set_address_bin(NMWifiAP *ap, const guint8 addr[static 6 /* ETH_ALEN */]) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if ( !priv->address - || !nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->address, -1)) { - g_free (priv->address); - priv->address = nm_utils_hwaddr_ntoa (addr, ETH_ALEN); - _notify (ap, PROP_HW_ADDRESS); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (!priv->address || !nm_utils_hwaddr_matches(addr, ETH_ALEN, priv->address, -1)) { + g_free(priv->address); + priv->address = nm_utils_hwaddr_ntoa(addr, ETH_ALEN); + _notify(ap, PROP_HW_ADDRESS); + return TRUE; + } + return FALSE; } gboolean -nm_wifi_ap_set_address (NMWifiAP *ap, const char *addr) +nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr) { - guint8 addr_buf[ETH_ALEN]; + guint8 addr_buf[ETH_ALEN]; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); - if ( !addr - || !nm_utils_hwaddr_aton (addr, addr_buf, sizeof (addr_buf))) - g_return_val_if_reached (FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); + if (!addr || !nm_utils_hwaddr_aton(addr, addr_buf, sizeof(addr_buf))) + g_return_val_if_reached(FALSE); - return nm_wifi_ap_set_address_bin (ap, addr_buf); + return nm_wifi_ap_set_address_bin(ap, addr_buf); } NM80211Mode -nm_wifi_ap_get_mode (NMWifiAP *ap) +nm_wifi_ap_get_mode(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), NM_802_11_MODE_UNKNOWN); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), NM_802_11_MODE_UNKNOWN); - return NM_WIFI_AP_GET_PRIVATE (ap)->mode; + return NM_WIFI_AP_GET_PRIVATE(ap)->mode; } static gboolean -nm_wifi_ap_set_mode (NMWifiAP *ap, NM80211Mode mode) +nm_wifi_ap_set_mode(NMWifiAP *ap, NM80211Mode mode) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - nm_assert (NM_IN_SET (mode, NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_ADHOC, - NM_802_11_MODE_INFRA, - NM_802_11_MODE_MESH)); - - if (priv->mode != mode) { - priv->mode = mode; - _notify (ap, PROP_MODE); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + nm_assert(NM_IN_SET(mode, + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_ADHOC, + NM_802_11_MODE_INFRA, + NM_802_11_MODE_MESH)); + + if (priv->mode != mode) { + priv->mode = mode; + _notify(ap, PROP_MODE); + return TRUE; + } + return FALSE; } gboolean -nm_wifi_ap_is_hotspot (NMWifiAP *ap) +nm_wifi_ap_is_hotspot(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - return NM_WIFI_AP_GET_PRIVATE (ap)->hotspot; + return NM_WIFI_AP_GET_PRIVATE(ap)->hotspot; } gint8 -nm_wifi_ap_get_strength (NMWifiAP *ap) +nm_wifi_ap_get_strength(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), 0); - return NM_WIFI_AP_GET_PRIVATE (ap)->strength; + return NM_WIFI_AP_GET_PRIVATE(ap)->strength; } gboolean -nm_wifi_ap_set_strength (NMWifiAP *ap, gint8 strength) +nm_wifi_ap_set_strength(NMWifiAP *ap, gint8 strength) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->strength != strength) { - priv->strength = strength; - _notify (ap, PROP_STRENGTH); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->strength != strength) { + priv->strength = strength; + _notify(ap, PROP_STRENGTH); + return TRUE; + } + return FALSE; } guint32 -nm_wifi_ap_get_freq (NMWifiAP *ap) +nm_wifi_ap_get_freq(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), 0); - return NM_WIFI_AP_GET_PRIVATE (ap)->freq; + return NM_WIFI_AP_GET_PRIVATE(ap)->freq; } gboolean -nm_wifi_ap_set_freq (NMWifiAP *ap, - guint32 freq) +nm_wifi_ap_set_freq(NMWifiAP *ap, guint32 freq) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->freq != freq) { - priv->freq = freq; - _notify (ap, PROP_FREQUENCY); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->freq != freq) { + priv->freq = freq; + _notify(ap, PROP_FREQUENCY); + return TRUE; + } + return FALSE; } guint32 -nm_wifi_ap_get_max_bitrate (NMWifiAP *ap) +nm_wifi_ap_get_max_bitrate(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0); - g_return_val_if_fail (nm_dbus_object_is_exported (NM_DBUS_OBJECT (ap)), 0); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), 0); + g_return_val_if_fail(nm_dbus_object_is_exported(NM_DBUS_OBJECT(ap)), 0); - return NM_WIFI_AP_GET_PRIVATE (ap)->max_bitrate; + return NM_WIFI_AP_GET_PRIVATE(ap)->max_bitrate; } gboolean -nm_wifi_ap_set_max_bitrate (NMWifiAP *ap, guint32 bitrate) +nm_wifi_ap_set_max_bitrate(NMWifiAP *ap, guint32 bitrate) { - NMWifiAPPrivate *priv; + NMWifiAPPrivate *priv; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - priv = NM_WIFI_AP_GET_PRIVATE (ap); + priv = NM_WIFI_AP_GET_PRIVATE(ap); - if (priv->max_bitrate != bitrate) { - priv->max_bitrate = bitrate; - _notify (ap, PROP_MAX_BITRATE); - return TRUE; - } - return FALSE; + if (priv->max_bitrate != bitrate) { + priv->max_bitrate = bitrate; + _notify(ap, PROP_MAX_BITRATE); + return TRUE; + } + return FALSE; } gboolean -nm_wifi_ap_get_fake (const NMWifiAP *ap) +nm_wifi_ap_get_fake(const NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - return NM_WIFI_AP_GET_PRIVATE (ap)->fake; + return NM_WIFI_AP_GET_PRIVATE(ap)->fake; } gboolean -nm_wifi_ap_set_fake (NMWifiAP *ap, gboolean fake) +nm_wifi_ap_set_fake(NMWifiAP *ap, gboolean fake) { - NMWifiAPPrivate *priv; + NMWifiAPPrivate *priv; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - priv = NM_WIFI_AP_GET_PRIVATE (ap); + priv = NM_WIFI_AP_GET_PRIVATE(ap); - if (priv->fake != !!fake) { - priv->fake = fake; - return TRUE; - } - return FALSE; + if (priv->fake != !!fake) { + priv->fake = fake; + return TRUE; + } + return FALSE; } NM80211ApFlags -nm_wifi_ap_get_flags (const NMWifiAP *ap) +nm_wifi_ap_get_flags(const NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), NM_802_11_AP_FLAGS_NONE); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), NM_802_11_AP_FLAGS_NONE); - return NM_WIFI_AP_GET_PRIVATE (ap)->flags; + return NM_WIFI_AP_GET_PRIVATE(ap)->flags; } static gboolean -nm_wifi_ap_set_last_seen (NMWifiAP *ap, gint32 last_seen_msec) +nm_wifi_ap_set_last_seen(NMWifiAP *ap, gint32 last_seen_msec) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (priv->last_seen_msec != last_seen_msec) { - priv->last_seen_msec = last_seen_msec; - _notify (ap, PROP_LAST_SEEN); - return TRUE; - } - return FALSE; + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); + + if (priv->last_seen_msec != last_seen_msec) { + priv->last_seen_msec = last_seen_msec; + _notify(ap, PROP_LAST_SEEN); + return TRUE; + } + return FALSE; } gboolean -nm_wifi_ap_get_metered (const NMWifiAP *self) +nm_wifi_ap_get_metered(const NMWifiAP *self) { - return NM_WIFI_AP_GET_PRIVATE (self)->metered; + return NM_WIFI_AP_GET_PRIVATE(self)->metered; } /*****************************************************************************/ gboolean -nm_wifi_ap_update_from_properties (NMWifiAP *ap, - const NMSupplicantBssInfo *bss_info) +nm_wifi_ap_update_from_properties(NMWifiAP *ap, const NMSupplicantBssInfo *bss_info) { - NMWifiAPPrivate *priv; - gboolean changed = FALSE; + NMWifiAPPrivate *priv; + gboolean changed = FALSE; - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); - g_return_val_if_fail (bss_info, FALSE); - nm_assert (NM_IS_REF_STRING (bss_info->bss_path)); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); + g_return_val_if_fail(bss_info, FALSE); + nm_assert(NM_IS_REF_STRING(bss_info->bss_path)); - priv = NM_WIFI_AP_GET_PRIVATE (ap); + priv = NM_WIFI_AP_GET_PRIVATE(ap); - nm_assert ( !ap->_supplicant_path - || ap->_supplicant_path == bss_info->bss_path); + nm_assert(!ap->_supplicant_path || ap->_supplicant_path == bss_info->bss_path); - g_object_freeze_notify (G_OBJECT (ap)); + g_object_freeze_notify(G_OBJECT(ap)); - if (!ap->_supplicant_path) { - ap->_supplicant_path = nm_ref_string_ref (bss_info->bss_path); - changed = TRUE; - } + if (!ap->_supplicant_path) { + ap->_supplicant_path = nm_ref_string_ref(bss_info->bss_path); + changed = TRUE; + } - changed |= nm_wifi_ap_set_flags (ap, bss_info->ap_flags); - changed |= nm_wifi_ap_set_mode (ap, bss_info->mode); - changed |= nm_wifi_ap_set_strength (ap, bss_info->signal_percent); - changed |= nm_wifi_ap_set_freq (ap, bss_info->frequency); - changed |= nm_wifi_ap_set_ssid (ap, bss_info->ssid); + changed |= nm_wifi_ap_set_flags(ap, bss_info->ap_flags); + changed |= nm_wifi_ap_set_mode(ap, bss_info->mode); + changed |= nm_wifi_ap_set_strength(ap, bss_info->signal_percent); + changed |= nm_wifi_ap_set_freq(ap, bss_info->frequency); + changed |= nm_wifi_ap_set_ssid(ap, bss_info->ssid); - if (bss_info->bssid_valid) - changed |= nm_wifi_ap_set_address_bin (ap, bss_info->bssid); - else { - /* we don't actually clear the value. */ - } + if (bss_info->bssid_valid) + changed |= nm_wifi_ap_set_address_bin(ap, bss_info->bssid); + else { + /* we don't actually clear the value. */ + } - changed |= nm_wifi_ap_set_max_bitrate (ap, bss_info->max_rate); + changed |= nm_wifi_ap_set_max_bitrate(ap, bss_info->max_rate); - if (priv->metered != bss_info->metered) { - priv->metered = bss_info->metered; - changed = TRUE; - } + if (priv->metered != bss_info->metered) { + priv->metered = bss_info->metered; + changed = TRUE; + } - changed |= nm_wifi_ap_set_wpa_flags (ap, bss_info->wpa_flags); - changed |= nm_wifi_ap_set_rsn_flags (ap, bss_info->rsn_flags); + changed |= nm_wifi_ap_set_wpa_flags(ap, bss_info->wpa_flags); + changed |= nm_wifi_ap_set_rsn_flags(ap, bss_info->rsn_flags); - changed |= nm_wifi_ap_set_last_seen (ap, bss_info->last_seen_msec); + changed |= nm_wifi_ap_set_last_seen(ap, bss_info->last_seen_msec); - changed |= nm_wifi_ap_set_fake (ap, FALSE); + changed |= nm_wifi_ap_set_fake(ap, FALSE); - g_object_thaw_notify (G_OBJECT (ap)); + g_object_thaw_notify(G_OBJECT(ap)); - return changed; + return changed; } static gboolean -has_proto (NMSettingWirelessSecurity *sec, const char *proto) +has_proto(NMSettingWirelessSecurity *sec, const char *proto) { - guint32 num_protos = nm_setting_wireless_security_get_num_protos (sec); - guint32 i; + guint32 num_protos = nm_setting_wireless_security_get_num_protos(sec); + guint32 i; - if (num_protos == 0) - return TRUE; /* interpret no protos as "all" */ + if (num_protos == 0) + return TRUE; /* interpret no protos as "all" */ - for (i = 0; i < num_protos; i++) { - if (!strcmp (nm_setting_wireless_security_get_proto (sec, i), proto)) - return TRUE; - } - return FALSE; + for (i = 0; i < num_protos; i++) { + if (!strcmp(nm_setting_wireless_security_get_proto(sec, i), proto)) + return TRUE; + } + return FALSE; } static void -add_pair_ciphers (NMWifiAP *ap, NMSettingWirelessSecurity *sec) +add_pair_ciphers(NMWifiAP *ap, NMSettingWirelessSecurity *sec) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - guint32 num = nm_setting_wireless_security_get_num_pairwise (sec); - NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE; - guint32 i; - - /* If no ciphers are specified, that means "all" WPA ciphers */ - if (num == 0) { - flags |= NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP; - } else { - for (i = 0; i < num; i++) { - const char *cipher = nm_setting_wireless_security_get_pairwise (sec, i); - - if (!strcmp (cipher, "tkip")) - flags |= NM_802_11_AP_SEC_PAIR_TKIP; - else if (!strcmp (cipher, "ccmp")) - flags |= NM_802_11_AP_SEC_PAIR_CCMP; - } - } - - if (has_proto (sec, PROTO_WPA)) - nm_wifi_ap_set_wpa_flags (ap, priv->wpa_flags | flags); - if (has_proto (sec, PROTO_RSN)) - nm_wifi_ap_set_rsn_flags (ap, priv->rsn_flags | flags); + NMWifiAPPrivate * priv = NM_WIFI_AP_GET_PRIVATE(ap); + guint32 num = nm_setting_wireless_security_get_num_pairwise(sec); + NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE; + guint32 i; + + /* If no ciphers are specified, that means "all" WPA ciphers */ + if (num == 0) { + flags |= NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP; + } else { + for (i = 0; i < num; i++) { + const char *cipher = nm_setting_wireless_security_get_pairwise(sec, i); + + if (!strcmp(cipher, "tkip")) + flags |= NM_802_11_AP_SEC_PAIR_TKIP; + else if (!strcmp(cipher, "ccmp")) + flags |= NM_802_11_AP_SEC_PAIR_CCMP; + } + } + + if (has_proto(sec, PROTO_WPA)) + nm_wifi_ap_set_wpa_flags(ap, priv->wpa_flags | flags); + if (has_proto(sec, PROTO_RSN)) + nm_wifi_ap_set_rsn_flags(ap, priv->rsn_flags | flags); } static void -add_group_ciphers (NMWifiAP *ap, NMSettingWirelessSecurity *sec) +add_group_ciphers(NMWifiAP *ap, NMSettingWirelessSecurity *sec) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (ap); - guint32 num = nm_setting_wireless_security_get_num_groups (sec); - NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE; - guint32 i; - - /* If no ciphers are specified, that means "all" WPA ciphers */ - if (num == 0) { - flags |= NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP; - } else { - for (i = 0; i < num; i++) { - const char *cipher = nm_setting_wireless_security_get_group (sec, i); - - if (!strcmp (cipher, "wep40")) - flags |= NM_802_11_AP_SEC_GROUP_WEP40; - else if (!strcmp (cipher, "wep104")) - flags |= NM_802_11_AP_SEC_GROUP_WEP104; - else if (!strcmp (cipher, "tkip")) - flags |= NM_802_11_AP_SEC_GROUP_TKIP; - else if (!strcmp (cipher, "ccmp")) - flags |= NM_802_11_AP_SEC_GROUP_CCMP; - } - } - - if (has_proto (sec, PROTO_WPA)) - nm_wifi_ap_set_wpa_flags (ap, priv->wpa_flags | flags); - if (has_proto (sec, PROTO_RSN)) - nm_wifi_ap_set_rsn_flags (ap, priv->rsn_flags | flags); + NMWifiAPPrivate * priv = NM_WIFI_AP_GET_PRIVATE(ap); + guint32 num = nm_setting_wireless_security_get_num_groups(sec); + NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE; + guint32 i; + + /* If no ciphers are specified, that means "all" WPA ciphers */ + if (num == 0) { + flags |= NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP; + } else { + for (i = 0; i < num; i++) { + const char *cipher = nm_setting_wireless_security_get_group(sec, i); + + if (!strcmp(cipher, "wep40")) + flags |= NM_802_11_AP_SEC_GROUP_WEP40; + else if (!strcmp(cipher, "wep104")) + flags |= NM_802_11_AP_SEC_GROUP_WEP104; + else if (!strcmp(cipher, "tkip")) + flags |= NM_802_11_AP_SEC_GROUP_TKIP; + else if (!strcmp(cipher, "ccmp")) + flags |= NM_802_11_AP_SEC_GROUP_CCMP; + } + } + + if (has_proto(sec, PROTO_WPA)) + nm_wifi_ap_set_wpa_flags(ap, priv->wpa_flags | flags); + if (has_proto(sec, PROTO_RSN)) + nm_wifi_ap_set_rsn_flags(ap, priv->rsn_flags | flags); } const char * -nm_wifi_ap_to_string (const NMWifiAP *self, - char *str_buf, - gulong buf_len, - gint64 now_msec) +nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64 now_msec) { - const NMWifiAPPrivate *priv; - const char *supplicant_id = "-"; - const char *export_path; - guint32 chan; - gs_free char *ssid_to_free = NULL; - char str_buf_ts[100]; - - g_return_val_if_fail (NM_IS_WIFI_AP (self), NULL); - - priv = NM_WIFI_AP_GET_PRIVATE (self); - - chan = nm_utils_wifi_freq_to_channel (priv->freq); - if (self->_supplicant_path) - supplicant_id = strrchr (self->_supplicant_path->str, '/') ?: supplicant_id; - - export_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); - if (export_path) - export_path = strrchr (export_path, '/') ?: export_path; - else - export_path = "/"; - - nm_utils_get_monotonic_timestamp_msec_cached (&now_msec); - - g_snprintf (str_buf, buf_len, - "%17s %-35s [ %c %3u %3u%% %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", - priv->address ?: "(none)", - (ssid_to_free = _nm_utils_ssid_to_string (priv->ssid)), - (priv->mode == NM_802_11_MODE_ADHOC - ? '*' - : (priv->hotspot - ? '#' - : (priv->fake - ? 'f' - : (priv->mode == NM_802_11_MODE_MESH - ? 'm' - : 'a')))), - chan, - priv->strength, - priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', - priv->metered ? 'M' : '_', - priv->wpa_flags & 0xFFFF, - priv->rsn_flags & 0xFFFF, - priv->last_seen_msec != G_MININT64 - ? nm_sprintf_buf (str_buf_ts, - "%3u.%03us", - (guint) ((now_msec - priv->last_seen_msec) / 1000), - (guint) ((now_msec - priv->last_seen_msec) % 1000)) - : " ", - supplicant_id, - export_path); - return str_buf; + const NMWifiAPPrivate *priv; + const char * supplicant_id = "-"; + const char * export_path; + guint32 chan; + gs_free char * ssid_to_free = NULL; + char str_buf_ts[100]; + + g_return_val_if_fail(NM_IS_WIFI_AP(self), NULL); + + priv = NM_WIFI_AP_GET_PRIVATE(self); + + chan = nm_utils_wifi_freq_to_channel(priv->freq); + if (self->_supplicant_path) + supplicant_id = strrchr(self->_supplicant_path->str, '/') ?: supplicant_id; + + export_path = nm_dbus_object_get_path(NM_DBUS_OBJECT(self)); + if (export_path) + export_path = strrchr(export_path, '/') ?: export_path; + else + export_path = "/"; + + nm_utils_get_monotonic_timestamp_msec_cached(&now_msec); + + g_snprintf(str_buf, + buf_len, + "%17s %-35s [ %c %3u %3u%% %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", + priv->address ?: "(none)", + (ssid_to_free = _nm_utils_ssid_to_string(priv->ssid)), + (priv->mode == NM_802_11_MODE_ADHOC + ? '*' + : (priv->hotspot + ? '#' + : (priv->fake ? 'f' : (priv->mode == NM_802_11_MODE_MESH ? 'm' : 'a')))), + chan, + priv->strength, + priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', + priv->metered ? 'M' : '_', + priv->wpa_flags & 0xFFFF, + priv->rsn_flags & 0xFFFF, + priv->last_seen_msec != G_MININT64 + ? nm_sprintf_buf(str_buf_ts, + "%3u.%03us", + (guint)((now_msec - priv->last_seen_msec) / 1000), + (guint)((now_msec - priv->last_seen_msec) % 1000)) + : " ", + supplicant_id, + export_path); + return str_buf; } static guint -freq_to_band (guint32 freq) +freq_to_band(guint32 freq) { - if (freq >= 4915 && freq <= 5825) - return 5; - else if (freq >= 2412 && freq <= 2484) - return 2; - return 0; + if (freq >= 4915 && freq <= 5825) + return 5; + else if (freq >= 2412 && freq <= 2484) + return 2; + return 0; } gboolean -nm_wifi_ap_check_compatible (NMWifiAP *self, - NMConnection *connection) +nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) { - NMWifiAPPrivate *priv; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wireless_sec; - GBytes *ssid; - const char *mode; - const char *band; - const char *bssid; - guint32 channel; - - g_return_val_if_fail (NM_IS_WIFI_AP (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - - priv = NM_WIFI_AP_GET_PRIVATE (self); - - s_wireless = nm_connection_get_setting_wireless (connection); - if (s_wireless == NULL) - return FALSE; - - ssid = nm_setting_wireless_get_ssid (s_wireless); - if (ssid != priv->ssid) { - if (!ssid || !priv->ssid) - return FALSE; - if (!g_bytes_equal (ssid, priv->ssid)) - return FALSE; - } - - bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid && (!priv->address || !nm_utils_hwaddr_matches (bssid, -1, priv->address, -1))) - return FALSE; - - mode = nm_setting_wireless_get_mode (s_wireless); - if (mode) { - if (!strcmp (mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA)) - return FALSE; - if (!strcmp (mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC)) - return FALSE; - if ( !strcmp (mode, "ap") - && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) - return FALSE; - if (!strcmp (mode, "mesh") && (priv->mode != NM_802_11_MODE_MESH)) - return FALSE; - } - - band = nm_setting_wireless_get_band (s_wireless); - if (band) { - guint ap_band = freq_to_band (priv->freq); - - if (!strcmp (band, "a") && ap_band != 5) - return FALSE; - else if (!strcmp (band, "bg") && ap_band != 2) - return FALSE; - } - - channel = nm_setting_wireless_get_channel (s_wireless); - if (channel) { - guint32 ap_chan = nm_utils_wifi_freq_to_channel (priv->freq); - - if (channel != ap_chan) - return FALSE; - } - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - - return nm_setting_wireless_ap_security_compatible (s_wireless, - s_wireless_sec, - priv->flags, - priv->wpa_flags, - priv->rsn_flags, - priv->mode); + NMWifiAPPrivate * priv; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wireless_sec; + GBytes * ssid; + const char * mode; + const char * band; + const char * bssid; + guint32 channel; + + g_return_val_if_fail(NM_IS_WIFI_AP(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); + + priv = NM_WIFI_AP_GET_PRIVATE(self); + + s_wireless = nm_connection_get_setting_wireless(connection); + if (s_wireless == NULL) + return FALSE; + + ssid = nm_setting_wireless_get_ssid(s_wireless); + if (ssid != priv->ssid) { + if (!ssid || !priv->ssid) + return FALSE; + if (!g_bytes_equal(ssid, priv->ssid)) + return FALSE; + } + + bssid = nm_setting_wireless_get_bssid(s_wireless); + if (bssid && (!priv->address || !nm_utils_hwaddr_matches(bssid, -1, priv->address, -1))) + return FALSE; + + mode = nm_setting_wireless_get_mode(s_wireless); + if (mode) { + if (!strcmp(mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA)) + return FALSE; + if (!strcmp(mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC)) + return FALSE; + if (!strcmp(mode, "ap") && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) + return FALSE; + if (!strcmp(mode, "mesh") && (priv->mode != NM_802_11_MODE_MESH)) + return FALSE; + } + + band = nm_setting_wireless_get_band(s_wireless); + if (band) { + guint ap_band = freq_to_band(priv->freq); + + if (!strcmp(band, "a") && ap_band != 5) + return FALSE; + else if (!strcmp(band, "bg") && ap_band != 2) + return FALSE; + } + + channel = nm_setting_wireless_get_channel(s_wireless); + if (channel) { + guint32 ap_chan = nm_utils_wifi_freq_to_channel(priv->freq); + + if (channel != ap_chan) + return FALSE; + } + + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + + return nm_setting_wireless_ap_security_compatible(s_wireless, + s_wireless_sec, + priv->flags, + priv->wpa_flags, + priv->rsn_flags, + priv->mode); } gboolean -nm_wifi_ap_complete_connection (NMWifiAP *self, - NMConnection *connection, - gboolean lock_bssid, - GError **error) +nm_wifi_ap_complete_connection(NMWifiAP * self, + NMConnection *connection, + gboolean lock_bssid, + GError ** error) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); - - g_return_val_if_fail (connection != NULL, FALSE); - - return nm_wifi_utils_complete_connection (priv->ssid, - priv->address, - priv->mode, - priv->freq, - priv->flags, - priv->wpa_flags, - priv->rsn_flags, - connection, - lock_bssid, - error); + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(self); + + g_return_val_if_fail(connection != NULL, FALSE); + + return nm_wifi_utils_complete_connection(priv->ssid, + priv->address, + priv->mode, + priv->freq, + priv->flags, + priv->wpa_flags, + priv->rsn_flags, + connection, + lock_bssid, + error); } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMWifiAP *self = NM_WIFI_AP (object); - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_FLAGS: - g_value_set_uint (value, priv->flags); - break; - case PROP_WPA_FLAGS: - g_value_set_uint (value, priv->wpa_flags); - break; - case PROP_RSN_FLAGS: - g_value_set_uint (value, priv->rsn_flags); - break; - case PROP_SSID: - g_value_take_variant (value, - nm_utils_gbytes_to_variant_ay (priv->ssid)); - break; - case PROP_FREQUENCY: - g_value_set_uint (value, priv->freq); - break; - case PROP_HW_ADDRESS: - g_value_set_string (value, priv->address); - break; - case PROP_MODE: - g_value_set_uint (value, priv->mode); - break; - case PROP_MAX_BITRATE: - g_value_set_uint (value, priv->max_bitrate); - break; - case PROP_STRENGTH: - g_value_set_uchar (value, priv->strength); - break; - case PROP_LAST_SEEN: - g_value_set_int (value, - priv->last_seen_msec != G_MININT64 - ? (int) NM_MAX (nm_utils_monotonic_timestamp_as_boottime (priv->last_seen_msec, NM_UTILS_NSEC_PER_MSEC) / 1000, 1) - : -1); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMWifiAP * self = NM_WIFI_AP(object); + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_uint(value, priv->flags); + break; + case PROP_WPA_FLAGS: + g_value_set_uint(value, priv->wpa_flags); + break; + case PROP_RSN_FLAGS: + g_value_set_uint(value, priv->rsn_flags); + break; + case PROP_SSID: + g_value_take_variant(value, nm_utils_gbytes_to_variant_ay(priv->ssid)); + break; + case PROP_FREQUENCY: + g_value_set_uint(value, priv->freq); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, priv->address); + break; + case PROP_MODE: + g_value_set_uint(value, priv->mode); + break; + case PROP_MAX_BITRATE: + g_value_set_uint(value, priv->max_bitrate); + break; + case PROP_STRENGTH: + g_value_set_uchar(value, priv->strength); + break; + case PROP_LAST_SEEN: + g_value_set_int(value, + priv->last_seen_msec != G_MININT64 ? (int) NM_MAX( + nm_utils_monotonic_timestamp_as_boottime(priv->last_seen_msec, + NM_UTILS_NSEC_PER_MSEC) + / 1000, + 1) + : -1); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_wifi_ap_init (NMWifiAP *self) +nm_wifi_ap_init(NMWifiAP *self) { - NMWifiAPPrivate *priv; + NMWifiAPPrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_WIFI_AP, NMWifiAPPrivate); + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_WIFI_AP, NMWifiAPPrivate); - self->_priv = priv; + self->_priv = priv; - c_list_init (&self->aps_lst); + c_list_init(&self->aps_lst); - priv->mode = NM_802_11_MODE_INFRA; - priv->flags = NM_802_11_AP_FLAGS_NONE; - priv->wpa_flags = NM_802_11_AP_SEC_NONE; - priv->rsn_flags = NM_802_11_AP_SEC_NONE; - priv->last_seen_msec = G_MININT64; + priv->mode = NM_802_11_MODE_INFRA; + priv->flags = NM_802_11_AP_FLAGS_NONE; + priv->wpa_flags = NM_802_11_AP_SEC_NONE; + priv->rsn_flags = NM_802_11_AP_SEC_NONE; + priv->last_seen_msec = G_MININT64; } NMWifiAP * -nm_wifi_ap_new_from_properties (const NMSupplicantBssInfo *bss_info) +nm_wifi_ap_new_from_properties(const NMSupplicantBssInfo *bss_info) { - NMWifiAP *ap; + NMWifiAP *ap; - ap = g_object_new (NM_TYPE_WIFI_AP, NULL); - nm_wifi_ap_update_from_properties (ap, bss_info); - return ap; + ap = g_object_new(NM_TYPE_WIFI_AP, NULL); + nm_wifi_ap_update_from_properties(ap, bss_info); + return ap; } NMWifiAP * -nm_wifi_ap_new_fake_from_connection (NMConnection *connection) +nm_wifi_ap_new_fake_from_connection(NMConnection *connection) { - NMWifiAP *ap; - NMWifiAPPrivate *priv; - NMSettingWireless *s_wireless; - NMSettingWirelessSecurity *s_wireless_sec; - const char *mode, *band, *key_mgmt; - guint32 channel; - NM80211ApSecurityFlags flags; - gboolean psk = FALSE, eap = FALSE, adhoc = FALSE; - - g_return_val_if_fail (connection != NULL, NULL); - - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_val_if_fail (s_wireless != NULL, NULL); - - ap = (NMWifiAP *) g_object_new (NM_TYPE_WIFI_AP, NULL); - priv = NM_WIFI_AP_GET_PRIVATE (ap); - priv->fake = TRUE; - - nm_wifi_ap_set_ssid (ap, - nm_setting_wireless_get_ssid (s_wireless)); - - // FIXME: bssid too? - - mode = nm_setting_wireless_get_mode (s_wireless); - if (mode) { - if (!strcmp (mode, "infrastructure")) - nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); - else if (!strcmp (mode, "adhoc")) { - nm_wifi_ap_set_mode (ap, NM_802_11_MODE_ADHOC); - adhoc = TRUE; - } else if (!strcmp (mode, "mesh")) - nm_wifi_ap_set_mode (ap, NM_802_11_MODE_MESH); - else if (!strcmp (mode, "ap")) { - nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); - NM_WIFI_AP_GET_PRIVATE (ap)->hotspot = TRUE; - } else - goto error; - } else { - nm_wifi_ap_set_mode (ap, NM_802_11_MODE_INFRA); - } - - band = nm_setting_wireless_get_band (s_wireless); - channel = nm_setting_wireless_get_channel (s_wireless); - - if (band && channel) { - guint32 freq = nm_utils_wifi_channel_to_freq (channel, band); - - if (freq == 0) - goto error; - - nm_wifi_ap_set_freq (ap, freq); - } - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - /* Assume presence of a security setting means the AP is encrypted */ - if (!s_wireless_sec) - goto done; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); - - /* Everything below here uses encryption */ - nm_wifi_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_PRIVACY); - - /* Static & Dynamic WEP */ - if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x")) - goto done; - - psk = !strcmp (key_mgmt, "wpa-psk"); - eap = !strcmp (key_mgmt, "wpa-eap"); - if (!adhoc && (psk || eap)) { - if (has_proto (s_wireless_sec, PROTO_WPA)) { - flags = priv->wpa_flags | (eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK); - nm_wifi_ap_set_wpa_flags (ap, flags); - } - if (has_proto (s_wireless_sec, PROTO_RSN)) { - flags = priv->rsn_flags | (eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK); - nm_wifi_ap_set_rsn_flags (ap, flags); - } - - add_pair_ciphers (ap, s_wireless_sec); - add_group_ciphers (ap, s_wireless_sec); - } else if (adhoc && psk) { - /* Ad-Hoc has special requirements: proto=RSN, pairwise=CCMP and - * group=CCMP. - */ - flags = priv->wpa_flags | NM_802_11_AP_SEC_KEY_MGMT_PSK; - - /* Clear ciphers; only CCMP is supported */ - flags &= ~( NM_802_11_AP_SEC_PAIR_WEP40 - | NM_802_11_AP_SEC_PAIR_WEP104 - | NM_802_11_AP_SEC_PAIR_TKIP - | NM_802_11_AP_SEC_GROUP_WEP40 - | NM_802_11_AP_SEC_GROUP_WEP104 - | NM_802_11_AP_SEC_GROUP_TKIP); - - flags |= NM_802_11_AP_SEC_PAIR_CCMP; - flags |= NM_802_11_AP_SEC_GROUP_CCMP; - nm_wifi_ap_set_rsn_flags (ap, flags); - - /* Don't use Ad-Hoc WPA (WPA-none) anymore */ - nm_wifi_ap_set_wpa_flags (ap, NM_802_11_AP_SEC_NONE); - } + NMWifiAP * ap; + NMWifiAPPrivate * priv; + NMSettingWireless * s_wireless; + NMSettingWirelessSecurity *s_wireless_sec; + const char * mode, *band, *key_mgmt; + guint32 channel; + NM80211ApSecurityFlags flags; + gboolean psk = FALSE, eap = FALSE, adhoc = FALSE; + + g_return_val_if_fail(connection != NULL, NULL); + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_val_if_fail(s_wireless != NULL, NULL); + + ap = (NMWifiAP *) g_object_new(NM_TYPE_WIFI_AP, NULL); + priv = NM_WIFI_AP_GET_PRIVATE(ap); + priv->fake = TRUE; + + nm_wifi_ap_set_ssid(ap, nm_setting_wireless_get_ssid(s_wireless)); + + // FIXME: bssid too? + + mode = nm_setting_wireless_get_mode(s_wireless); + if (mode) { + if (!strcmp(mode, "infrastructure")) + nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + else if (!strcmp(mode, "adhoc")) { + nm_wifi_ap_set_mode(ap, NM_802_11_MODE_ADHOC); + adhoc = TRUE; + } else if (!strcmp(mode, "mesh")) + nm_wifi_ap_set_mode(ap, NM_802_11_MODE_MESH); + else if (!strcmp(mode, "ap")) { + nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + NM_WIFI_AP_GET_PRIVATE(ap)->hotspot = TRUE; + } else + goto error; + } else { + nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + } + + band = nm_setting_wireless_get_band(s_wireless); + channel = nm_setting_wireless_get_channel(s_wireless); + + if (band && channel) { + guint32 freq = nm_utils_wifi_channel_to_freq(channel, band); + + if (freq == 0) + goto error; + + nm_wifi_ap_set_freq(ap, freq); + } + + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + /* Assume presence of a security setting means the AP is encrypted */ + if (!s_wireless_sec) + goto done; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wireless_sec); + + /* Everything below here uses encryption */ + nm_wifi_ap_set_flags(ap, priv->flags | NM_802_11_AP_FLAGS_PRIVACY); + + /* Static & Dynamic WEP */ + if (!strcmp(key_mgmt, "none") || !strcmp(key_mgmt, "ieee8021x")) + goto done; + + psk = !strcmp(key_mgmt, "wpa-psk"); + eap = !strcmp(key_mgmt, "wpa-eap"); + if (!adhoc && (psk || eap)) { + if (has_proto(s_wireless_sec, PROTO_WPA)) { + flags = priv->wpa_flags + | (eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK); + nm_wifi_ap_set_wpa_flags(ap, flags); + } + if (has_proto(s_wireless_sec, PROTO_RSN)) { + flags = priv->rsn_flags + | (eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK); + nm_wifi_ap_set_rsn_flags(ap, flags); + } + + add_pair_ciphers(ap, s_wireless_sec); + add_group_ciphers(ap, s_wireless_sec); + } else if (adhoc && psk) { + /* Ad-Hoc has special requirements: proto=RSN, pairwise=CCMP and + * group=CCMP. + */ + flags = priv->wpa_flags | NM_802_11_AP_SEC_KEY_MGMT_PSK; + + /* Clear ciphers; only CCMP is supported */ + flags &= ~(NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 + | NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_WEP40 + | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_GROUP_TKIP); + + flags |= NM_802_11_AP_SEC_PAIR_CCMP; + flags |= NM_802_11_AP_SEC_GROUP_CCMP; + nm_wifi_ap_set_rsn_flags(ap, flags); + + /* Don't use Ad-Hoc WPA (WPA-none) anymore */ + nm_wifi_ap_set_wpa_flags(ap, NM_802_11_AP_SEC_NONE); + } done: - return ap; + return ap; error: - g_object_unref (ap); - return NULL; + g_object_unref(ap); + return NULL; } static void -finalize (GObject *object) +finalize(GObject *object) { - NMWifiAP *self = NM_WIFI_AP (object); - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); + NMWifiAP * self = NM_WIFI_AP(object); + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(self); - nm_assert (!self->wifi_device); - nm_assert (c_list_is_empty (&self->aps_lst)); + nm_assert(!self->wifi_device); + nm_assert(c_list_is_empty(&self->aps_lst)); - nm_ref_string_unref (self->_supplicant_path); - if (priv->ssid) - g_bytes_unref (priv->ssid); - g_free (priv->address); + nm_ref_string_unref(self->_supplicant_path); + if (priv->ssid) + g_bytes_unref(priv->ssid); + g_free(priv->address); - G_OBJECT_CLASS (nm_wifi_ap_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_wifi_ap_parent_class)->finalize(object); } static const NMDBusInterfaceInfoExtended interface_info_access_point = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_ACCESS_POINT, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Flags", "u", NM_WIFI_AP_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ssid", "ay", NM_WIFI_AP_SSID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Frequency", "u", NM_WIFI_AP_FREQUENCY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_WIFI_AP_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_WIFI_AP_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("MaxBitrate", "u", NM_WIFI_AP_MAX_BITRATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Strength", "y", NM_WIFI_AP_STRENGTH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("LastSeen", "i", NM_WIFI_AP_LAST_SEEN), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_ACCESS_POINT, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Flags", "u", NM_WIFI_AP_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ssid", "ay", NM_WIFI_AP_SSID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Frequency", + "u", + NM_WIFI_AP_FREQUENCY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_WIFI_AP_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_WIFI_AP_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("MaxBitrate", + "u", + NM_WIFI_AP_MAX_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Strength", "y", NM_WIFI_AP_STRENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("LastSeen", + "i", + NM_WIFI_AP_LAST_SEEN), ), ), + .legacy_property_changed = TRUE, }; static void -nm_wifi_ap_class_init (NMWifiAPClass *ap_class) +nm_wifi_ap_class_init(NMWifiAPClass *ap_class) { -#define ALL_SEC_FLAGS \ - ( NM_802_11_AP_SEC_NONE \ - | NM_802_11_AP_SEC_PAIR_WEP40 \ - | NM_802_11_AP_SEC_PAIR_WEP104 \ - | NM_802_11_AP_SEC_PAIR_TKIP \ - | NM_802_11_AP_SEC_PAIR_CCMP \ - | NM_802_11_AP_SEC_GROUP_WEP40 \ - | NM_802_11_AP_SEC_GROUP_WEP104 \ - | NM_802_11_AP_SEC_GROUP_TKIP \ - | NM_802_11_AP_SEC_GROUP_CCMP \ - | NM_802_11_AP_SEC_KEY_MGMT_PSK \ - | NM_802_11_AP_SEC_KEY_MGMT_802_1X \ - | NM_802_11_AP_SEC_KEY_MGMT_SAE \ - | NM_802_11_AP_SEC_KEY_MGMT_OWE \ - | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM) - - GObjectClass *object_class = G_OBJECT_CLASS (ap_class); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (ap_class); - - g_type_class_add_private (object_class, sizeof (NMWifiAPPrivate)); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_ACCESS_POINT); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_access_point); - - object_class->get_property = get_property; - object_class->finalize = finalize; - - obj_properties[PROP_FLAGS] = - g_param_spec_uint (NM_WIFI_AP_FLAGS, "", "", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_FLAGS_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_WPA_FLAGS] = - g_param_spec_uint (NM_WIFI_AP_WPA_FLAGS, "", "", - NM_802_11_AP_SEC_NONE, - ALL_SEC_FLAGS, - NM_802_11_AP_SEC_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_RSN_FLAGS] = - g_param_spec_uint (NM_WIFI_AP_RSN_FLAGS, "", "", - NM_802_11_AP_SEC_NONE, - ALL_SEC_FLAGS, - NM_802_11_AP_SEC_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SSID] = - g_param_spec_variant (NM_WIFI_AP_SSID, "", "", - G_VARIANT_TYPE ("ay"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FREQUENCY] = - g_param_spec_uint (NM_WIFI_AP_FREQUENCY, "", "", - 0, 10000, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_WIFI_AP_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MODE] = - g_param_spec_uint (NM_WIFI_AP_MODE, "", "", - NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MAX_BITRATE] = - g_param_spec_uint (NM_WIFI_AP_MAX_BITRATE, "", "", - 0, G_MAXUINT16, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_STRENGTH] = - g_param_spec_uchar (NM_WIFI_AP_STRENGTH, "", "", - 0, G_MAXINT8, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LAST_SEEN] = - g_param_spec_int (NM_WIFI_AP_LAST_SEEN, "", "", - -1, G_MAXINT, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +#define ALL_SEC_FLAGS \ + (NM_802_11_AP_SEC_NONE | NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 \ + | NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_WEP40 \ + | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP \ + | NM_802_11_AP_SEC_KEY_MGMT_PSK | NM_802_11_AP_SEC_KEY_MGMT_802_1X \ + | NM_802_11_AP_SEC_KEY_MGMT_SAE | NM_802_11_AP_SEC_KEY_MGMT_OWE \ + | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM) + + GObjectClass * object_class = G_OBJECT_CLASS(ap_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(ap_class); + + g_type_class_add_private(object_class, sizeof(NMWifiAPPrivate)); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH_ACCESS_POINT); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_access_point); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_WIFI_AP_FLAGS, + "", + "", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_WPA_FLAGS] = g_param_spec_uint(NM_WIFI_AP_WPA_FLAGS, + "", + "", + NM_802_11_AP_SEC_NONE, + ALL_SEC_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_RSN_FLAGS] = g_param_spec_uint(NM_WIFI_AP_RSN_FLAGS, + "", + "", + NM_802_11_AP_SEC_NONE, + ALL_SEC_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SSID] = g_param_spec_variant(NM_WIFI_AP_SSID, + "", + "", + G_VARIANT_TYPE("ay"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_FREQUENCY] = g_param_spec_uint(NM_WIFI_AP_FREQUENCY, + "", + "", + 0, + 10000, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_WIFI_AP_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MODE] = g_param_spec_uint(NM_WIFI_AP_MODE, + "", + "", + NM_802_11_MODE_ADHOC, + NM_802_11_MODE_INFRA, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MAX_BITRATE] = g_param_spec_uint(NM_WIFI_AP_MAX_BITRATE, + "", + "", + 0, + G_MAXUINT16, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STRENGTH] = g_param_spec_uchar(NM_WIFI_AP_STRENGTH, + "", + "", + 0, + G_MAXINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LAST_SEEN] = g_param_spec_int(NM_WIFI_AP_LAST_SEEN, + "", + "", + -1, + G_MAXINT, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } /*****************************************************************************/ const char ** -nm_wifi_aps_get_paths (const CList *aps_lst_head, gboolean include_without_ssid) +nm_wifi_aps_get_paths(const CList *aps_lst_head, gboolean include_without_ssid) { - NMWifiAP *ap; - gsize i, n; - const char **list; - const char *path; - - n = c_list_length (aps_lst_head); - list = g_new (const char *, n + 1); - - i = 0; - if (n > 0) { - c_list_for_each_entry (ap, aps_lst_head, aps_lst) { - nm_assert (i < n); - if ( !include_without_ssid - && !nm_wifi_ap_get_ssid (ap)) - continue; - - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)); - nm_assert (path); - - list[i++] = path; - } - nm_assert (i <= n); - nm_assert (!include_without_ssid || i == n); - } - list[i] = NULL; - return list; + NMWifiAP * ap; + gsize i, n; + const char **list; + const char * path; + + n = c_list_length(aps_lst_head); + list = g_new(const char *, n + 1); + + i = 0; + if (n > 0) { + c_list_for_each_entry (ap, aps_lst_head, aps_lst) { + nm_assert(i < n); + if (!include_without_ssid && !nm_wifi_ap_get_ssid(ap)) + continue; + + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(ap)); + nm_assert(path); + + list[i++] = path; + } + nm_assert(i <= n); + nm_assert(!include_without_ssid || i == n); + } + list[i] = NULL; + return list; } NMWifiAP * -nm_wifi_aps_find_first_compatible (const CList *aps_lst_head, - NMConnection *connection) +nm_wifi_aps_find_first_compatible(const CList *aps_lst_head, NMConnection *connection) { - NMWifiAP *ap; + NMWifiAP *ap; - g_return_val_if_fail (connection, NULL); + g_return_val_if_fail(connection, NULL); - c_list_for_each_entry (ap, aps_lst_head, aps_lst) { - if (nm_wifi_ap_check_compatible (ap, connection)) - return ap; - } - return NULL; + c_list_for_each_entry (ap, aps_lst_head, aps_lst) { + if (nm_wifi_ap_check_compatible(ap, connection)) + return ap; + } + return NULL; } /*****************************************************************************/ NMWifiAP * -nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path) +nm_wifi_ap_lookup_for_device(NMDevice *device, const char *exported_path) { - NMWifiAP *ap; + NMWifiAP *ap; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); - ap = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (device)), - exported_path); - if ( !ap - || !NM_IS_WIFI_AP (ap) - || ap->wifi_device != device) - return NULL; + ap = nm_dbus_manager_lookup_object(nm_dbus_object_get_manager(NM_DBUS_OBJECT(device)), + exported_path); + if (!ap || !NM_IS_WIFI_AP(ap) || ap->wifi_device != device) + return NULL; - return ap; + return ap; } diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index 1bf4e604..4608c6ff 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2004 - 2017 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. @@ -11,97 +11,84 @@ #include "nm-dbus-interface.h" #include "nm-connection.h" -#define NM_TYPE_WIFI_AP (nm_wifi_ap_get_type ()) -#define NM_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_AP, NMWifiAP)) -#define NM_WIFI_AP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_AP, NMWifiAPClass)) -#define NM_IS_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_AP)) -#define NM_IS_WIFI_AP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_AP)) -#define NM_WIFI_AP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_AP, NMWifiAPClass)) - -#define NM_WIFI_AP_FLAGS "flags" -#define NM_WIFI_AP_WPA_FLAGS "wpa-flags" -#define NM_WIFI_AP_RSN_FLAGS "rsn-flags" -#define NM_WIFI_AP_SSID "ssid" -#define NM_WIFI_AP_FREQUENCY "frequency" -#define NM_WIFI_AP_HW_ADDRESS "hw-address" -#define NM_WIFI_AP_MODE "mode" -#define NM_WIFI_AP_MAX_BITRATE "max-bitrate" -#define NM_WIFI_AP_STRENGTH "strength" -#define NM_WIFI_AP_LAST_SEEN "last-seen" +#define NM_TYPE_WIFI_AP (nm_wifi_ap_get_type()) +#define NM_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_AP, NMWifiAP)) +#define NM_WIFI_AP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_AP, NMWifiAPClass)) +#define NM_IS_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_AP)) +#define NM_IS_WIFI_AP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_AP)) +#define NM_WIFI_AP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_AP, NMWifiAPClass)) + +#define NM_WIFI_AP_FLAGS "flags" +#define NM_WIFI_AP_WPA_FLAGS "wpa-flags" +#define NM_WIFI_AP_RSN_FLAGS "rsn-flags" +#define NM_WIFI_AP_SSID "ssid" +#define NM_WIFI_AP_FREQUENCY "frequency" +#define NM_WIFI_AP_HW_ADDRESS "hw-address" +#define NM_WIFI_AP_MODE "mode" +#define NM_WIFI_AP_MAX_BITRATE "max-bitrate" +#define NM_WIFI_AP_STRENGTH "strength" +#define NM_WIFI_AP_LAST_SEEN "last-seen" typedef struct { - NMDBusObject parent; - NMDevice *wifi_device; - CList aps_lst; - NMRefString *_supplicant_path; - struct _NMWifiAPPrivate *_priv; + NMDBusObject parent; + NMDevice * wifi_device; + CList aps_lst; + NMRefString * _supplicant_path; + struct _NMWifiAPPrivate *_priv; } NMWifiAP; struct _NMSupplicantBssInfo; typedef struct _NMWifiAPClass NMWifiAPClass; -GType nm_wifi_ap_get_type (void); +GType nm_wifi_ap_get_type(void); -NMWifiAP *nm_wifi_ap_new_from_properties (const struct _NMSupplicantBssInfo *bss_info); -NMWifiAP *nm_wifi_ap_new_fake_from_connection (NMConnection *connection); +NMWifiAP *nm_wifi_ap_new_from_properties(const struct _NMSupplicantBssInfo *bss_info); +NMWifiAP *nm_wifi_ap_new_fake_from_connection(NMConnection *connection); -gboolean nm_wifi_ap_update_from_properties (NMWifiAP *ap, - const struct _NMSupplicantBssInfo *bss_info); +gboolean nm_wifi_ap_update_from_properties(NMWifiAP * ap, + const struct _NMSupplicantBssInfo *bss_info); -gboolean nm_wifi_ap_check_compatible (NMWifiAP *self, - NMConnection *connection); +gboolean nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection); -gboolean nm_wifi_ap_complete_connection (NMWifiAP *self, - NMConnection *connection, - gboolean lock_bssid, - GError **error); +gboolean nm_wifi_ap_complete_connection(NMWifiAP * self, + NMConnection *connection, + gboolean lock_bssid, + GError ** error); static inline NMRefString * -nm_wifi_ap_get_supplicant_path (NMWifiAP *ap) +nm_wifi_ap_get_supplicant_path(NMWifiAP *ap) { - g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), NULL); - return ap->_supplicant_path; + return ap->_supplicant_path; } -GBytes *nm_wifi_ap_get_ssid (const NMWifiAP *ap); -gboolean nm_wifi_ap_set_ssid_arr (NMWifiAP *ap, - const guint8 *ssid, - gsize ssid_len); -gboolean nm_wifi_ap_set_ssid (NMWifiAP *ap, - GBytes *ssid); -const char * nm_wifi_ap_get_address (const NMWifiAP *ap); -gboolean nm_wifi_ap_set_address (NMWifiAP *ap, - const char *addr); -NM80211Mode nm_wifi_ap_get_mode (NMWifiAP *ap); -gboolean nm_wifi_ap_is_hotspot (NMWifiAP *ap); -gint8 nm_wifi_ap_get_strength (NMWifiAP *ap); -gboolean nm_wifi_ap_set_strength (NMWifiAP *ap, - gint8 strength); -guint32 nm_wifi_ap_get_freq (NMWifiAP *ap); -gboolean nm_wifi_ap_set_freq (NMWifiAP *ap, - guint32 freq); -guint32 nm_wifi_ap_get_max_bitrate (NMWifiAP *ap); -gboolean nm_wifi_ap_set_max_bitrate (NMWifiAP *ap, - guint32 bitrate); -gboolean nm_wifi_ap_get_fake (const NMWifiAP *ap); -gboolean nm_wifi_ap_set_fake (NMWifiAP *ap, - gboolean fake); -NM80211ApFlags nm_wifi_ap_get_flags (const NMWifiAP *self); -gboolean nm_wifi_ap_get_metered (const NMWifiAP *self); - -const char *nm_wifi_ap_to_string (const NMWifiAP *self, - char *str_buf, - gulong buf_len, - gint64 now_msec); - -const char **nm_wifi_aps_get_paths (const CList *aps_lst_head, - gboolean include_without_ssid); - -NMWifiAP *nm_wifi_aps_find_first_compatible (const CList *aps_lst_head, - NMConnection *connection); - -NMWifiAP *nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path); +GBytes * nm_wifi_ap_get_ssid(const NMWifiAP *ap); +gboolean nm_wifi_ap_set_ssid_arr(NMWifiAP *ap, const guint8 *ssid, gsize ssid_len); +gboolean nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid); +const char * nm_wifi_ap_get_address(const NMWifiAP *ap); +gboolean nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr); +NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); +gboolean nm_wifi_ap_is_hotspot(NMWifiAP *ap); +gint8 nm_wifi_ap_get_strength(NMWifiAP *ap); +gboolean nm_wifi_ap_set_strength(NMWifiAP *ap, gint8 strength); +guint32 nm_wifi_ap_get_freq(NMWifiAP *ap); +gboolean nm_wifi_ap_set_freq(NMWifiAP *ap, guint32 freq); +guint32 nm_wifi_ap_get_max_bitrate(NMWifiAP *ap); +gboolean nm_wifi_ap_set_max_bitrate(NMWifiAP *ap, guint32 bitrate); +gboolean nm_wifi_ap_get_fake(const NMWifiAP *ap); +gboolean nm_wifi_ap_set_fake(NMWifiAP *ap, gboolean fake); +NM80211ApFlags nm_wifi_ap_get_flags(const NMWifiAP *self); +gboolean nm_wifi_ap_get_metered(const NMWifiAP *self); + +const char * +nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64 now_msec); + +const char **nm_wifi_aps_get_paths(const CList *aps_lst_head, gboolean include_without_ssid); + +NMWifiAP *nm_wifi_aps_find_first_compatible(const CList *aps_lst_head, NMConnection *connection); + +NMWifiAP *nm_wifi_ap_lookup_for_device(NMDevice *device, const char *exported_path); #endif /* __NM_WIFI_AP_H__ */ diff --git a/src/devices/wifi/nm-wifi-common.c b/src/devices/wifi/nm-wifi-common.c index 087465b5..e2ef4186 100644 --- a/src/devices/wifi/nm-wifi-common.c +++ b/src/devices/wifi/nm-wifi-common.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -13,180 +13,164 @@ #include "nm-dbus-manager.h" #if WITH_IWD -#include "nm-device-iwd.h" + #include "nm-device-iwd.h" #endif /*****************************************************************************/ void -nm_device_wifi_emit_signal_access_point (NMDevice *device, - NMWifiAP *ap, - gboolean is_added /* or else is_removed */) +nm_device_wifi_emit_signal_access_point(NMDevice *device, + NMWifiAP *ap, + gboolean is_added /* or else is_removed */) { - nm_dbus_object_emit_signal (NM_DBUS_OBJECT (device), - &nm_interface_info_device_wireless, - is_added - ? &nm_signal_info_wireless_access_point_added - : &nm_signal_info_wireless_access_point_removed, - "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); + nm_dbus_object_emit_signal(NM_DBUS_OBJECT(device), + &nm_interface_info_device_wireless, + is_added ? &nm_signal_info_wireless_access_point_added + : &nm_signal_info_wireless_access_point_removed, + "(o)", + nm_dbus_object_get_path(NM_DBUS_OBJECT(ap))); } /*****************************************************************************/ static const CList * -_dispatch_get_aps (NMDevice *device) +_dispatch_get_aps(NMDevice *device) { #if WITH_IWD - if (NM_IS_DEVICE_IWD (device)) - return _nm_device_iwd_get_aps (NM_DEVICE_IWD (device)); + if (NM_IS_DEVICE_IWD(device)) + return _nm_device_iwd_get_aps(NM_DEVICE_IWD(device)); #endif - return _nm_device_wifi_get_aps (NM_DEVICE_WIFI (device)); + return _nm_device_wifi_get_aps(NM_DEVICE_WIFI(device)); } static void -_dispatch_request_scan (NMDevice *device, - GVariant *options, - GDBusMethodInvocation *invocation) +_dispatch_request_scan(NMDevice *device, GVariant *options, GDBusMethodInvocation *invocation) { #if WITH_IWD - if (NM_IS_DEVICE_IWD (device)) { - _nm_device_iwd_request_scan (NM_DEVICE_IWD (device), - options, - invocation); - return; - } + if (NM_IS_DEVICE_IWD(device)) { + _nm_device_iwd_request_scan(NM_DEVICE_IWD(device), options, invocation); + return; + } #endif - _nm_device_wifi_request_scan (NM_DEVICE_WIFI (device), - options, - invocation); + _nm_device_wifi_request_scan(NM_DEVICE_WIFI(device), options, invocation); } static void -impl_device_wifi_get_access_points (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_device_wifi_get_access_points(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - gs_free const char **list = NULL; - GVariant *v; - const CList *all_aps; + gs_free const char **list = NULL; + GVariant * v; + const CList * all_aps; - /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ - all_aps = _dispatch_get_aps (NM_DEVICE (obj)); - list = nm_wifi_aps_get_paths (all_aps, FALSE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (invocation, - g_variant_new_tuple (&v, 1)); + all_aps = _dispatch_get_aps(NM_DEVICE(obj)); + list = nm_wifi_aps_get_paths(all_aps, FALSE); + v = g_variant_new_objv(list, -1); + g_dbus_method_invocation_return_value(invocation, g_variant_new_tuple(&v, 1)); } static void -impl_device_wifi_get_all_access_points (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_device_wifi_get_all_access_points(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - gs_free const char **list = NULL; - GVariant *v; - const CList *all_aps; + gs_free const char **list = NULL; + GVariant * v; + const CList * all_aps; - /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ - all_aps = _dispatch_get_aps (NM_DEVICE (obj)); - list = nm_wifi_aps_get_paths (all_aps, TRUE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (invocation, - g_variant_new_tuple (&v, 1)); + all_aps = _dispatch_get_aps(NM_DEVICE(obj)); + list = nm_wifi_aps_get_paths(all_aps, TRUE); + v = g_variant_new_objv(list, -1); + g_dbus_method_invocation_return_value(invocation, g_variant_new_tuple(&v, 1)); } static void -impl_device_wifi_request_scan (NMDBusObject *obj, - const NMDBusInterfaceInfoExtended *interface_info, - const NMDBusMethodInfoExtended *method_info, - GDBusConnection *connection, - const char *sender, - GDBusMethodInvocation *invocation, - GVariant *parameters) +impl_device_wifi_request_scan(NMDBusObject * obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended * method_info, + GDBusConnection * connection, + const char * sender, + GDBusMethodInvocation * invocation, + GVariant * parameters) { - gs_unref_variant GVariant *options = NULL; + gs_unref_variant GVariant *options = NULL; - /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ - g_variant_get (parameters, "(@a{sv})", &options); + g_variant_get(parameters, "(@a{sv})", &options); - _dispatch_request_scan (NM_DEVICE (obj), - options, - invocation); + _dispatch_request_scan(NM_DEVICE(obj), options, invocation); } -const GDBusSignalInfo nm_signal_info_wireless_access_point_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "AccessPointAdded", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("access_point", "o"), - ), -); +const GDBusSignalInfo nm_signal_info_wireless_access_point_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "AccessPointAdded", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("access_point", "o"), ), ); -const GDBusSignalInfo nm_signal_info_wireless_access_point_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( - "AccessPointRemoved", - .args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("access_point", "o"), - ), -); +const GDBusSignalInfo nm_signal_info_wireless_access_point_removed = + NM_DEFINE_GDBUS_SIGNAL_INFO_INIT( + "AccessPointRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS(NM_DEFINE_GDBUS_ARG_INFO("access_point", "o"), ), ); const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WIRELESS, - .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetAccessPoints", - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("access_points", "ao"), - ), - ), - .handle = impl_device_wifi_get_access_points, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "GetAllAccessPoints", - .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("access_points", "ao"), - ), - ), - .handle = impl_device_wifi_get_all_access_points, - ), - NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( - NM_DEFINE_GDBUS_METHOD_INFO_INIT ( - "RequestScan", - .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( - NM_DEFINE_GDBUS_ARG_INFO ("options", "a{sv}"), - ), - ), - .handle = impl_device_wifi_request_scan, - ), - ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - &nm_signal_info_wireless_access_point_added, - &nm_signal_info_wireless_access_point_removed, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PermHwAddress", "s", NM_DEVICE_PERM_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_DEVICE_WIFI_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Bitrate", "u", NM_DEVICE_WIFI_BITRATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AccessPoints", "ao", NM_DEVICE_WIFI_ACCESS_POINTS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveAccessPoint", "o", NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WirelessCapabilities", "u", NM_DEVICE_WIFI_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("LastScan", "x", NM_DEVICE_WIFI_LAST_SCAN), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetAccessPoints", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("access_points", "ao"), ), ), + .handle = impl_device_wifi_get_access_points, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "GetAllAccessPoints", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("access_points", "ao"), ), ), + .handle = impl_device_wifi_get_all_access_points, ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED( + NM_DEFINE_GDBUS_METHOD_INFO_INIT( + "RequestScan", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS( + NM_DEFINE_GDBUS_ARG_INFO("options", "a{sv}"), ), ), + .handle = impl_device_wifi_request_scan, ), ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, + &nm_signal_info_wireless_access_point_added, + &nm_signal_info_wireless_access_point_removed, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_DEVICE_WIFI_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Bitrate", + "u", + NM_DEVICE_WIFI_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("AccessPoints", + "ao", + NM_DEVICE_WIFI_ACCESS_POINTS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ActiveAccessPoint", + "o", + NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("WirelessCapabilities", + "u", + NM_DEVICE_WIFI_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastScan", + "x", + NM_DEVICE_WIFI_LAST_SCAN), ), ), + .legacy_property_changed = TRUE, }; diff --git a/src/devices/wifi/nm-wifi-common.h b/src/devices/wifi/nm-wifi-common.h index 829df826..203f2a53 100644 --- a/src/devices/wifi/nm-wifi-common.h +++ b/src/devices/wifi/nm-wifi-common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -11,12 +11,12 @@ /*****************************************************************************/ -void nm_device_wifi_emit_signal_access_point (NMDevice *device, - NMWifiAP *ap, - gboolean is_added /* or else is_removed */); +void nm_device_wifi_emit_signal_access_point(NMDevice *device, + NMWifiAP *ap, + gboolean is_added /* or else is_removed */); extern const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless; -extern const GDBusSignalInfo nm_signal_info_wireless_access_point_added; -extern const GDBusSignalInfo nm_signal_info_wireless_access_point_removed; +extern const GDBusSignalInfo nm_signal_info_wireless_access_point_added; +extern const GDBusSignalInfo nm_signal_info_wireless_access_point_removed; -#endif /* __NM_WIFI_COMMON_H__ */ +#endif /* __NM_WIFI_COMMON_H__ */ diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 9b87bbbf..1d140759 100644 --- a/src/devices/wifi/nm-wifi-factory.c +++ b/src/devices/wifi/nm-wifi-factory.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 - 2014 Red Hat, Inc. */ @@ -20,135 +20,138 @@ /*****************************************************************************/ -#define NM_TYPE_WIFI_FACTORY (nm_wifi_factory_get_type ()) -#define NM_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactory)) -#define NM_WIFI_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_FACTORY, NMWifiFactoryClass)) -#define NM_IS_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_FACTORY)) -#define NM_IS_WIFI_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_FACTORY)) -#define NM_WIFI_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactoryClass)) +#define NM_TYPE_WIFI_FACTORY (nm_wifi_factory_get_type()) +#define NM_WIFI_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactory)) +#define NM_WIFI_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_FACTORY, NMWifiFactoryClass)) +#define NM_IS_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_FACTORY)) +#define NM_IS_WIFI_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_FACTORY)) +#define NM_WIFI_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactoryClass)) typedef struct { - NMDeviceFactory parent; + NMDeviceFactory parent; } NMWifiFactory; typedef struct { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; } NMWifiFactoryClass; -static GType nm_wifi_factory_get_type (void); +static GType nm_wifi_factory_get_type(void); -G_DEFINE_TYPE (NMWifiFactory, nm_wifi_factory, NM_TYPE_DEVICE_FACTORY) +G_DEFINE_TYPE(NMWifiFactory, nm_wifi_factory, NM_TYPE_DEVICE_FACTORY) /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WIFI, NM_LINK_TYPE_OLPC_MESH) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_OLPC_MESH_SETTING_NAME) -) +NM_DEVICE_FACTORY_DECLARE_TYPES( + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_WIFI, NM_LINK_TYPE_OLPC_MESH) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_OLPC_MESH_SETTING_NAME)) G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - return (NMDeviceFactory *) g_object_new (NM_TYPE_WIFI_FACTORY, NULL); + return (NMDeviceFactory *) g_object_new(NM_TYPE_WIFI_FACTORY, NULL); } /*****************************************************************************/ static void -p2p_device_created (NMDeviceWifi *device, - NMDeviceWifiP2P *p2p_device, - NMDeviceFactory *self) +p2p_device_created(NMDeviceWifi *device, NMDeviceWifiP2P *p2p_device, NMDeviceFactory *self) { - nm_log_info (LOGD_PLATFORM | LOGD_WIFI, - "Wi-Fi P2P device controlled by interface %s created", - nm_device_get_iface (NM_DEVICE (device))); + nm_log_info(LOGD_PLATFORM | LOGD_WIFI, + "Wi-Fi P2P device controlled by interface %s created", + nm_device_get_iface(NM_DEVICE(device))); - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, p2p_device); + g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, p2p_device); } static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - gs_free char *backend = NULL; - - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (plink != NULL, NULL); - g_return_val_if_fail (g_strcmp0 (iface, plink->name) == 0, NULL); - g_return_val_if_fail (NM_IN_SET (plink->type, NM_LINK_TYPE_WIFI, NM_LINK_TYPE_OLPC_MESH), NULL); - - if (plink->type != NM_LINK_TYPE_WIFI) - return nm_device_olpc_mesh_new (iface); - - backend = nm_config_data_get_device_config_by_pllink (NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND, - plink, - "wifi", - NULL); - nm_strstrip (backend); - - nm_log_dbg (LOGD_PLATFORM | LOGD_WIFI, - "(%s) config: backend is %s%s%s%s", - iface, - NM_PRINT_FMT_QUOTE_STRING (backend), - WITH_IWD ? " (iwd support enabled)" : ""); - if (!backend || !g_ascii_strcasecmp (backend, "wpa_supplicant")) { - NMDevice *device; - NMDeviceWifiCapabilities capabilities; - NM80211Mode mode; - - if (!nm_platform_wifi_get_capabilities (NM_PLATFORM_GET, - plink->ifindex, - &capabilities)) { - nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, - "(%s) failed to initialize Wi-Fi driver for ifindex %d", - iface, plink->ifindex); - return NULL; - } - - /* Ignore monitor-mode and other unhandled interface types. - * FIXME: keep TYPE_MONITOR devices in UNAVAILABLE state and manage - * them if/when they change to a handled type. - */ - mode = nm_platform_wifi_get_mode (NM_PLATFORM_GET, plink->ifindex); - if (mode == NM_802_11_MODE_UNKNOWN) { - *out_ignore = TRUE; - return NULL; - } - - device = nm_device_wifi_new (iface, capabilities); - - g_signal_connect_object (device, NM_DEVICE_WIFI_P2P_DEVICE_CREATED, - G_CALLBACK (p2p_device_created), - factory, - 0); - - return device; - } + gs_free char *backend = NULL; + + g_return_val_if_fail(iface != NULL, NULL); + g_return_val_if_fail(plink != NULL, NULL); + g_return_val_if_fail(g_strcmp0(iface, plink->name) == 0, NULL); + g_return_val_if_fail(NM_IN_SET(plink->type, NM_LINK_TYPE_WIFI, NM_LINK_TYPE_OLPC_MESH), NULL); + + if (plink->type != NM_LINK_TYPE_WIFI) + return nm_device_olpc_mesh_new(iface); + + backend = nm_config_data_get_device_config_by_pllink(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND, + plink, + "wifi", + NULL); + nm_strstrip(backend); + + nm_log_dbg(LOGD_PLATFORM | LOGD_WIFI, + "(%s) config: backend is %s%s%s%s", + iface, + NM_PRINT_FMT_QUOTE_STRING(backend), + WITH_IWD ? " (iwd support enabled)" : ""); + if (!backend || !g_ascii_strcasecmp(backend, "wpa_supplicant")) { + NMDevice * device; + NMDeviceWifiCapabilities capabilities; + NM80211Mode mode; + + if (!nm_platform_wifi_get_capabilities(NM_PLATFORM_GET, plink->ifindex, &capabilities)) { + nm_log_warn(LOGD_PLATFORM | LOGD_WIFI, + "(%s) failed to initialize Wi-Fi driver for ifindex %d", + iface, + plink->ifindex); + return NULL; + } + + /* Ignore monitor-mode and other unhandled interface types. + * FIXME: keep TYPE_MONITOR devices in UNAVAILABLE state and manage + * them if/when they change to a handled type. + */ + mode = nm_platform_wifi_get_mode(NM_PLATFORM_GET, plink->ifindex); + if (mode == NM_802_11_MODE_UNKNOWN) { + *out_ignore = TRUE; + return NULL; + } + + device = nm_device_wifi_new(iface, capabilities); + + g_signal_connect_object(device, + NM_DEVICE_WIFI_P2P_DEVICE_CREATED, + G_CALLBACK(p2p_device_created), + factory, + 0); + + return device; + } #if WITH_IWD - else if (!g_ascii_strcasecmp (backend, "iwd")) - return nm_device_iwd_new (iface); + else if (!g_ascii_strcasecmp(backend, "iwd")) + return nm_device_iwd_new(iface); #endif - nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s) config: unknown or unsupported wifi-backend %s", iface, backend); - return NULL; + nm_log_warn(LOGD_PLATFORM | LOGD_WIFI, + "(%s) config: unknown or unsupported wifi-backend %s", + iface, + backend); + return NULL; } /*****************************************************************************/ static void -nm_wifi_factory_init (NMWifiFactory *self) -{ -} +nm_wifi_factory_init(NMWifiFactory *self) +{} static void -nm_wifi_factory_class_init (NMWifiFactoryClass *klass) +nm_wifi_factory_class_init(NMWifiFactoryClass *klass) { - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - factory_class->create_device = create_device; - factory_class->get_supported_types = get_supported_types; + factory_class->create_device = create_device; + factory_class->get_supported_types = get_supported_types; } diff --git a/src/devices/wifi/nm-wifi-p2p-peer.c b/src/devices/wifi/nm-wifi-p2p-peer.c index c58bd95e..fe6ad0a0 100644 --- a/src/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/devices/wifi/nm-wifi-p2p-peer.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -22,649 +22,668 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMWifiP2PPeer, - PROP_NAME, - PROP_MANUFACTURER, - PROP_MODEL, - PROP_MODEL_NUMBER, - PROP_SERIAL, - PROP_WFD_IES, - PROP_HW_ADDRESS, - PROP_STRENGTH, - PROP_LAST_SEEN, - PROP_FLAGS, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMWifiP2PPeer, + PROP_NAME, + PROP_MANUFACTURER, + PROP_MODEL, + PROP_MODEL_NUMBER, + PROP_SERIAL, + PROP_WFD_IES, + PROP_HW_ADDRESS, + PROP_STRENGTH, + PROP_LAST_SEEN, + PROP_FLAGS, ); struct _NMWifiP2PPeerPrivate { - NMRefString *supplicant_path; /* D-Bus object path of this Peer from wpa_supplicant */ + NMRefString *supplicant_path; /* D-Bus object path of this Peer from wpa_supplicant */ - /* Scanned or cached values */ - char * name; - char * manufacturer; - char * model; - char * model_number; - char * serial; + /* Scanned or cached values */ + char *name; + char *manufacturer; + char *model; + char *model_number; + char *serial; - char * address; + char *address; - GBytes * wfd_ies; - char ** groups; + GBytes *wfd_ies; + char ** groups; - guint8 strength; + guint8 strength; - NM80211ApFlags flags; /* General flags */ + NM80211ApFlags flags; /* General flags */ - /* Non-scanned attributes */ - gint32 last_seen; /* Timestamp when the Peer was seen lastly (obtained via nm_utils_get_monotonic_timestamp_sec()) */ + /* Non-scanned attributes */ + gint32 + last_seen; /* Timestamp when the Peer was seen lastly (obtained via nm_utils_get_monotonic_timestamp_sec()) */ }; typedef struct _NMWifiP2PPeerPrivate NMWifiP2PPeerPrivate; struct _NMWifiP2PPeerClass { - NMDBusObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMWifiP2PPeer, nm_wifi_p2p_peer, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE(NMWifiP2PPeer, nm_wifi_p2p_peer, NM_TYPE_DBUS_OBJECT) -#define NM_WIFI_P2P_PEER_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMWifiP2PPeer, NM_IS_WIFI_P2P_PEER) +#define NM_WIFI_P2P_PEER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE_PTR(self, NMWifiP2PPeer, NM_IS_WIFI_P2P_PEER) /*****************************************************************************/ const char ** -nm_wifi_p2p_peers_get_paths (const CList *peers_lst_head) +nm_wifi_p2p_peers_get_paths(const CList *peers_lst_head) { - NMWifiP2PPeer *peer; - const char **list; - const char *path; - gsize i, n; + NMWifiP2PPeer *peer; + const char ** list; + const char * path; + gsize i, n; - n = c_list_length (peers_lst_head); - list = g_new (const char *, n + 1); + n = c_list_length(peers_lst_head); + list = g_new(const char *, n + 1); - i = 0; - if (n > 0) { - c_list_for_each_entry (peer, peers_lst_head, peers_lst) { - nm_assert (i < n); - path = nm_dbus_object_get_path (NM_DBUS_OBJECT (peer)); - nm_assert (path); + i = 0; + if (n > 0) { + c_list_for_each_entry (peer, peers_lst_head, peers_lst) { + nm_assert(i < n); + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(peer)); + nm_assert(path); - list[i++] = path; - } - nm_assert (i <= n); - } - list[i] = NULL; - return list; + list[i++] = path; + } + nm_assert(i <= n); + } + list[i] = NULL; + return list; } NMWifiP2PPeer * -nm_wifi_p2p_peers_find_first_compatible (const CList *peers_lst_head, - NMConnection *connection) +nm_wifi_p2p_peers_find_first_compatible(const CList *peers_lst_head, NMConnection *connection) { - NMWifiP2PPeer *peer; + NMWifiP2PPeer *peer; - g_return_val_if_fail (connection, NULL); + g_return_val_if_fail(connection, NULL); - c_list_for_each_entry (peer, peers_lst_head, peers_lst) { - if (nm_wifi_p2p_peer_check_compatible (peer, connection)) - return peer; - } - return NULL; + c_list_for_each_entry (peer, peers_lst_head, peers_lst) { + if (nm_wifi_p2p_peer_check_compatible(peer, connection)) + return peer; + } + return NULL; } NMWifiP2PPeer * -nm_wifi_p2p_peers_find_by_supplicant_path (const CList *peers_lst_head, const char *path) +nm_wifi_p2p_peers_find_by_supplicant_path(const CList *peers_lst_head, const char *path) { - NMWifiP2PPeer *peer; + NMWifiP2PPeer *peer; - g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail(path != NULL, NULL); - c_list_for_each_entry (peer, peers_lst_head, peers_lst) { - if (nm_streq0 (path, nm_wifi_p2p_peer_get_supplicant_path (peer))) - return peer; - } - return NULL; + c_list_for_each_entry (peer, peers_lst_head, peers_lst) { + if (nm_streq0(path, nm_wifi_p2p_peer_get_supplicant_path(peer))) + return peer; + } + return NULL; } /*****************************************************************************/ NMWifiP2PPeer * -nm_wifi_p2p_peer_lookup_for_device (NMDevice *device, const char *exported_path) +nm_wifi_p2p_peer_lookup_for_device(NMDevice *device, const char *exported_path) { - NMWifiP2PPeer *peer; + NMWifiP2PPeer *peer; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); - peer = (NMWifiP2PPeer *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (device)), - exported_path); - if ( !peer - || !NM_IS_WIFI_P2P_PEER (peer) - || peer->wifi_device != device) - return NULL; + peer = (NMWifiP2PPeer *) nm_dbus_manager_lookup_object( + nm_dbus_object_get_manager(NM_DBUS_OBJECT(device)), + exported_path); + if (!peer || !NM_IS_WIFI_P2P_PEER(peer) || peer->wifi_device != device) + return NULL; - return peer; + return peer; } /*****************************************************************************/ const char * -nm_wifi_p2p_peer_get_supplicant_path (NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_supplicant_path(NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return nm_ref_string_get_str (NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->supplicant_path); + return nm_ref_string_get_str(NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->supplicant_path); } const char * -nm_wifi_p2p_peer_get_name (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_name(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->name; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->name; } gboolean -nm_wifi_p2p_peer_set_name (NMWifiP2PPeer *peer, const char *str) +nm_wifi_p2p_peer_set_name(NMWifiP2PPeer *peer, const char *str) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset (&priv->name, str)) - return FALSE; - _notify (peer, PROP_NAME); - return TRUE; + if (!nm_utils_strdup_reset(&priv->name, str)) + return FALSE; + _notify(peer, PROP_NAME); + return TRUE; } const char * -nm_wifi_p2p_peer_get_manufacturer (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_manufacturer(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->manufacturer; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->manufacturer; } gboolean -nm_wifi_p2p_peer_set_manufacturer (NMWifiP2PPeer *peer, const char *str) +nm_wifi_p2p_peer_set_manufacturer(NMWifiP2PPeer *peer, const char *str) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset (&priv->manufacturer, str)) - return FALSE; - _notify (peer, PROP_MANUFACTURER); - return TRUE; + if (!nm_utils_strdup_reset(&priv->manufacturer, str)) + return FALSE; + _notify(peer, PROP_MANUFACTURER); + return TRUE; } const char * -nm_wifi_p2p_peer_get_model (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_model(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->model; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->model; } gboolean -nm_wifi_p2p_peer_set_model (NMWifiP2PPeer *peer, const char *str) +nm_wifi_p2p_peer_set_model(NMWifiP2PPeer *peer, const char *str) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset (&priv->model, str)) - return FALSE; - _notify (peer, PROP_MODEL); - return TRUE; + if (!nm_utils_strdup_reset(&priv->model, str)) + return FALSE; + _notify(peer, PROP_MODEL); + return TRUE; } const char * -nm_wifi_p2p_peer_get_model_number (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_model_number(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->model_number; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->model_number; } gboolean -nm_wifi_p2p_peer_set_model_number (NMWifiP2PPeer *peer, const char *str) +nm_wifi_p2p_peer_set_model_number(NMWifiP2PPeer *peer, const char *str) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset (&priv->model_number, str)) - return FALSE; - _notify (peer, PROP_MODEL_NUMBER); - return TRUE; + if (!nm_utils_strdup_reset(&priv->model_number, str)) + return FALSE; + _notify(peer, PROP_MODEL_NUMBER); + return TRUE; } const char * -nm_wifi_p2p_peer_get_serial (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_serial(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->serial; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->serial; } gboolean -nm_wifi_p2p_peer_set_serial (NMWifiP2PPeer *peer, const char *str) +nm_wifi_p2p_peer_set_serial(NMWifiP2PPeer *peer, const char *str) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset (&priv->serial, str)) - return FALSE; - _notify (peer, PROP_SERIAL); - return TRUE; + if (!nm_utils_strdup_reset(&priv->serial, str)) + return FALSE; + _notify(peer, PROP_SERIAL); + return TRUE; } GBytes * -nm_wifi_p2p_peer_get_wfd_ies (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_wfd_ies(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->wfd_ies; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->wfd_ies; } gboolean -nm_wifi_p2p_peer_set_wfd_ies (NMWifiP2PPeer *peer, GBytes *wfd_ies) +nm_wifi_p2p_peer_set_wfd_ies(NMWifiP2PPeer *peer, GBytes *wfd_ies) { - NMWifiP2PPeerPrivate *priv; - gs_unref_bytes GBytes *wfd_ies_old = NULL; + NMWifiP2PPeerPrivate *priv; + gs_unref_bytes GBytes *wfd_ies_old = NULL; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), FALSE); - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (nm_gbytes_equal0 (priv->wfd_ies, wfd_ies)) - return FALSE; + if (nm_gbytes_equal0(priv->wfd_ies, wfd_ies)) + return FALSE; - wfd_ies_old = g_steal_pointer (&priv->wfd_ies); - priv->wfd_ies = wfd_ies ? g_bytes_ref (wfd_ies) : NULL; + wfd_ies_old = g_steal_pointer(&priv->wfd_ies); + priv->wfd_ies = wfd_ies ? g_bytes_ref(wfd_ies) : NULL; - _notify (peer, PROP_WFD_IES); - return TRUE; + _notify(peer, PROP_WFD_IES); + return TRUE; } -const char *const* -nm_wifi_p2p_peer_get_groups (const NMWifiP2PPeer *peer) +const char *const * +nm_wifi_p2p_peer_get_groups(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return (const char *const*) NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->groups; + return (const char *const *) NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->groups; } const char * -nm_wifi_p2p_peer_get_address (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_address(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->address; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->address; } static gboolean -nm_wifi_p2p_peer_set_address_bin (NMWifiP2PPeer *peer, const guint8 addr[static ETH_ALEN]) +nm_wifi_p2p_peer_set_address_bin(NMWifiP2PPeer *peer, const guint8 addr[static ETH_ALEN]) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if ( priv->address - && nm_utils_hwaddr_matches (addr, ETH_ALEN, priv->address, -1)) - return FALSE; + if (priv->address && nm_utils_hwaddr_matches(addr, ETH_ALEN, priv->address, -1)) + return FALSE; - g_free (priv->address); - priv->address = nm_utils_hwaddr_ntoa (addr, ETH_ALEN); - _notify (peer, PROP_HW_ADDRESS); - return TRUE; + g_free(priv->address); + priv->address = nm_utils_hwaddr_ntoa(addr, ETH_ALEN); + _notify(peer, PROP_HW_ADDRESS); + return TRUE; } gboolean -nm_wifi_p2p_peer_set_address (NMWifiP2PPeer *peer, const char *addr) +nm_wifi_p2p_peer_set_address(NMWifiP2PPeer *peer, const char *addr) { - guint8 addr_buf[ETH_ALEN]; + guint8 addr_buf[ETH_ALEN]; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), FALSE); - if ( !addr - || !nm_utils_hwaddr_aton (addr, addr_buf, sizeof (addr_buf))) - g_return_val_if_reached (FALSE); + if (!addr || !nm_utils_hwaddr_aton(addr, addr_buf, sizeof(addr_buf))) + g_return_val_if_reached(FALSE); - return nm_wifi_p2p_peer_set_address_bin (peer, addr_buf); + return nm_wifi_p2p_peer_set_address_bin(peer, addr_buf); } gint8 -nm_wifi_p2p_peer_get_strength (NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_strength(NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), 0); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), 0); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->strength; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->strength; } gboolean -nm_wifi_p2p_peer_set_strength (NMWifiP2PPeer *peer, const gint8 strength) +nm_wifi_p2p_peer_set_strength(NMWifiP2PPeer *peer, const gint8 strength) { - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (priv->strength != strength) { - priv->strength = strength; - _notify (peer, PROP_STRENGTH); - return TRUE; - } - return FALSE; + if (priv->strength != strength) { + priv->strength = strength; + _notify(peer, PROP_STRENGTH); + return TRUE; + } + return FALSE; } NM80211ApFlags -nm_wifi_p2p_peer_get_flags (const NMWifiP2PPeer *peer) +nm_wifi_p2p_peer_get_flags(const NMWifiP2PPeer *peer) { - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), NM_802_11_AP_FLAGS_NONE); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NM_802_11_AP_FLAGS_NONE); - return NM_WIFI_P2P_PEER_GET_PRIVATE (peer)->flags; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->flags; } static gboolean -nm_wifi_p2p_peer_set_last_seen (NMWifiP2PPeer *peer, gint32 last_seen) +nm_wifi_p2p_peer_set_last_seen(NMWifiP2PPeer *peer, gint32 last_seen) { - NMWifiP2PPeerPrivate *priv; + NMWifiP2PPeerPrivate *priv; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), FALSE); - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (priv->last_seen != last_seen) { - priv->last_seen = last_seen; - _notify (peer, PROP_LAST_SEEN); - return TRUE; - } - return FALSE; + if (priv->last_seen != last_seen) { + priv->last_seen = last_seen; + _notify(peer, PROP_LAST_SEEN); + return TRUE; + } + return FALSE; } - /*****************************************************************************/ gboolean -nm_wifi_p2p_peer_update_from_properties (NMWifiP2PPeer *peer, - const NMSupplicantPeerInfo *peer_info) +nm_wifi_p2p_peer_update_from_properties(NMWifiP2PPeer *peer, const NMSupplicantPeerInfo *peer_info) { - NMWifiP2PPeerPrivate *priv; - gboolean changed = FALSE; + NMWifiP2PPeerPrivate *priv; + gboolean changed = FALSE; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (peer), FALSE); - g_return_val_if_fail (peer_info, FALSE); - nm_assert (NM_IS_REF_STRING (peer_info->peer_path)); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), FALSE); + g_return_val_if_fail(peer_info, FALSE); + nm_assert(NM_IS_REF_STRING(peer_info->peer_path)); - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (peer); + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - nm_assert ( !priv->supplicant_path - || priv->supplicant_path == peer_info->peer_path); + nm_assert(!priv->supplicant_path || priv->supplicant_path == peer_info->peer_path); - g_object_freeze_notify (G_OBJECT (peer)); + g_object_freeze_notify(G_OBJECT(peer)); - if (!priv->supplicant_path) { - priv->supplicant_path = nm_ref_string_ref (peer_info->peer_path); - changed = TRUE; - } + if (!priv->supplicant_path) { + priv->supplicant_path = nm_ref_string_ref(peer_info->peer_path); + changed = TRUE; + } - changed |= nm_wifi_p2p_peer_set_strength (peer, peer_info->signal_percent); - changed |= nm_wifi_p2p_peer_set_name (peer, peer_info->device_name); - changed |= nm_wifi_p2p_peer_set_manufacturer (peer, peer_info->manufacturer); - changed |= nm_wifi_p2p_peer_set_model (peer, peer_info->model); - changed |= nm_wifi_p2p_peer_set_model_number (peer, peer_info->model_number); - changed |= nm_wifi_p2p_peer_set_serial (peer, peer_info->serial); + changed |= nm_wifi_p2p_peer_set_strength(peer, peer_info->signal_percent); + changed |= nm_wifi_p2p_peer_set_name(peer, peer_info->device_name); + changed |= nm_wifi_p2p_peer_set_manufacturer(peer, peer_info->manufacturer); + changed |= nm_wifi_p2p_peer_set_model(peer, peer_info->model); + changed |= nm_wifi_p2p_peer_set_model_number(peer, peer_info->model_number); + changed |= nm_wifi_p2p_peer_set_serial(peer, peer_info->serial); - if (peer_info->address_valid) - changed |= nm_wifi_p2p_peer_set_address_bin (peer, peer_info->address); - else { - /* we don't reset the address. */ - } + if (peer_info->address_valid) + changed |= nm_wifi_p2p_peer_set_address_bin(peer, peer_info->address); + else { + /* we don't reset the address. */ + } - changed |= nm_wifi_p2p_peer_set_wfd_ies (peer, peer_info->ies); - changed |= nm_wifi_p2p_peer_set_last_seen (peer, peer_info->last_seen_msec / 1000u); + changed |= nm_wifi_p2p_peer_set_wfd_ies(peer, peer_info->ies); + changed |= nm_wifi_p2p_peer_set_last_seen(peer, peer_info->last_seen_msec / 1000u); - g_object_thaw_notify (G_OBJECT (peer)); + g_object_thaw_notify(G_OBJECT(peer)); - return changed; + return changed; } const char * -nm_wifi_p2p_peer_to_string (const NMWifiP2PPeer *self, - char *str_buf, - gsize buf_len, - gint32 now_s) +nm_wifi_p2p_peer_to_string(const NMWifiP2PPeer *self, char *str_buf, gsize buf_len, gint32 now_s) { - const NMWifiP2PPeerPrivate *priv; - const char *supplicant_id = "-"; - const char* export_path; + const NMWifiP2PPeerPrivate *priv; + const char * supplicant_id = "-"; + const char * export_path; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (self), NULL); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(self), NULL); - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (self); + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(self); - if (priv->supplicant_path) - supplicant_id = strrchr (priv->supplicant_path->str, '/') ?: supplicant_id; + if (priv->supplicant_path) + supplicant_id = strrchr(priv->supplicant_path->str, '/') ?: supplicant_id; - export_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); - if (export_path) - export_path = strrchr (export_path, '/') ?: export_path; - else - export_path = "/"; + export_path = nm_dbus_object_get_path(NM_DBUS_OBJECT(self)); + if (export_path) + export_path = strrchr(export_path, '/') ?: export_path; + else + export_path = "/"; - g_snprintf (str_buf, buf_len, - "%17s [n:%s, m:%s, mod:%s, mod_num:%s, ser:%s] %3us sup:%s [nm:%s]", - priv->address ?: "(none)", - priv->name, - priv->manufacturer, - priv->model, - priv->model_number, - priv->serial, - priv->last_seen > 0 ? ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_sec ()) - priv->last_seen) : -1, - supplicant_id, - export_path); + g_snprintf(str_buf, + buf_len, + "%17s [n:%s, m:%s, mod:%s, mod_num:%s, ser:%s] %3us sup:%s [nm:%s]", + priv->address ?: "(none)", + priv->name, + priv->manufacturer, + priv->model, + priv->model_number, + priv->serial, + priv->last_seen > 0 ? ((now_s > 0 ? now_s : nm_utils_get_monotonic_timestamp_sec()) + - priv->last_seen) + : -1, + supplicant_id, + export_path); - return str_buf; + return str_buf; } gboolean -nm_wifi_p2p_peer_check_compatible (NMWifiP2PPeer *self, - NMConnection *connection) +nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection) { - NMWifiP2PPeerPrivate *priv; - NMSettingWifiP2P *s_wifi_p2p; - const char *hwaddr; + NMWifiP2PPeerPrivate *priv; + NMSettingWifiP2P * s_wifi_p2p; + const char * hwaddr; - g_return_val_if_fail (NM_IS_WIFI_P2P_PEER (self), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(self), FALSE); + g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE); - priv = NM_WIFI_P2P_PEER_GET_PRIVATE (self); + priv = NM_WIFI_P2P_PEER_GET_PRIVATE(self); - s_wifi_p2p = NM_SETTING_WIFI_P2P (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIFI_P2P)); - if (s_wifi_p2p == NULL) - return FALSE; + s_wifi_p2p = + NM_SETTING_WIFI_P2P(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIFI_P2P)); + if (s_wifi_p2p == NULL) + return FALSE; - hwaddr = nm_setting_wifi_p2p_get_peer (s_wifi_p2p); - if ( hwaddr - && ( !priv->address - || !nm_utils_hwaddr_matches (hwaddr, -1, priv->address, -1))) - return FALSE; + hwaddr = nm_setting_wifi_p2p_get_peer(s_wifi_p2p); + if (hwaddr && (!priv->address || !nm_utils_hwaddr_matches(hwaddr, -1, priv->address, -1))) + return FALSE; - return TRUE; + return TRUE; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMWifiP2PPeer *self = NM_WIFI_P2P_PEER (object); - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_FLAGS: - g_value_set_uint (value, priv->flags); - break; - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - case PROP_MANUFACTURER: - g_value_set_string (value, priv->manufacturer); - break; - case PROP_MODEL: - g_value_set_string (value, priv->model); - break; - case PROP_MODEL_NUMBER: - g_value_set_string (value, priv->model_number); - break; - case PROP_SERIAL: - g_value_set_string (value, priv->serial); - break; - case PROP_WFD_IES: - g_value_take_variant (value, nm_utils_gbytes_to_variant_ay (priv->wfd_ies)); - break; - case PROP_HW_ADDRESS: - g_value_set_string (value, priv->address); - break; - case PROP_STRENGTH: - g_value_set_uchar (value, priv->strength); - break; - case PROP_LAST_SEEN: - g_value_set_int (value, - priv->last_seen > 0 - ? (int) nm_utils_monotonic_timestamp_as_boottime (priv->last_seen, NM_UTILS_NSEC_PER_SEC) - : -1); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMWifiP2PPeer * self = NM_WIFI_P2P_PEER(object); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_uint(value, priv->flags); + break; + case PROP_NAME: + g_value_set_string(value, priv->name); + break; + case PROP_MANUFACTURER: + g_value_set_string(value, priv->manufacturer); + break; + case PROP_MODEL: + g_value_set_string(value, priv->model); + break; + case PROP_MODEL_NUMBER: + g_value_set_string(value, priv->model_number); + break; + case PROP_SERIAL: + g_value_set_string(value, priv->serial); + break; + case PROP_WFD_IES: + g_value_take_variant(value, nm_utils_gbytes_to_variant_ay(priv->wfd_ies)); + break; + case PROP_HW_ADDRESS: + g_value_set_string(value, priv->address); + break; + case PROP_STRENGTH: + g_value_set_uchar(value, priv->strength); + break; + case PROP_LAST_SEEN: + g_value_set_int(value, + priv->last_seen > 0 + ? (int) nm_utils_monotonic_timestamp_as_boottime(priv->last_seen, + NM_UTILS_NSEC_PER_SEC) + : -1); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_wifi_p2p_peer_init (NMWifiP2PPeer *self) +nm_wifi_p2p_peer_init(NMWifiP2PPeer *self) { - NMWifiP2PPeerPrivate *priv; + NMWifiP2PPeerPrivate *priv; - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerPrivate); + priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerPrivate); - self->_priv = priv; + self->_priv = priv; - c_list_init (&self->peers_lst); + c_list_init(&self->peers_lst); - priv->flags = NM_802_11_AP_FLAGS_NONE; - priv->last_seen = -1; + priv->flags = NM_802_11_AP_FLAGS_NONE; + priv->last_seen = -1; } NMWifiP2PPeer * -nm_wifi_p2p_peer_new_from_properties (const NMSupplicantPeerInfo *peer_info) +nm_wifi_p2p_peer_new_from_properties(const NMSupplicantPeerInfo *peer_info) { - NMWifiP2PPeer *peer; + NMWifiP2PPeer *peer; - g_return_val_if_fail (peer_info, NULL); + g_return_val_if_fail(peer_info, NULL); - peer = g_object_new (NM_TYPE_WIFI_P2P_PEER, NULL); - nm_wifi_p2p_peer_update_from_properties (peer, peer_info); - return peer; + peer = g_object_new(NM_TYPE_WIFI_P2P_PEER, NULL); + nm_wifi_p2p_peer_update_from_properties(peer, peer_info); + return peer; } static void -finalize (GObject *object) +finalize(GObject *object) { - NMWifiP2PPeer *self = NM_WIFI_P2P_PEER (object); - NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (self); + NMWifiP2PPeer * self = NM_WIFI_P2P_PEER(object); + NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(self); - nm_assert (!self->wifi_device); - nm_assert (c_list_is_empty (&self->peers_lst)); + nm_assert(!self->wifi_device); + nm_assert(c_list_is_empty(&self->peers_lst)); - nm_ref_string_unref (priv->supplicant_path); - g_free (priv->name); - g_free (priv->manufacturer); - g_free (priv->model); - g_free (priv->model_number); - g_free (priv->serial); - g_free (priv->address); - g_bytes_unref (priv->wfd_ies); - g_strfreev (priv->groups); + nm_ref_string_unref(priv->supplicant_path); + g_free(priv->name); + g_free(priv->manufacturer); + g_free(priv->model); + g_free(priv->model_number); + g_free(priv->serial); + g_free(priv->address); + g_bytes_unref(priv->wfd_ies); + g_strfreev(priv->groups); - G_OBJECT_CLASS (nm_wifi_p2p_peer_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_wifi_p2p_peer_parent_class)->finalize(object); } static const NMDBusInterfaceInfoExtended interface_info_p2p_peer = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_WIFI_P2P_PEER, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - /* Before 1.24, we wrongly exposed a property "Groups" of type "as". Don't reuse that property name. */ - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Flags", "u", NM_WIFI_P2P_PEER_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Name", "s", NM_WIFI_P2P_PEER_NAME), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Manufacturer", "s", NM_WIFI_P2P_PEER_MANUFACTURER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Model", "s", NM_WIFI_P2P_PEER_MODEL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("ModelNumber", "s", NM_WIFI_P2P_PEER_MODEL_NUMBER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Serial", "s", NM_WIFI_P2P_PEER_SERIAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("WfdIEs", "ay", NM_WIFI_P2P_PEER_WFD_IES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_WIFI_P2P_PEER_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Strength", "y", NM_WIFI_P2P_PEER_STRENGTH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("LastSeen", "i", NM_WIFI_P2P_PEER_LAST_SEEN), - ), - ), - .legacy_property_changed = FALSE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_WIFI_P2P_PEER, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + /* Before 1.24, we wrongly exposed a property "Groups" of type "as". Don't reuse that property name. */ + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", "u", NM_WIFI_P2P_PEER_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Name", "s", NM_WIFI_P2P_PEER_NAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Manufacturer", + "s", + NM_WIFI_P2P_PEER_MANUFACTURER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Model", "s", NM_WIFI_P2P_PEER_MODEL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ModelNumber", + "s", + NM_WIFI_P2P_PEER_MODEL_NUMBER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Serial", "s", NM_WIFI_P2P_PEER_SERIAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WfdIEs", + "ay", + NM_WIFI_P2P_PEER_WFD_IES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_WIFI_P2P_PEER_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Strength", + "y", + NM_WIFI_P2P_PEER_STRENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastSeen", + "i", + NM_WIFI_P2P_PEER_LAST_SEEN), ), ), + .legacy_property_changed = FALSE, }; static void -nm_wifi_p2p_peer_class_init (NMWifiP2PPeerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMWifiP2PPeerPrivate)); - - dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_WIFI_P2P_PEER); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_p2p_peer); - - object_class->get_property = get_property; - object_class->finalize = finalize; - - obj_properties[PROP_FLAGS] = - g_param_spec_uint (NM_WIFI_P2P_PEER_FLAGS, "", "", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_FLAGS_NONE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_NAME] = - g_param_spec_string (NM_WIFI_P2P_PEER_NAME, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MANUFACTURER] = - g_param_spec_string (NM_WIFI_P2P_PEER_MANUFACTURER, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MODEL] = - g_param_spec_string (NM_WIFI_P2P_PEER_MODEL, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_MODEL_NUMBER] = - g_param_spec_string (NM_WIFI_P2P_PEER_MODEL_NUMBER, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SERIAL] = - g_param_spec_string (NM_WIFI_P2P_PEER_SERIAL, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_WFD_IES] = - g_param_spec_variant (NM_WIFI_P2P_PEER_WFD_IES, "", "", - G_VARIANT_TYPE ("ay"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_WIFI_P2P_PEER_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_STRENGTH] = - g_param_spec_uchar (NM_WIFI_P2P_PEER_STRENGTH, "", "", - 0, G_MAXINT8, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LAST_SEEN] = - g_param_spec_int (NM_WIFI_P2P_PEER_LAST_SEEN, "", "", - -1, G_MAXINT, -1, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +nm_wifi_p2p_peer_class_init(NMWifiP2PPeerClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + + g_type_class_add_private(object_class, sizeof(NMWifiP2PPeerPrivate)); + + dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH_WIFI_P2P_PEER); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_p2p_peer); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_WIFI_P2P_PEER_FLAGS, + "", + "", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_NAME] = g_param_spec_string(NM_WIFI_P2P_PEER_NAME, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MANUFACTURER] = + g_param_spec_string(NM_WIFI_P2P_PEER_MANUFACTURER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MODEL] = g_param_spec_string(NM_WIFI_P2P_PEER_MODEL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_MODEL_NUMBER] = + g_param_spec_string(NM_WIFI_P2P_PEER_MODEL_NUMBER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SERIAL] = g_param_spec_string(NM_WIFI_P2P_PEER_SERIAL, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_WFD_IES] = g_param_spec_variant(NM_WIFI_P2P_PEER_WFD_IES, + "", + "", + G_VARIANT_TYPE("ay"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string(NM_WIFI_P2P_PEER_HW_ADDRESS, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STRENGTH] = g_param_spec_uchar(NM_WIFI_P2P_PEER_STRENGTH, + "", + "", + 0, + G_MAXINT8, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_LAST_SEEN] = g_param_spec_int(NM_WIFI_P2P_PEER_LAST_SEEN, + "", + "", + -1, + G_MAXINT, + -1, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/wifi/nm-wifi-p2p-peer.h b/src/devices/wifi/nm-wifi-p2p-peer.h index 59f9c5d2..e19cf3d8 100644 --- a/src/devices/wifi/nm-wifi-p2p-peer.h +++ b/src/devices/wifi/nm-wifi-p2p-peer.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -10,89 +10,82 @@ #include "nm-dbus-interface.h" #include "nm-connection.h" -#define NM_TYPE_WIFI_P2P_PEER (nm_wifi_p2p_peer_get_type ()) -#define NM_WIFI_P2P_PEER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeer)) -#define NM_WIFI_P2P_PEER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) -#define NM_IS_WIFI_P2P_PEER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_P2P_PEER)) -#define NM_IS_WIFI_P2P_PEER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_P2P_PEER)) -#define NM_WIFI_P2P_PEER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) - -#define NM_WIFI_P2P_PEER_FLAGS "flags" -#define NM_WIFI_P2P_PEER_NAME "name" -#define NM_WIFI_P2P_PEER_MANUFACTURER "manufacturer" -#define NM_WIFI_P2P_PEER_MODEL "model" -#define NM_WIFI_P2P_PEER_MODEL_NUMBER "model-number" -#define NM_WIFI_P2P_PEER_SERIAL "serial" -#define NM_WIFI_P2P_PEER_WFD_IES "wfd-ies" -#define NM_WIFI_P2P_PEER_HW_ADDRESS "hw-address" -#define NM_WIFI_P2P_PEER_STRENGTH "strength" -#define NM_WIFI_P2P_PEER_LAST_SEEN "last-seen" +#define NM_TYPE_WIFI_P2P_PEER (nm_wifi_p2p_peer_get_type()) +#define NM_WIFI_P2P_PEER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeer)) +#define NM_WIFI_P2P_PEER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) +#define NM_IS_WIFI_P2P_PEER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WIFI_P2P_PEER)) +#define NM_IS_WIFI_P2P_PEER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WIFI_P2P_PEER)) +#define NM_WIFI_P2P_PEER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WIFI_P2P_PEER, NMWifiP2PPeerClass)) + +#define NM_WIFI_P2P_PEER_FLAGS "flags" +#define NM_WIFI_P2P_PEER_NAME "name" +#define NM_WIFI_P2P_PEER_MANUFACTURER "manufacturer" +#define NM_WIFI_P2P_PEER_MODEL "model" +#define NM_WIFI_P2P_PEER_MODEL_NUMBER "model-number" +#define NM_WIFI_P2P_PEER_SERIAL "serial" +#define NM_WIFI_P2P_PEER_WFD_IES "wfd-ies" +#define NM_WIFI_P2P_PEER_HW_ADDRESS "hw-address" +#define NM_WIFI_P2P_PEER_STRENGTH "strength" +#define NM_WIFI_P2P_PEER_LAST_SEEN "last-seen" typedef struct { - NMDBusObject parent; - NMDevice *wifi_device; - CList peers_lst; - struct _NMWifiP2PPeerPrivate *_priv; + NMDBusObject parent; + NMDevice * wifi_device; + CList peers_lst; + struct _NMWifiP2PPeerPrivate *_priv; } NMWifiP2PPeer; typedef struct _NMWifiP2PPeerClass NMWifiP2PPeerClass; struct _NMSupplicantPeerInfo; -GType nm_wifi_p2p_peer_get_type (void); +GType nm_wifi_p2p_peer_get_type(void); -NMWifiP2PPeer *nm_wifi_p2p_peer_new_from_properties (const struct _NMSupplicantPeerInfo *peer_info); +NMWifiP2PPeer *nm_wifi_p2p_peer_new_from_properties(const struct _NMSupplicantPeerInfo *peer_info); -gboolean nm_wifi_p2p_peer_update_from_properties (NMWifiP2PPeer *peer, - const struct _NMSupplicantPeerInfo *peer_info); +gboolean nm_wifi_p2p_peer_update_from_properties(NMWifiP2PPeer * peer, + const struct _NMSupplicantPeerInfo *peer_info); -gboolean nm_wifi_p2p_peer_check_compatible (NMWifiP2PPeer *self, - NMConnection *connection); +gboolean nm_wifi_p2p_peer_check_compatible(NMWifiP2PPeer *self, NMConnection *connection); -const char * nm_wifi_p2p_peer_get_supplicant_path (NMWifiP2PPeer *peer); +const char *nm_wifi_p2p_peer_get_supplicant_path(NMWifiP2PPeer *peer); -const char * nm_wifi_p2p_peer_get_name (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_name (NMWifiP2PPeer *peer, - const char *name); -const char * nm_wifi_p2p_peer_get_manufacturer (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_manufacturer (NMWifiP2PPeer *peer, - const char *manufacturer); -const char * nm_wifi_p2p_peer_get_model (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_model (NMWifiP2PPeer *peer, - const char *model); -const char * nm_wifi_p2p_peer_get_model_number (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_model_number (NMWifiP2PPeer *peer, - const char *number); -const char * nm_wifi_p2p_peer_get_serial (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_serial (NMWifiP2PPeer *peer, - const char *serial); +const char *nm_wifi_p2p_peer_get_name(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_name(NMWifiP2PPeer *peer, const char *name); +const char *nm_wifi_p2p_peer_get_manufacturer(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_manufacturer(NMWifiP2PPeer *peer, const char *manufacturer); +const char *nm_wifi_p2p_peer_get_model(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_model(NMWifiP2PPeer *peer, const char *model); +const char *nm_wifi_p2p_peer_get_model_number(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_model_number(NMWifiP2PPeer *peer, const char *number); +const char *nm_wifi_p2p_peer_get_serial(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_serial(NMWifiP2PPeer *peer, const char *serial); -GBytes * nm_wifi_p2p_peer_get_wfd_ies (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_wfd_ies (NMWifiP2PPeer *peer, - GBytes *bytes); +GBytes * nm_wifi_p2p_peer_get_wfd_ies(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_wfd_ies(NMWifiP2PPeer *peer, GBytes *bytes); -const char *const*nm_wifi_p2p_peer_get_groups (const NMWifiP2PPeer *peer); +const char *const *nm_wifi_p2p_peer_get_groups(const NMWifiP2PPeer *peer); -const char * nm_wifi_p2p_peer_get_address (const NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_address (NMWifiP2PPeer *peer, - const char *addr); -gint8 nm_wifi_p2p_peer_get_strength (NMWifiP2PPeer *peer); -gboolean nm_wifi_p2p_peer_set_strength (NMWifiP2PPeer *peer, - gint8 strength); -NM80211ApFlags nm_wifi_p2p_peer_get_flags (const NMWifiP2PPeer *self); +const char * nm_wifi_p2p_peer_get_address(const NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_address(NMWifiP2PPeer *peer, const char *addr); +gint8 nm_wifi_p2p_peer_get_strength(NMWifiP2PPeer *peer); +gboolean nm_wifi_p2p_peer_set_strength(NMWifiP2PPeer *peer, gint8 strength); +NM80211ApFlags nm_wifi_p2p_peer_get_flags(const NMWifiP2PPeer *self); -const char *nm_wifi_p2p_peer_to_string (const NMWifiP2PPeer *self, - char *str_buf, - gsize buf_len, - gint32 now_s); +const char * +nm_wifi_p2p_peer_to_string(const NMWifiP2PPeer *self, char *str_buf, gsize buf_len, gint32 now_s); -const char **nm_wifi_p2p_peers_get_paths (const CList *peers_lst_head); +const char **nm_wifi_p2p_peers_get_paths(const CList *peers_lst_head); -NMWifiP2PPeer *nm_wifi_p2p_peers_find_first_compatible (const CList *peers_lst_head, - NMConnection *connection); +NMWifiP2PPeer *nm_wifi_p2p_peers_find_first_compatible(const CList * peers_lst_head, + NMConnection *connection); -NMWifiP2PPeer *nm_wifi_p2p_peers_find_by_supplicant_path (const CList *peers_lst_head, const char *path); +NMWifiP2PPeer *nm_wifi_p2p_peers_find_by_supplicant_path(const CList *peers_lst_head, + const char * path); -NMWifiP2PPeer *nm_wifi_p2p_peer_lookup_for_device (NMDevice *device, const char *exported_path); +NMWifiP2PPeer *nm_wifi_p2p_peer_lookup_for_device(NMDevice *device, const char *exported_path); #endif /* __NM_WIFI_P2P_PEER_H__ */ diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index 68538525..e371d197 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -13,846 +13,907 @@ #include "nm-core-internal.h" static gboolean -verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) +verify_no_wep(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) { - if ( nm_setting_wireless_security_get_wep_key (s_wsec, 0) - || nm_setting_wireless_security_get_wep_key (s_wsec, 1) - || nm_setting_wireless_security_get_wep_key (s_wsec, 2) - || nm_setting_wireless_security_get_wep_key (s_wsec, 3) - || nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) - || nm_setting_wireless_security_get_wep_key_type (s_wsec)) { - /* Dynamic WEP cannot have any WEP keys set */ - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("%s is incompatible with static WEP keys"), tag); - g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - return FALSE; - } - - return TRUE; + if (nm_setting_wireless_security_get_wep_key(s_wsec, 0) + || nm_setting_wireless_security_get_wep_key(s_wsec, 1) + || nm_setting_wireless_security_get_wep_key(s_wsec, 2) + || nm_setting_wireless_security_get_wep_key(s_wsec, 3) + || nm_setting_wireless_security_get_wep_tx_keyidx(s_wsec) + || nm_setting_wireless_security_get_wep_key_type(s_wsec)) { + /* Dynamic WEP cannot have any WEP keys set */ + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("%s is incompatible with static WEP keys"), + tag); + g_prefix_error(error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + return TRUE; } static gboolean -verify_leap (NMSettingWirelessSecurity *s_wsec, - NMSetting8021x *s_8021x, - gboolean adhoc, - GError **error) +verify_leap(NMSettingWirelessSecurity *s_wsec, + NMSetting8021x * s_8021x, + gboolean adhoc, + GError ** error) { - const char *key_mgmt, *auth_alg, *leap_username; + const char *key_mgmt, *auth_alg, *leap_username; - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username(s_wsec); - /* One (or both) of two things indicates we want LEAP: - * 1) auth_alg == 'leap' - * 2) valid leap_username + /* One (or both) of two things indicates we want LEAP: + * 1) auth_alg == 'leap' + * 2) valid leap_username * * LEAP always requires a LEAP username. - */ - - if (auth_alg) { - if (!strcmp (auth_alg, "leap")) { - /* LEAP authentication requires at least a LEAP username */ - if (!leap_username) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("LEAP authentication requires a LEAP username")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); - return FALSE; - } - } else if (leap_username) { - /* Leap username requires 'leap' auth */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("LEAP username requires 'leap' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); - return FALSE; - } - } - - if (leap_username) { - if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) { - /* LEAP requires ieee8021x key management */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("LEAP authentication requires IEEE 802.1x key management")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - } - - /* At this point if auth_alg is set it must be 'leap', and if key_mgmt - * is set it must be 'ieee8021x'. - */ - if (leap_username) { - if (auth_alg) - g_assert (strcmp (auth_alg, "leap") == 0); - if (key_mgmt) - g_assert (strcmp (key_mgmt, "ieee8021x") == 0); - - if (adhoc) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("LEAP authentication is incompatible with Ad-Hoc mode")); - g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - return FALSE; - } - - if (!verify_no_wep (s_wsec, "LEAP", error)) - return FALSE; - - if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("LEAP authentication is incompatible with 802.1x setting")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - } - - return TRUE; + */ + + if (auth_alg) { + if (!strcmp(auth_alg, "leap")) { + /* LEAP authentication requires at least a LEAP username */ + if (!leap_username) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("LEAP authentication requires a LEAP username")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + } else if (leap_username) { + /* Leap username requires 'leap' auth */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP username requires 'leap' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + } + + if (leap_username) { + if (key_mgmt && strcmp(key_mgmt, "ieee8021x")) { + /* LEAP requires ieee8021x key management */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP authentication requires IEEE 802.1x key management")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + } + + /* At this point if auth_alg is set it must be 'leap', and if key_mgmt + * is set it must be 'ieee8021x'. + */ + if (leap_username) { + if (auth_alg) + g_assert(strcmp(auth_alg, "leap") == 0); + if (key_mgmt) + g_assert(strcmp(key_mgmt, "ieee8021x") == 0); + + if (adhoc) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with Ad-Hoc mode")); + g_prefix_error(error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + return FALSE; + } + + if (!verify_no_wep(s_wsec, "LEAP", error)) + return FALSE; + + if (s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with 802.1x setting")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + } + + return TRUE; } static gboolean -verify_no_wpa (NMSettingWirelessSecurity *s_wsec, - const char *tag, - GError **error) +verify_no_wpa(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) { - const char *key_mgmt; - int n, i; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("a connection using '%s' authentication cannot use WPA key management"), - tag); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - - if (nm_setting_wireless_security_get_num_protos (s_wsec)) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("a connection using '%s' authentication cannot specify WPA protocols"), - tag); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PROTO); - return FALSE; - } - - n = nm_setting_wireless_security_get_num_pairwise (s_wsec); - for (i = 0; i < n; i++) { - const char *pw; - - pw = nm_setting_wireless_security_get_pairwise (s_wsec, i); - if (!strcmp (pw, "tkip") || !strcmp (pw, "ccmp")) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("a connection using '%s' authentication cannot specify WPA ciphers"), - tag); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PAIRWISE); - return FALSE; - } - } - - n = nm_setting_wireless_security_get_num_groups (s_wsec); - for (i = 0; i < n; i++) { - const char *gr; - - gr = nm_setting_wireless_security_get_group (s_wsec, i); - if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("a connection using '%s' authentication cannot specify WPA ciphers"), - tag); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_GROUP); - return FALSE; - } - } - - if (nm_setting_wireless_security_get_psk (s_wsec)) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("a connection using '%s' authentication cannot specify a WPA password"), - tag); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PSK); - return FALSE; - } - - return TRUE; + const char *key_mgmt; + int n, i; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + if (key_mgmt && !strncmp(key_mgmt, "wpa", 3)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot use WPA key management"), + tag); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (nm_setting_wireless_security_get_num_protos(s_wsec)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specify WPA protocols"), + tag); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + return FALSE; + } + + n = nm_setting_wireless_security_get_num_pairwise(s_wsec); + for (i = 0; i < n; i++) { + const char *pw; + + pw = nm_setting_wireless_security_get_pairwise(s_wsec, i); + if (!strcmp(pw, "tkip") || !strcmp(pw, "ccmp")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specify WPA ciphers"), + tag); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + } + + n = nm_setting_wireless_security_get_num_groups(s_wsec); + for (i = 0; i < n; i++) { + const char *gr; + + gr = nm_setting_wireless_security_get_group(s_wsec, i); + if (strcmp(gr, "wep40") && strcmp(gr, "wep104")) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specify WPA ciphers"), + tag); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + return FALSE; + } + } + + if (nm_setting_wireless_security_get_psk(s_wsec)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specify a WPA password"), + tag); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); + return FALSE; + } + + return TRUE; } static gboolean -verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, - NMSetting8021x *s_8021x, - gboolean adhoc, - GError **error) +verify_dynamic_wep(NMSettingWirelessSecurity *s_wsec, + NMSetting8021x * s_8021x, + gboolean adhoc, + GError ** error) { - const char *key_mgmt, *auth_alg, *leap_username; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); - - g_return_val_if_fail (leap_username == NULL, TRUE); - - if (key_mgmt) { - if (!strcmp (key_mgmt, "ieee8021x")) { - if (!s_8021x) { - /* 802.1x key management requires an 802.1x setting */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_SETTING, - _("Dynamic WEP requires an 802.1x setting")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - - if (auth_alg && strcmp (auth_alg, "open")) { - /* 802.1x key management must use "open" authentication */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Dynamic WEP requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - /* Dynamic WEP incompatible with anything static WEP related */ - if (!verify_no_wep (s_wsec, "Dynamic WEP", error)) - return FALSE; - } else if (!strcmp (key_mgmt, "none")) { - if (s_8021x) { - /* 802.1x setting requires 802.1x key management */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Dynamic WEP requires 'ieee8021x' key management")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - } - } else if (s_8021x) { - /* 802.1x setting incompatible with anything but 'open' auth */ - if (auth_alg && strcmp (auth_alg, "open")) { - /* 802.1x key management must use "open" authentication */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Dynamic WEP requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - /* Dynamic WEP incompatible with anything static WEP related */ - if (!verify_no_wep (s_wsec, "Dynamic WEP", error)) - return FALSE; - } - - return TRUE; + const char *key_mgmt, *auth_alg, *leap_username; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username(s_wsec); + + g_return_val_if_fail(leap_username == NULL, TRUE); + + if (key_mgmt) { + if (!strcmp(key_mgmt, "ieee8021x")) { + if (!s_8021x) { + /* 802.1x key management requires an 802.1x setting */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("Dynamic WEP requires an 802.1x setting")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + + if (auth_alg && strcmp(auth_alg, "open")) { + /* 802.1x key management must use "open" authentication */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + /* Dynamic WEP incompatible with anything static WEP related */ + if (!verify_no_wep(s_wsec, "Dynamic WEP", error)) + return FALSE; + } else if (!strcmp(key_mgmt, "none")) { + if (s_8021x) { + /* 802.1x setting requires 802.1x key management */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'ieee8021x' key management")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + } + } else if (s_8021x) { + /* 802.1x setting incompatible with anything but 'open' auth */ + if (auth_alg && strcmp(auth_alg, "open")) { + /* 802.1x key management must use "open" authentication */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + /* Dynamic WEP incompatible with anything static WEP related */ + if (!verify_no_wep(s_wsec, "Dynamic WEP", error)) + return FALSE; + } + + return TRUE; } static gboolean -verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, - NMSetting8021x *s_8021x, - gboolean adhoc, - guint32 wpa_flags, - guint32 rsn_flags, - GError **error) +verify_wpa_psk(NMSettingWirelessSecurity *s_wsec, + NMSetting8021x * s_8021x, + gboolean adhoc, + guint32 wpa_flags, + guint32 rsn_flags, + GError ** error) { - const char *key_mgmt, *auth_alg; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - - if (!nm_streq0 (key_mgmt, "wpa-psk")) - return TRUE; - - if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("WPA-PSK authentication is incompatible with 802.1x")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - - if (auth_alg && !nm_streq (auth_alg, "open")) { - /* WPA must use "open" authentication */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA-PSK requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - /* Make sure the AP's capabilities support WPA-PSK */ - if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Access point does not support PSK but setting requires it")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - - if (adhoc) { - /* Ad-Hoc RSN requires 'rsn' proto, 'ccmp' pairwise, and 'ccmp' group */ - if ( nm_setting_wireless_security_get_num_protos (s_wsec) != 1 - || !nm_streq0 (nm_setting_wireless_security_get_proto (s_wsec, 0), "rsn")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA Ad-Hoc authentication requires 'rsn' protocol")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PROTO); - return FALSE; - } - - if ( nm_setting_wireless_security_get_num_pairwise (s_wsec) != 1 - || !nm_streq0 (nm_setting_wireless_security_get_pairwise (s_wsec, 0), "ccmp")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA Ad-Hoc authentication requires 'ccmp' pairwise cipher")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_PAIRWISE); - return FALSE; - } - - if ( nm_setting_wireless_security_get_num_groups (s_wsec) != 1 - || !nm_streq0 (nm_setting_wireless_security_get_group (s_wsec, 0), "ccmp")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA Ad-Hoc requires 'ccmp' group cipher")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_GROUP); - return FALSE; - } - } - - return TRUE; + const char *key_mgmt, *auth_alg; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + + if (!nm_streq0(key_mgmt, "wpa-psk")) + return TRUE; + + if (s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA-PSK authentication is incompatible with 802.1x")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + + if (auth_alg && !nm_streq(auth_alg, "open")) { + /* WPA must use "open" authentication */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-PSK requires 'open' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + /* Make sure the AP's capabilities support WPA-PSK */ + if (!(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point does not support PSK but setting requires it")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (adhoc) { + /* Ad-Hoc RSN requires 'rsn' proto, 'ccmp' pairwise, and 'ccmp' group */ + if (nm_setting_wireless_security_get_num_protos(s_wsec) != 1 + || !nm_streq0(nm_setting_wireless_security_get_proto(s_wsec, 0), "rsn")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'rsn' protocol")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); + return FALSE; + } + + if (nm_setting_wireless_security_get_num_pairwise(s_wsec) != 1 + || !nm_streq0(nm_setting_wireless_security_get_pairwise(s_wsec, 0), "ccmp")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'ccmp' pairwise cipher")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + + if (nm_setting_wireless_security_get_num_groups(s_wsec) != 1 + || !nm_streq0(nm_setting_wireless_security_get_group(s_wsec, 0), "ccmp")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc requires 'ccmp' group cipher")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); + return FALSE; + } + } + + return TRUE; } static gboolean -verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, - NMSetting8021x *s_8021x, - guint32 wpa_flags, - guint32 rsn_flags, - GError **error) +verify_wpa_eap(NMSettingWirelessSecurity *s_wsec, + NMSetting8021x * s_8021x, + guint32 wpa_flags, + guint32 rsn_flags, + GError ** error) { - const char *key_mgmt, *auth_alg; - gboolean is_wpa_eap = FALSE; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - - if (key_mgmt) { - if (!strcmp (key_mgmt, "wpa-eap")) { - if (!s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_SETTING, - _("WPA-EAP authentication requires an 802.1x setting")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - - if (auth_alg && strcmp (auth_alg, "open")) { - /* WPA must use "open" authentication */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA-EAP requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - is_wpa_eap = TRUE; - } else if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("802.1x setting requires 'wpa-eap' key management")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - } - - if (is_wpa_eap || s_8021x) { - /* Make sure the AP's capabilities support WPA-EAP */ - if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) - && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("Access point does not support 802.1x but setting requires it")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - } - - return TRUE; + const char *key_mgmt, *auth_alg; + gboolean is_wpa_eap = FALSE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + + if (key_mgmt) { + if (!strcmp(key_mgmt, "wpa-eap")) { + if (!s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("WPA-EAP authentication requires an 802.1x setting")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + + if (auth_alg && strcmp(auth_alg, "open")) { + /* WPA must use "open" authentication */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-EAP requires 'open' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + is_wpa_eap = TRUE; + } else if (s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("802.1x setting requires 'wpa-eap' key management")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + } + + if (is_wpa_eap || s_8021x) { + /* Make sure the AP's capabilities support WPA-EAP */ + if (!(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point does not support 802.1x but setting requires it")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + } + + return TRUE; } static gboolean -verify_adhoc (NMSettingWirelessSecurity *s_wsec, - NMSetting8021x *s_8021x, - gboolean adhoc, - GError **error) +verify_adhoc(NMSettingWirelessSecurity *s_wsec, + NMSetting8021x * s_8021x, + gboolean adhoc, + GError ** error) { - const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL; - - if (!adhoc) - return TRUE; - - if (s_wsec) { - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); - } - - if (key_mgmt && !NM_IN_STRSET (key_mgmt, "none", "wpa-psk")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Ad-Hoc mode requires 'none' or 'wpa-psk' key management")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - - if (s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("Ad-Hoc mode is incompatible with 802.1x security")); - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - - if (leap_username) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Ad-Hoc mode is incompatible with LEAP security")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - if (auth_alg && !nm_streq (auth_alg, "open")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("Ad-Hoc mode requires 'open' authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - return TRUE; + const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL; + + if (!adhoc) + return TRUE; + + if (s_wsec) { + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username(s_wsec); + } + + if (key_mgmt && !NM_IN_STRSET(key_mgmt, "none", "wpa-psk")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'none' or 'wpa-psk' key management")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Ad-Hoc mode is incompatible with 802.1x security")); + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + + if (leap_username) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode is incompatible with LEAP security")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + if (auth_alg && !nm_streq(auth_alg, "open")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'open' authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + return TRUE; } gboolean -nm_wifi_utils_complete_connection (GBytes *ap_ssid, - const char *bssid, - NM80211Mode ap_mode, - guint32 ap_freq, - guint32 ap_flags, - guint32 ap_wpa_flags, - guint32 ap_rsn_flags, - NMConnection *connection, - gboolean lock_bssid, - GError **error) +nm_wifi_utils_complete_connection(GBytes * ap_ssid, + const char * bssid, + NM80211Mode ap_mode, + guint32 ap_freq, + guint32 ap_flags, + guint32 ap_wpa_flags, + guint32 ap_rsn_flags, + NMConnection *connection, + gboolean lock_bssid, + GError ** error) { - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; - GBytes *ssid; - const char *mode, *key_mgmt, *auth_alg, *leap_username; - gboolean adhoc = FALSE; - gboolean mesh = FALSE; - - s_wifi = nm_connection_get_setting_wireless (connection); - g_assert (s_wifi); - s_wsec = nm_connection_get_setting_wireless_security (connection); - s_8021x = nm_connection_get_setting_802_1x (connection); - - /* Fill in missing SSID */ - ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!ssid) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); - else if (!ap_ssid || !g_bytes_equal (ssid, ap_ssid)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("connection does not match access point")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - return FALSE; - } - - if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - - /* And mode */ - mode = nm_setting_wireless_get_mode (s_wifi); - if (mode) { - gboolean valid = FALSE; - - /* Make sure the supplied mode matches the AP's */ - if ( !strcmp (mode, NM_SETTING_WIRELESS_MODE_INFRA) - || !strcmp (mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (ap_mode == NM_802_11_MODE_INFRA) - valid = TRUE; - } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - if (ap_mode == NM_802_11_MODE_ADHOC) - valid = TRUE; - adhoc = TRUE; - } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_MESH)) { - if (ap_mode == NM_802_11_MODE_MESH) - valid = TRUE; - mesh = TRUE; - } - - if (valid == FALSE) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("connection does not match access point")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); - return FALSE; - } - } else { - mode = NM_SETTING_WIRELESS_MODE_INFRA; - if (ap_mode == NM_802_11_MODE_ADHOC) { - mode = NM_SETTING_WIRELESS_MODE_ADHOC; - adhoc = TRUE; - } else if (ap_mode == NM_802_11_MODE_MESH) { - mode = NM_SETTING_WIRELESS_MODE_MESH; - mesh = TRUE; - } - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL); - } - - /* For now mesh requires channel and band, fill them only if both not present. - * Do not check existing values against an existing ap/mesh point, - * mesh join will start a new network if required */ - if (mesh) { - const char *band; - guint32 channel; - gboolean band_valid = TRUE; - gboolean chan_valid = TRUE; - gboolean valid; - - band = nm_setting_wireless_get_band (s_wifi); - channel = nm_setting_wireless_get_channel (s_wifi); - - valid = ((band == NULL) && (channel == 0)) - || ((band != NULL) && (channel != 0)); - - if ((band == NULL) && (channel == 0)) { - channel = nm_utils_wifi_freq_to_channel (ap_freq); - if (channel) { - g_object_set (s_wifi, - NM_SETTING_WIRELESS_CHANNEL, channel, - NULL); - } else { - chan_valid = FALSE; - } - - band = nm_utils_wifi_freq_to_band (ap_freq); - if (band) { - g_object_set (s_wifi, NM_SETTING_WIRELESS_BAND, band, NULL); - } else { - band_valid = FALSE; - } - } - - if (!valid || !chan_valid || !band_valid) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("connection does not match mesh point")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); - return FALSE; - } - } - - /* Security */ - - /* Open */ - if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) - && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) - && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { - /* Make sure the connection doesn't specify security */ - if (s_wsec || s_8021x) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_SETTING, - _("Access point is unencrypted but setting specifies security")); - if (s_wsec) - g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); - else - g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); - return FALSE; - } - return TRUE; - } - - /* Everything else requires security */ - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); - auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); - leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); - - /* Ad-Hoc checks */ - if (!verify_adhoc (s_wsec, s_8021x, adhoc, error)) - return FALSE; - - /* Static WEP, Dynamic WEP, or LEAP */ - if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) - && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) - && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { - const char *tag = "WEP"; - gboolean is_dynamic_wep = FALSE; - - if (!verify_leap (s_wsec, s_8021x, adhoc, error)) - return FALSE; - - if (leap_username) { - tag = "LEAP"; - } else { - /* Static or Dynamic WEP */ - if (!verify_dynamic_wep (s_wsec, s_8021x, adhoc, error)) - return FALSE; - - if (s_8021x || (key_mgmt && !strcmp (key_mgmt, "ieee8021x"))) { - is_dynamic_wep = TRUE; - tag = "Dynamic WEP"; - } - } - - /* Nothing WPA-related can be set */ - if (!verify_no_wpa (s_wsec, tag, error)) - return FALSE; - - if (leap_username) { - /* LEAP */ - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", - NULL); - } else if (is_dynamic_wep) { - /* Dynamic WEP */ - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - - if (s_8021x) { - /* Dynamic WEP requires a valid 802.1x setting since we can't - * autocomplete 802.1x. - */ - if (!nm_setting_verify (NM_SETTING (s_8021x), NULL, error)) - return FALSE; - } - } else { - /* Static WEP */ - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", - NULL); - } - - return TRUE; - } - - /* WPA/RSN */ - g_assert (ap_wpa_flags || ap_rsn_flags); - - /* Ensure key management is valid for WPA */ - if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic WEP")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); - return FALSE; - } - - /* 'shared' auth incompatible with any type of WPA */ - if (auth_alg && strcmp (auth_alg, "open")) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("WPA authentication is incompatible with Shared Key authentication")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); - return FALSE; - } - - if (!verify_no_wep (s_wsec, "WPA", error)) - return FALSE; - - if (!verify_wpa_psk (s_wsec, s_8021x, adhoc, ap_wpa_flags, ap_rsn_flags, error)) - return FALSE; - - if (!adhoc && !verify_wpa_eap (s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error)) - return FALSE; - - if (adhoc) { - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - nm_setting_wireless_security_add_proto (s_wsec, "rsn"); - nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp"); - nm_setting_wireless_security_add_group (s_wsec, "ccmp"); - } else if (s_8021x) { - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - /* Leave proto/pairwise/group as client set them; if they are unset the - * supplicant will figure out the best combination at connect time. - */ - - /* 802.1x also requires the client to completely fill in the 8021x - * setting. Since there's so much configuration required for it, there's - * no way it can be automatically completed. - */ - } else if ( (key_mgmt && !strcmp (key_mgmt, "sae")) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - } else if ( (key_mgmt && !strcmp (key_mgmt, "owe")) - || NM_FLAGS_ANY (ap_rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | - NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "owe", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - } else if ( (key_mgmt && !strcmp (key_mgmt, "wpa-psk")) - || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { - g_object_set (s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NULL); - /* Leave proto/pairwise/group as client set them; if they are unset the - * supplicant will figure out the best combination at connect time. - */ - } else { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_FAILED, - _("Failed to determine AP security information")); - return FALSE; - } - - return TRUE; + NMSettingWireless * s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x * s_8021x; + GBytes * ssid; + const char * mode, *key_mgmt, *auth_alg, *leap_username; + gboolean adhoc = FALSE; + gboolean mesh = FALSE; + + s_wifi = nm_connection_get_setting_wireless(connection); + g_assert(s_wifi); + s_wsec = nm_connection_get_setting_wireless_security(connection); + s_8021x = nm_connection_get_setting_802_1x(connection); + + /* Fill in missing SSID */ + ssid = nm_setting_wireless_get_ssid(s_wifi); + if (!ssid) + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); + else if (!ap_ssid || !g_bytes_equal(ssid, ap_ssid)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + if (lock_bssid && !nm_setting_wireless_get_bssid(s_wifi)) + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); + + /* And mode */ + mode = nm_setting_wireless_get_mode(s_wifi); + if (mode) { + gboolean valid = FALSE; + + /* Make sure the supplied mode matches the AP's */ + if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_INFRA) + || !strcmp(mode, NM_SETTING_WIRELESS_MODE_AP)) { + if (ap_mode == NM_802_11_MODE_INFRA) + valid = TRUE; + } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { + if (ap_mode == NM_802_11_MODE_ADHOC) + valid = TRUE; + adhoc = TRUE; + } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_MESH)) { + if (ap_mode == NM_802_11_MODE_MESH) + valid = TRUE; + mesh = TRUE; + } + + if (valid == FALSE) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + return FALSE; + } + } else { + mode = NM_SETTING_WIRELESS_MODE_INFRA; + if (ap_mode == NM_802_11_MODE_ADHOC) { + mode = NM_SETTING_WIRELESS_MODE_ADHOC; + adhoc = TRUE; + } else if (ap_mode == NM_802_11_MODE_MESH) { + mode = NM_SETTING_WIRELESS_MODE_MESH; + mesh = TRUE; + } + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL); + } + + /* For now mesh requires channel and band, fill them only if both not present. + * Do not check existing values against an existing ap/mesh point, + * mesh join will start a new network if required */ + if (mesh) { + const char *band; + guint32 channel; + gboolean band_valid = TRUE; + gboolean chan_valid = TRUE; + gboolean valid; + + band = nm_setting_wireless_get_band(s_wifi); + channel = nm_setting_wireless_get_channel(s_wifi); + + valid = ((band == NULL) && (channel == 0)) || ((band != NULL) && (channel != 0)); + + if ((band == NULL) && (channel == 0)) { + channel = nm_utils_wifi_freq_to_channel(ap_freq); + if (channel) { + g_object_set(s_wifi, NM_SETTING_WIRELESS_CHANNEL, channel, NULL); + } else { + chan_valid = FALSE; + } + + band = nm_utils_wifi_freq_to_band(ap_freq); + if (band) { + g_object_set(s_wifi, NM_SETTING_WIRELESS_BAND, band, NULL); + } else { + band_valid = FALSE; + } + } + + if (!valid || !chan_valid || !band_valid) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match mesh point")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); + return FALSE; + } + } + + /* Security */ + + /* Open */ + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) + && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { + /* Make sure the connection doesn't specify security */ + if (s_wsec || s_8021x) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point is unencrypted but setting specifies security")); + if (s_wsec) + g_prefix_error(error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + else + g_prefix_error(error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + return TRUE; + } + + /* Everything else requires security */ + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username(s_wsec); + + /* Ad-Hoc checks */ + if (!verify_adhoc(s_wsec, s_8021x, adhoc, error)) + return FALSE; + + /* Static WEP, Dynamic WEP, or LEAP */ + if ((ap_flags & NM_802_11_AP_FLAGS_PRIVACY) && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) + && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { + const char *tag = "WEP"; + gboolean is_dynamic_wep = FALSE; + + if (!verify_leap(s_wsec, s_8021x, adhoc, error)) + return FALSE; + + if (leap_username) { + tag = "LEAP"; + } else { + /* Static or Dynamic WEP */ + if (!verify_dynamic_wep(s_wsec, s_8021x, adhoc, error)) + return FALSE; + + if (s_8021x || (key_mgmt && !strcmp(key_mgmt, "ieee8021x"))) { + is_dynamic_wep = TRUE; + tag = "Dynamic WEP"; + } + } + + /* Nothing WPA-related can be set */ + if (!verify_no_wpa(s_wsec, tag, error)) + return FALSE; + + if (leap_username) { + /* LEAP */ + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "leap", + NULL); + } else if (is_dynamic_wep) { + /* Dynamic WEP */ + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + + if (s_8021x) { + /* Dynamic WEP requires a valid 802.1x setting since we can't + * autocomplete 802.1x. + */ + if (!nm_setting_verify(NM_SETTING(s_8021x), NULL, error)) + return FALSE; + } + } else { + /* Static WEP */ + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); + } + + return TRUE; + } + + /* WPA/RSN */ + g_assert(ap_wpa_flags || ap_rsn_flags); + + /* Ensure key management is valid for WPA */ + if ((key_mgmt && !strcmp(key_mgmt, "ieee8021x")) || leap_username) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic WEP")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + /* 'shared' auth incompatible with any type of WPA */ + if (auth_alg && strcmp(auth_alg, "open")) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with Shared Key authentication")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + if (!verify_no_wep(s_wsec, "WPA", error)) + return FALSE; + + if (!verify_wpa_psk(s_wsec, s_8021x, adhoc, ap_wpa_flags, ap_rsn_flags, error)) + return FALSE; + + if (!adhoc && !verify_wpa_eap(s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error)) + return FALSE; + + if (adhoc) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + nm_setting_wireless_security_add_proto(s_wsec, "rsn"); + nm_setting_wireless_security_add_pairwise(s_wsec, "ccmp"); + nm_setting_wireless_security_add_group(s_wsec, "ccmp"); + } else if (s_8021x) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-eap", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + /* Leave proto/pairwise/group as client set them; if they are unset the + * supplicant will figure out the best combination at connect time. + */ + + /* 802.1x also requires the client to completely fill in the 8021x + * setting. Since there's so much configuration required for it, there's + * no way it can be automatically completed. + */ + } else if ((key_mgmt && !strcmp(key_mgmt, "sae")) + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "sae", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + } else if ((key_mgmt && !strcmp(key_mgmt, "owe")) + || NM_FLAGS_ANY(ap_rsn_flags, + NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "owe", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-psk")) + || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + /* Leave proto/pairwise/group as client set them; if they are unset the + * supplicant will figure out the best combination at connect time. + */ + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Failed to determine AP security information")); + return FALSE; + } + + return TRUE; } gboolean -nm_wifi_utils_is_manf_default_ssid (GBytes *ssid) +nm_wifi_utils_is_manf_default_ssid(GBytes *ssid) { - const guint8 *ssid_p; - gsize ssid_l; - int i; - /* - * List of manufacturer default SSIDs that are often unchanged by users. - * - * NOTE: this list should *not* contain networks that you would like to - * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot". - */ - static const char *manf_defaults[] = { - "linksys", - "linksys-a", - "linksys-g", - "default", - "belkin54g", - "NETGEAR", - "o2DSL", - "WLAN", - "ALICE-WLAN", - "Speedport W 501V", - "TURBONETT", - }; - - ssid_p = g_bytes_get_data (ssid, &ssid_l); - - for (i = 0; i < G_N_ELEMENTS (manf_defaults); i++) { - if (ssid_l == strlen (manf_defaults[i])) { - if (memcmp (manf_defaults[i], ssid_p, ssid_l) == 0) - return TRUE; - } - } - return FALSE; + const guint8 *ssid_p; + gsize ssid_l; + int i; + /* + * List of manufacturer default SSIDs that are often unchanged by users. + * + * NOTE: this list should *not* contain networks that you would like to + * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot". + */ + static const char *manf_defaults[] = { + "linksys", + "linksys-a", + "linksys-g", + "default", + "belkin54g", + "NETGEAR", + "o2DSL", + "WLAN", + "ALICE-WLAN", + "Speedport W 501V", + "TURBONETT", + }; + + ssid_p = g_bytes_get_data(ssid, &ssid_l); + + for (i = 0; i < G_N_ELEMENTS(manf_defaults); i++) { + if (ssid_l == strlen(manf_defaults[i])) { + if (memcmp(manf_defaults[i], ssid_p, ssid_l) == 0) + return TRUE; + } + } + return FALSE; } NMIwdNetworkSecurity -nm_wifi_connection_get_iwd_security (NMConnection *connection, - gboolean *mapped) +nm_wifi_connection_get_iwd_security(NMConnection *connection, gboolean *mapped) { - NMSettingWirelessSecurity *s_wireless_sec; - const char *key_mgmt = NULL; + NMSettingWirelessSecurity *s_wireless_sec; + const char * key_mgmt = NULL; - if (!nm_connection_get_setting_wireless (connection)) - goto error; + if (!nm_connection_get_setting_wireless(connection)) + goto error; - NM_SET_OUT (mapped, TRUE); + NM_SET_OUT(mapped, TRUE); - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - if (!s_wireless_sec) - return NM_IWD_NETWORK_SECURITY_NONE; + s_wireless_sec = nm_connection_get_setting_wireless_security(connection); + if (!s_wireless_sec) + return NM_IWD_NETWORK_SECURITY_NONE; - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); - nm_assert (key_mgmt); + key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wireless_sec); + nm_assert(key_mgmt); - if (NM_IN_STRSET (key_mgmt, "none", "ieee8021x")) - return NM_IWD_NETWORK_SECURITY_WEP; + if (NM_IN_STRSET(key_mgmt, "none", "ieee8021x")) + return NM_IWD_NETWORK_SECURITY_WEP; - if (nm_streq (key_mgmt, "wpa-psk")) - return NM_IWD_NETWORK_SECURITY_PSK; + if (nm_streq(key_mgmt, "wpa-psk")) + return NM_IWD_NETWORK_SECURITY_PSK; - if (nm_streq (key_mgmt, "wpa-eap")) - return NM_IWD_NETWORK_SECURITY_8021X; + if (nm_streq(key_mgmt, "wpa-eap")) + return NM_IWD_NETWORK_SECURITY_8021X; error: - NM_SET_OUT (mapped, FALSE); - return NM_IWD_NETWORK_SECURITY_NONE; + NM_SET_OUT(mapped, FALSE); + return NM_IWD_NETWORK_SECURITY_NONE; } diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h index 505baa84..678b353b 100644 --- a/src/devices/wifi/nm-wifi-utils.h +++ b/src/devices/wifi/nm-wifi-utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -13,26 +13,26 @@ #include "nm-setting-8021x.h" typedef enum { - NM_IWD_NETWORK_SECURITY_NONE, - NM_IWD_NETWORK_SECURITY_WEP, - NM_IWD_NETWORK_SECURITY_PSK, - NM_IWD_NETWORK_SECURITY_8021X, + NM_IWD_NETWORK_SECURITY_NONE, + NM_IWD_NETWORK_SECURITY_WEP, + NM_IWD_NETWORK_SECURITY_PSK, + NM_IWD_NETWORK_SECURITY_8021X, } NMIwdNetworkSecurity; -gboolean nm_wifi_utils_complete_connection (GBytes *ssid, - const char *bssid, - NM80211Mode mode, - guint32 ap_freq, - guint32 flags, - guint32 wpa_flags, - guint32 rsn_flags, - NMConnection *connection, - gboolean lock_bssid, - GError **error); +gboolean nm_wifi_utils_complete_connection(GBytes * ssid, + const char * bssid, + NM80211Mode mode, + guint32 ap_freq, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + NMConnection *connection, + gboolean lock_bssid, + GError ** error); -gboolean nm_wifi_utils_is_manf_default_ssid (GBytes *ssid); +gboolean nm_wifi_utils_is_manf_default_ssid(GBytes *ssid); -NMIwdNetworkSecurity nm_wifi_connection_get_iwd_security (NMConnection *connection, - gboolean *mapped); +NMIwdNetworkSecurity nm_wifi_connection_get_iwd_security(NMConnection *connection, + gboolean * mapped); -#endif /* __NM_WIFI_UTILS_H__ */ +#endif /* __NM_WIFI_UTILS_H__ */ diff --git a/src/devices/wifi/tests/test-devices-wifi.c b/src/devices/wifi/tests/test-devices-wifi.c index bde36307..7be55860 100644 --- a/src/devices/wifi/tests/test-devices-wifi.c +++ b/src/devices/wifi/tests/test-devices-wifi.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -15,1548 +15,1595 @@ /*****************************************************************************/ -#define COMPARE(src, expected, success, error, edomain, ecode) \ -{ \ - if (expected) { \ - if (!success) { \ - g_assert (error != NULL); \ - g_warning ("Failed to complete connection: %s", error->message); \ - } \ - g_assert (success == TRUE); \ - g_assert (error == NULL); \ -\ - success = nm_connection_compare (src, expected, NM_SETTING_COMPARE_FLAG_EXACT); \ - if (success == FALSE && DEBUG) { \ - g_print ("\n- COMPLETED ---------------------------------\n"); \ - nm_connection_dump (src); \ - g_print ("+ EXPECTED ++++++++++++++++++++++++++++++++++++\n"); \ - nm_connection_dump (expected); \ - g_print ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); \ - } \ - g_assert (success == TRUE); \ - } else { \ - if (success) { \ - g_print ("\n- COMPLETED ---------------------------------\n"); \ - nm_connection_dump (src); \ - } \ - g_assert (success == FALSE); \ - g_assert_error (error, edomain, ecode); \ - } \ - \ - g_clear_error (&error); \ -} +#define COMPARE(src, expected, success, error, edomain, ecode) \ + { \ + if (expected) { \ + if (!success) { \ + g_assert(error != NULL); \ + g_warning("Failed to complete connection: %s", error->message); \ + } \ + g_assert(success == TRUE); \ + g_assert(error == NULL); \ + \ + success = nm_connection_compare(src, expected, NM_SETTING_COMPARE_FLAG_EXACT); \ + if (success == FALSE && DEBUG) { \ + g_print("\n- COMPLETED ---------------------------------\n"); \ + nm_connection_dump(src); \ + g_print("+ EXPECTED ++++++++++++++++++++++++++++++++++++\n"); \ + nm_connection_dump(expected); \ + g_print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); \ + } \ + g_assert(success == TRUE); \ + } else { \ + if (success) { \ + g_print("\n- COMPLETED ---------------------------------\n"); \ + nm_connection_dump(src); \ + } \ + g_assert(success == FALSE); \ + g_assert_error(error, edomain, ecode); \ + } \ + \ + g_clear_error(&error); \ + } static gboolean -complete_connection (const char *ssid, - const char *bssid, - NM80211Mode mode, - guint32 flags, - guint32 wpa_flags, - guint32 rsn_flags, - gboolean lock_bssid, - NMConnection *src, - GError **error) +complete_connection(const char * ssid, + const char * bssid, + NM80211Mode mode, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean lock_bssid, + NMConnection *src, + GError ** error) { - gs_unref_bytes GBytes *ssid_b = NULL; - NMSettingWireless *s_wifi; - - /* Add a wifi setting if one doesn't exist */ - s_wifi = nm_connection_get_setting_wireless (src); - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (src, NM_SETTING (s_wifi)); - } - - ssid_b = g_bytes_new (ssid, strlen (ssid)); - - return nm_wifi_utils_complete_connection (ssid_b, - bssid, - mode, - 0, - flags, - wpa_flags, - rsn_flags, - src, - lock_bssid, - error); + gs_unref_bytes GBytes *ssid_b = NULL; + NMSettingWireless * s_wifi; + + /* Add a wifi setting if one doesn't exist */ + s_wifi = nm_connection_get_setting_wireless(src); + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(src, NM_SETTING(s_wifi)); + } + + ssid_b = g_bytes_new(ssid, strlen(ssid)); + + return nm_wifi_utils_complete_connection(ssid_b, + bssid, + mode, + 0, + flags, + wpa_flags, + rsn_flags, + src, + lock_bssid, + error); } typedef struct { - const char *key; - const char *str; - guint32 uint; + const char *key; + const char *str; + guint32 uint; } KeyData; static void -set_items (NMSetting *setting, const KeyData *items) +set_items(NMSetting *setting, const KeyData *items) { - const KeyData *item; - GParamSpec *pspec; - GBytes *tmp; - - for (item = items; item && item->key; item++) { - g_assert (item->key); - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), item->key); - g_assert (pspec); - - if (pspec->value_type == G_TYPE_STRING) { - g_assert (item->uint == 0); - if (item->str) - g_object_set (G_OBJECT (setting), item->key, item->str, NULL); - } else if (pspec->value_type == G_TYPE_UINT) { - g_assert (item->str == NULL); - g_object_set (G_OBJECT (setting), item->key, item->uint, NULL); - } else if (pspec->value_type == G_TYPE_INT) { - int foo = (int) item->uint; - - g_assert (item->str == NULL); - g_object_set (G_OBJECT (setting), item->key, foo, NULL); - } else if (pspec->value_type == G_TYPE_BOOLEAN) { - gboolean foo = !! (item->uint); - - g_assert (item->str == NULL); - g_object_set (G_OBJECT (setting), item->key, foo, NULL); - } else if (pspec->value_type == G_TYPE_BYTES) { - g_assert (item->str); - tmp = g_bytes_new (item->str, strlen (item->str)); - g_object_set (G_OBJECT (setting), item->key, tmp, NULL); - g_bytes_unref (tmp); - } else { - /* Special types, check based on property name */ - if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) - nm_setting_wireless_security_add_proto (NM_SETTING_WIRELESS_SECURITY (setting), item->str); - else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PAIRWISE)) - nm_setting_wireless_security_add_pairwise (NM_SETTING_WIRELESS_SECURITY (setting), item->str); - else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_GROUP)) - nm_setting_wireless_security_add_group (NM_SETTING_WIRELESS_SECURITY (setting), item->str); - else if (!strcmp (item->key, NM_SETTING_802_1X_EAP)) - nm_setting_802_1x_add_eap_method (NM_SETTING_802_1X (setting), item->str); - } - } + const KeyData *item; + GParamSpec * pspec; + GBytes * tmp; + + for (item = items; item && item->key; item++) { + g_assert(item->key); + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(setting), item->key); + g_assert(pspec); + + if (pspec->value_type == G_TYPE_STRING) { + g_assert(item->uint == 0); + if (item->str) + g_object_set(G_OBJECT(setting), item->key, item->str, NULL); + } else if (pspec->value_type == G_TYPE_UINT) { + g_assert(item->str == NULL); + g_object_set(G_OBJECT(setting), item->key, item->uint, NULL); + } else if (pspec->value_type == G_TYPE_INT) { + int foo = (int) item->uint; + + g_assert(item->str == NULL); + g_object_set(G_OBJECT(setting), item->key, foo, NULL); + } else if (pspec->value_type == G_TYPE_BOOLEAN) { + gboolean foo = !!(item->uint); + + g_assert(item->str == NULL); + g_object_set(G_OBJECT(setting), item->key, foo, NULL); + } else if (pspec->value_type == G_TYPE_BYTES) { + g_assert(item->str); + tmp = g_bytes_new(item->str, strlen(item->str)); + g_object_set(G_OBJECT(setting), item->key, tmp, NULL); + g_bytes_unref(tmp); + } else { + /* Special types, check based on property name */ + if (!strcmp(item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) + nm_setting_wireless_security_add_proto(NM_SETTING_WIRELESS_SECURITY(setting), + item->str); + else if (!strcmp(item->key, NM_SETTING_WIRELESS_SECURITY_PAIRWISE)) + nm_setting_wireless_security_add_pairwise(NM_SETTING_WIRELESS_SECURITY(setting), + item->str); + else if (!strcmp(item->key, NM_SETTING_WIRELESS_SECURITY_GROUP)) + nm_setting_wireless_security_add_group(NM_SETTING_WIRELESS_SECURITY(setting), + item->str); + else if (!strcmp(item->key, NM_SETTING_802_1X_EAP)) + nm_setting_802_1x_add_eap_method(NM_SETTING_802_1X(setting), item->str); + } + } } static NMSettingWireless * -fill_wifi_empty (NMConnection *connection) +fill_wifi_empty(NMConnection *connection) { - NMSettingWireless *s_wifi; - - s_wifi = nm_connection_get_setting_wireless (connection); - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - } - return s_wifi; + NMSettingWireless *s_wifi; + + s_wifi = nm_connection_get_setting_wireless(connection); + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + } + return s_wifi; } static NMSettingWireless * -fill_wifi (NMConnection *connection, const KeyData items[]) +fill_wifi(NMConnection *connection, const KeyData items[]) { - NMSettingWireless *s_wifi; + NMSettingWireless *s_wifi; - s_wifi = nm_connection_get_setting_wireless (connection); - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - } + s_wifi = nm_connection_get_setting_wireless(connection); + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); + } - set_items (NM_SETTING (s_wifi), items); - return s_wifi; + set_items(NM_SETTING(s_wifi), items); + return s_wifi; } static NMSettingWirelessSecurity * -fill_wsec (NMConnection *connection, const KeyData items[]) +fill_wsec(NMConnection *connection, const KeyData items[]) { - NMSettingWirelessSecurity *s_wsec; + NMSettingWirelessSecurity *s_wsec; - s_wsec = nm_connection_get_setting_wireless_security (connection); - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } + s_wsec = nm_connection_get_setting_wireless_security(connection); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wsec)); + } - set_items (NM_SETTING (s_wsec), items); - return s_wsec; + set_items(NM_SETTING(s_wsec), items); + return s_wsec; } static NMSetting8021x * -fill_8021x (NMConnection *connection, const KeyData items[]) +fill_8021x(NMConnection *connection, const KeyData items[]) { - NMSetting8021x *s_8021x; + NMSetting8021x *s_8021x; - s_8021x = nm_connection_get_setting_802_1x (connection); - if (!s_8021x) { - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - } + s_8021x = nm_connection_get_setting_802_1x(connection); + if (!s_8021x) { + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new(); + nm_connection_add_setting(connection, NM_SETTING(s_8021x)); + } - set_items (NM_SETTING (s_8021x), items); - return s_8021x; + set_items(NM_SETTING(s_8021x), items); + return s_8021x; } static NMConnection * -create_basic (const char *ssid, - const char *bssid, - NM80211Mode mode) +create_basic(const char *ssid, const char *bssid, NM80211Mode mode) { - NMConnection *connection; - NMSettingWireless *s_wifi = NULL; - GBytes *tmp; + NMConnection * connection; + NMSettingWireless *s_wifi = NULL; + GBytes * tmp; - connection = nm_simple_connection_new (); + connection = nm_simple_connection_new(); - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); + nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - /* SSID */ - tmp = g_bytes_new (ssid, strlen (ssid)); - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL); - g_bytes_unref (tmp); + /* SSID */ + tmp = g_bytes_new(ssid, strlen(ssid)); + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL); + g_bytes_unref(tmp); - /* BSSID */ - if (bssid) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); + /* BSSID */ + if (bssid) + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - if (mode == NM_802_11_MODE_INFRA) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - else if (mode == NM_802_11_MODE_ADHOC) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL); - else - g_assert_not_reached (); + if (mode == NM_802_11_MODE_INFRA) + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); + else if (mode == NM_802_11_MODE_ADHOC) + g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL); + else + g_assert_not_reached(); - return connection; + return connection; } /*****************************************************************************/ static void -test_lock_bssid (void) +test_lock_bssid(void) { - NMConnection *src, *expected; - const char *bssid = "01:02:03:04:05:06"; - const char *ssid = "blahblah"; - gboolean success; - GError *error = NULL; - - src = nm_simple_connection_new (); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE, - src, &error); - expected = create_basic (ssid, bssid, NM_802_11_MODE_INFRA); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * bssid = "01:02:03:04:05:06"; + const char * ssid = "blahblah"; + gboolean success; + GError * error = NULL; + + src = nm_simple_connection_new(); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, + src, + &error); + expected = create_basic(ssid, bssid, NM_802_11_MODE_INFRA); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_open_ap_empty_connection (void) +test_open_ap_empty_connection(void) { - NMConnection *src, *expected; - const char *bssid = "01:02:03:04:05:06"; - const char *ssid = "blahblah"; - gboolean success; - GError *error = NULL; - - /* Test that an empty source connection is correctly filled with the - * SSID and Infra modes of the given AP details. - */ - - src = nm_simple_connection_new (); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * bssid = "01:02:03:04:05:06"; + const char * ssid = "blahblah"; + gboolean success; + GError * error = NULL; + + /* Test that an empty source connection is correctly filled with the + * SSID and Infra modes of the given AP details. + */ + + src = nm_simple_connection_new(); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_open_ap_leap_connection_1 (gconstpointer add_wifi) +test_open_ap_leap_connection_1(gconstpointer add_wifi) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0 }, { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that a basic connection filled with a LEAP username is - * rejected when completion is attempted with an open AP. LEAP requires - * the AP to have the Privacy bit set. - */ - - src = nm_simple_connection_new (); - if (add_wifi) - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* We expect failure */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that a basic connection filled with a LEAP username is + * rejected when completion is attempted with an open AP. LEAP requires + * the AP to have the Privacy bit set. + */ + + src = nm_simple_connection_new(); + if (add_wifi) + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* We expect failure */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + + g_object_unref(src); } /*****************************************************************************/ static void -test_open_ap_leap_connection_2 (void) +test_open_ap_leap_connection_2(void) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that a basic connection specifying IEEE8021x security (ie, Dynamic - * WEP or LEAP) is rejected when completion is attempted with an open AP. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* We expect failure */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that a basic connection specifying IEEE8021x security (ie, Dynamic + * WEP or LEAP) is rejected when completion is attempted with an open AP. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* We expect failure */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + + g_object_unref(src); } /*****************************************************************************/ static void -test_open_ap_wep_connection (gconstpointer add_wifi) +test_open_ap_wep_connection(gconstpointer add_wifi) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0 }, - { NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that a static WEP connection is rejected when completion is - * attempted with an open AP. - */ - - src = nm_simple_connection_new (); - if (add_wifi) - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* We expect failure */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = { + {NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0}, + {NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that a static WEP connection is rejected when completion is + * attempted with an open AP. + */ + + src = nm_simple_connection_new(); + if (add_wifi) + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* We expect failure */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + + g_object_unref(src); } /*****************************************************************************/ static void -test_ap_wpa_psk_connection_base (const char *key_mgmt, - const char *auth_alg, - guint32 flags, - guint32 wpa_flags, - guint32 rsn_flags, - gboolean add_wifi, - guint error_code, - NMConnection *expected) +test_ap_wpa_psk_connection_base(const char * key_mgmt, + const char * auth_alg, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean add_wifi, + guint error_code, + NMConnection *expected) { - NMConnection *src; - const char *ssid = "blahblah"; - const char *bssid = "01:02:03:04:05:06"; - const KeyData exp_wifi[] = { - { NM_SETTING_WIRELESS_SSID, ssid, 0 }, - { NM_SETTING_WIRELESS_MODE, "infrastructure", 0 }, - { NULL } }; - const KeyData both_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 }, - { NM_SETTING_WIRELESS_SECURITY_PSK, "asdfasdfasdfasdfasdfafs", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - src = nm_simple_connection_new (); - if (add_wifi) - fill_wifi_empty (src); - fill_wsec (src, both_wsec); - success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, - flags, wpa_flags, rsn_flags, - FALSE, src, &error); - if (expected) { - fill_wifi (expected, exp_wifi); - fill_wsec (expected, both_wsec); - } - COMPARE (src, expected, success, error, NM_CONNECTION_ERROR, error_code); - - g_object_unref (src); + NMConnection *src; + const char * ssid = "blahblah"; + const char * bssid = "01:02:03:04:05:06"; + const KeyData exp_wifi[] = {{NM_SETTING_WIRELESS_SSID, ssid, 0}, + {NM_SETTING_WIRELESS_MODE, "infrastructure", 0}, + {NULL}}; + const KeyData both_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0}, + {NM_SETTING_WIRELESS_SECURITY_PSK, "asdfasdfasdfasdfasdfafs", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + src = nm_simple_connection_new(); + if (add_wifi) + fill_wifi_empty(src); + fill_wsec(src, both_wsec); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + flags, + wpa_flags, + rsn_flags, + FALSE, + src, + &error); + if (expected) { + fill_wifi(expected, exp_wifi); + fill_wsec(expected, both_wsec); + } + COMPARE(src, expected, success, error, NM_CONNECTION_ERROR, error_code); + + g_object_unref(src); } static void -test_open_ap_wpa_psk_connection_1 (void) +test_open_ap_wpa_psk_connection_1(void) { - /* Test that a WPA-PSK connection filling only the PSK itself and *not* - * filling the wifi setting is rejected when completion is attempted with - * an open AP. - */ - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_SETTING, - NULL); + /* Test that a WPA-PSK connection filling only the PSK itself and *not* + * filling the wifi setting is rejected when completion is attempted with + * an open AP. + */ + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void -test_open_ap_wpa_psk_connection_2 (void) +test_open_ap_wpa_psk_connection_2(void) { - /* Test that a WPA-PSK connection filling only the PSK itself and also - * filling the wifi setting is rejected when completion is attempted with - * an open AP. - */ - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - TRUE, - NM_CONNECTION_ERROR_INVALID_SETTING, - NULL); + /* Test that a WPA-PSK connection filling only the PSK itself and also + * filling the wifi setting is rejected when completion is attempted with + * an open AP. + */ + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void -test_open_ap_wpa_psk_connection_3 (void) +test_open_ap_wpa_psk_connection_3(void) { - /* Test that a WPA-PSK connection filling the PSK and setting the auth alg - * to 'open' is rejected when completion is attempted with an open AP. - */ - test_ap_wpa_psk_connection_base (NULL, "open", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_SETTING, - NULL); + /* Test that a WPA-PSK connection filling the PSK and setting the auth alg + * to 'open' is rejected when completion is attempted with an open AP. + */ + test_ap_wpa_psk_connection_base(NULL, + "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void -test_open_ap_wpa_psk_connection_4 (void) +test_open_ap_wpa_psk_connection_4(void) { - /* Test that a WPA-PSK connection filling the PSK and setting the auth alg - * to 'shared' is rejected when completion is attempted with an open AP. - * Shared auth cannot be used with WPA. - */ - test_ap_wpa_psk_connection_base (NULL, "shared", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_SETTING, - NULL); + /* Test that a WPA-PSK connection filling the PSK and setting the auth alg + * to 'shared' is rejected when completion is attempted with an open AP. + * Shared auth cannot be used with WPA. + */ + test_ap_wpa_psk_connection_base(NULL, + "shared", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void -test_open_ap_wpa_psk_connection_5 (void) +test_open_ap_wpa_psk_connection_5(void) { - /* Test that a WPA-PSK connection filling the PSK, the auth algorithm, and - * key management is rejected when completion is attempted with an open AP. - */ - test_ap_wpa_psk_connection_base ("wpa-psk", "open", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_SETTING, - NULL); + /* Test that a WPA-PSK connection filling the PSK, the auth algorithm, and + * key management is rejected when completion is attempted with an open AP. + */ + test_ap_wpa_psk_connection_base("wpa-psk", + "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } /*****************************************************************************/ static void -test_ap_wpa_eap_connection_base (const char *key_mgmt, - const char *auth_alg, - guint32 flags, - guint32 wpa_flags, - guint32 rsn_flags, - gboolean add_wifi, - guint error_code) +test_ap_wpa_eap_connection_base(const char *key_mgmt, + const char *auth_alg, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean add_wifi, + guint error_code) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_empty[] = { { NULL } }; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - src = nm_simple_connection_new (); - if (add_wifi) - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - fill_8021x (src, src_empty); - success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, - flags, wpa_flags, rsn_flags, - FALSE, src, &error); - /* Failure expected */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, error_code); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_empty[] = {{NULL}}; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + src = nm_simple_connection_new(); + if (add_wifi) + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + fill_8021x(src, src_empty); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + flags, + wpa_flags, + rsn_flags, + FALSE, + src, + &error); + /* Failure expected */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, error_code); + + g_object_unref(src); } enum { - IDX_NONE = 0, - IDX_OPEN, - IDX_PRIV, - IDX_WPA_PSK_PTKIP_GTKIP, - IDX_WPA_PSK_PTKIP_PCCMP_GTKIP, - IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP, - IDX_WPA_RSN_PSK_PCCMP_GCCMP, - IDX_RSN_PSK_PCCMP_GCCMP, - IDX_RSN_PSK_PTKIP_PCCMP_GTKIP, - IDX_WPA_8021X, - IDX_RSN_8021X, + IDX_NONE = 0, + IDX_OPEN, + IDX_PRIV, + IDX_WPA_PSK_PTKIP_GTKIP, + IDX_WPA_PSK_PTKIP_PCCMP_GTKIP, + IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP, + IDX_WPA_RSN_PSK_PCCMP_GCCMP, + IDX_RSN_PSK_PCCMP_GCCMP, + IDX_RSN_PSK_PTKIP_PCCMP_GTKIP, + IDX_WPA_8021X, + IDX_RSN_8021X, }; static guint32 -flags_for_idx (guint32 idx) +flags_for_idx(guint32 idx) { - if (idx == IDX_OPEN) - return NM_802_11_AP_FLAGS_NONE; - else if ( idx == IDX_PRIV - || idx == IDX_WPA_PSK_PTKIP_GTKIP - || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_RSN_PSK_PCCMP_GCCMP - || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP - || idx == IDX_WPA_8021X - || idx == IDX_RSN_8021X) - return NM_802_11_AP_FLAGS_PRIVACY; - else - g_assert_not_reached (); + if (idx == IDX_OPEN) + return NM_802_11_AP_FLAGS_NONE; + else if (idx == IDX_PRIV || idx == IDX_WPA_PSK_PTKIP_GTKIP + || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP + || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP + || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_8021X || idx == IDX_RSN_8021X) + return NM_802_11_AP_FLAGS_PRIVACY; + else + g_assert_not_reached(); } static guint32 -wpa_flags_for_idx (guint32 idx) +wpa_flags_for_idx(guint32 idx) { - if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_RSN_8021X - || idx == IDX_RSN_PSK_PCCMP_GCCMP || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP) - return NM_802_11_AP_SEC_NONE; - else if (idx == IDX_WPA_PSK_PTKIP_GTKIP) - return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP) - return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (NM_IN_SET (idx, IDX_WPA_PSK_PTKIP_PCCMP_GTKIP, IDX_WPA_RSN_PSK_PCCMP_GCCMP)) - return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_WPA_8021X) - return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_802_1X; - else - g_assert_not_reached (); + if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_RSN_8021X || idx == IDX_RSN_PSK_PCCMP_GCCMP + || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP) + return NM_802_11_AP_SEC_NONE; + else if (idx == IDX_WPA_PSK_PTKIP_GTKIP) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (NM_IN_SET(idx, IDX_WPA_PSK_PTKIP_PCCMP_GTKIP, IDX_WPA_RSN_PSK_PCCMP_GCCMP)) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_WPA_8021X) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP + | NM_802_11_AP_SEC_KEY_MGMT_802_1X; + else + g_assert_not_reached(); } static guint32 -rsn_flags_for_idx (guint32 idx) +rsn_flags_for_idx(guint32 idx) { - if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_WPA_8021X - || idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP) - return NM_802_11_AP_SEC_NONE; - else if (idx == IDX_RSN_PSK_PCCMP_GCCMP) - return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP) - return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP) - return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP) - return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK; - else if (idx == IDX_RSN_8021X) - return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_802_1X; - else - g_assert_not_reached (); + if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_WPA_8021X || idx == IDX_WPA_PSK_PTKIP_GTKIP + || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP) + return NM_802_11_AP_SEC_NONE; + else if (idx == IDX_RSN_PSK_PCCMP_GCCMP) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP + | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_RSN_8021X) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP + | NM_802_11_AP_SEC_KEY_MGMT_802_1X; + else + g_assert_not_reached(); } static guint32 -error_code_for_idx (guint32 idx, guint num) +error_code_for_idx(guint32 idx, guint num) { - if (idx == IDX_OPEN) - return NM_CONNECTION_ERROR_INVALID_SETTING; - else if (idx == IDX_PRIV) { - if (num <= 3) - return NM_CONNECTION_ERROR_MISSING_PROPERTY; - else - return NM_CONNECTION_ERROR_INVALID_PROPERTY; - } else if ( idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) - if (num == 4) - return NM_CONNECTION_ERROR_INVALID_PROPERTY; - else - return NM_CONNECTION_ERROR_INVALID_SETTING; - else - g_assert_not_reached (); + if (idx == IDX_OPEN) + return NM_CONNECTION_ERROR_INVALID_SETTING; + else if (idx == IDX_PRIV) { + if (num <= 3) + return NM_CONNECTION_ERROR_MISSING_PROPERTY; + else + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP + || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP + || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) + if (num == 4) + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + else + return NM_CONNECTION_ERROR_INVALID_SETTING; + else + g_assert_not_reached(); } static void -test_ap_wpa_eap_connection_1 (gconstpointer data) +test_ap_wpa_eap_connection_1(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - - test_ap_wpa_eap_connection_base (NULL, NULL, - flags_for_idx (idx), - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - error_code_for_idx (idx, 1)); + guint idx = GPOINTER_TO_UINT(data); + + test_ap_wpa_eap_connection_base(NULL, + NULL, + flags_for_idx(idx), + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + error_code_for_idx(idx, 1)); } static void -test_ap_wpa_eap_connection_2 (gconstpointer data) +test_ap_wpa_eap_connection_2(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - - test_ap_wpa_eap_connection_base (NULL, NULL, - flags_for_idx (idx), - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - TRUE, - error_code_for_idx (idx, 2)); + guint idx = GPOINTER_TO_UINT(data); + + test_ap_wpa_eap_connection_base(NULL, + NULL, + flags_for_idx(idx), + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + TRUE, + error_code_for_idx(idx, 2)); } static void -test_ap_wpa_eap_connection_3 (gconstpointer data) +test_ap_wpa_eap_connection_3(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - - test_ap_wpa_eap_connection_base (NULL, "open", - flags_for_idx (idx), - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - error_code_for_idx (idx, 3)); + guint idx = GPOINTER_TO_UINT(data); + + test_ap_wpa_eap_connection_base(NULL, + "open", + flags_for_idx(idx), + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + error_code_for_idx(idx, 3)); } static void -test_ap_wpa_eap_connection_4 (gconstpointer data) +test_ap_wpa_eap_connection_4(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - - test_ap_wpa_eap_connection_base (NULL, "shared", - flags_for_idx (idx), - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - error_code_for_idx (idx, 4)); + guint idx = GPOINTER_TO_UINT(data); + + test_ap_wpa_eap_connection_base(NULL, + "shared", + flags_for_idx(idx), + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + error_code_for_idx(idx, 4)); } static void -test_ap_wpa_eap_connection_5 (gconstpointer data) +test_ap_wpa_eap_connection_5(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - - test_ap_wpa_eap_connection_base ("wpa-eap", "open", - flags_for_idx (idx), - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - error_code_for_idx (idx, 5)); + guint idx = GPOINTER_TO_UINT(data); + + test_ap_wpa_eap_connection_base("wpa-eap", + "open", + flags_for_idx(idx), + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + error_code_for_idx(idx, 5)); } /*****************************************************************************/ static void -test_priv_ap_empty_connection (void) +test_priv_ap_empty_connection(void) { - NMConnection *src, *expected; - const char *bssid = "01:02:03:04:05:06"; - const char *ssid = "blahblah"; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that an empty connection is completed to a valid Static WEP - * connection when completed with an AP with the Privacy bit set. - */ - - src = nm_simple_connection_new (); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - - /* Static WEP connection expected */ - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - fill_wsec (expected, exp_wsec); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * bssid = "01:02:03:04:05:06"; + const char * ssid = "blahblah"; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0}, {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that an empty connection is completed to a valid Static WEP + * connection when completed with an AP with the Privacy bit set. + */ + + src = nm_simple_connection_new(); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + + /* Static WEP connection expected */ + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + fill_wsec(expected, exp_wsec); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_priv_ap_leap_connection_1 (gconstpointer add_wifi) +test_priv_ap_leap_connection_1(gconstpointer add_wifi) { - NMConnection *src, *expected; - const char *ssid = "blahblah"; - const char *bssid = "01:02:03:04:05:06"; - const char *leap_username = "Bill Smith"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, - { NULL } }; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, - { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that an minimal LEAP connection specifying only key management and - * the LEAP username is completed to a full LEAP connection when completed - * with an AP with the Privacy bit set. - */ - - src = nm_simple_connection_new (); - if (add_wifi) - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* We expect success here; since LEAP APs just set the 'privacy' flag - * there's no way to determine from the AP's beacon whether it's static WEP, - * dynamic WEP, or LEAP. - */ - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - fill_wsec (expected, exp_wsec); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * ssid = "blahblah"; + const char * bssid = "01:02:03:04:05:06"; + const char * leap_username = "Bill Smith"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0}, + {NULL}}; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0}, + {NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that an minimal LEAP connection specifying only key management and + * the LEAP username is completed to a full LEAP connection when completed + * with an AP with the Privacy bit set. + */ + + src = nm_simple_connection_new(); + if (add_wifi) + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* We expect success here; since LEAP APs just set the 'privacy' flag + * there's no way to determine from the AP's beacon whether it's static WEP, + * dynamic WEP, or LEAP. + */ + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + fill_wsec(expected, exp_wsec); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_priv_ap_leap_connection_2 (void) +test_priv_ap_leap_connection_2(void) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that an minimal LEAP connection specifying only key management and - * the LEAP auth alg is completed to a full LEAP connection when completed - * with an AP with the Privacy bit set. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that an minimal LEAP connection specifying only key management and + * the LEAP auth alg is completed to a full LEAP connection when completed + * with an AP with the Privacy bit set. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* We expect failure here, we need a LEAP username */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_unref(src); } /*****************************************************************************/ static void -test_priv_ap_dynamic_wep_1 (void) +test_priv_ap_dynamic_wep_1(void) { - NMConnection *src, *expected; - const char *ssid = "blahblah"; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - const KeyData both_8021x[] = { - { NM_SETTING_802_1X_EAP, "peap", 0 }, - { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, - { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, - { NULL } }; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that an minimal Dynamic WEP connection specifying key management, - * the auth algorithm, and valid 802.1x setting is completed to a valid - * Dynamic WEP connection when completed with an AP with the Privacy bit set. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - fill_8021x (src, both_8021x); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - - /* We expect a completed Dynamic WEP connection */ - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - fill_wsec (expected, exp_wsec); - fill_8021x (expected, both_8021x); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * ssid = "blahblah"; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + const KeyData both_8021x[] = {{NM_SETTING_802_1X_EAP, "peap", 0}, + {NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0}, + {NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0}, + {NULL}}; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that an minimal Dynamic WEP connection specifying key management, + * the auth algorithm, and valid 802.1x setting is completed to a valid + * Dynamic WEP connection when completed with an AP with the Privacy bit set. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + fill_8021x(src, both_8021x); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + + /* We expect a completed Dynamic WEP connection */ + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + fill_wsec(expected, exp_wsec); + fill_8021x(expected, both_8021x); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_priv_ap_dynamic_wep_2 (void) +test_priv_ap_dynamic_wep_2(void) { - NMConnection *src, *expected; - const char *ssid = "blahblah"; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - const KeyData both_8021x[] = { - { NM_SETTING_802_1X_EAP, "peap", 0 }, - { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, - { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, - { NULL } }; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that an minimal Dynamic WEP connection specifying only the auth - * algorithm and a valid 802.1x setting is completed to a valid Dynamic - * WEP connection when completed with an AP with the Privacy bit set. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - fill_8021x (src, both_8021x); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - - /* We expect a completed Dynamic WEP connection */ - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - fill_wsec (expected, exp_wsec); - fill_8021x (expected, both_8021x); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + NMConnection *src, *expected; + const char * ssid = "blahblah"; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, {NULL}}; + const KeyData both_8021x[] = {{NM_SETTING_802_1X_EAP, "peap", 0}, + {NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0}, + {NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0}, + {NULL}}; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that an minimal Dynamic WEP connection specifying only the auth + * algorithm and a valid 802.1x setting is completed to a valid Dynamic + * WEP connection when completed with an AP with the Privacy bit set. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + fill_8021x(src, both_8021x); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + + /* We expect a completed Dynamic WEP connection */ + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + fill_wsec(expected, exp_wsec); + fill_8021x(expected, both_8021x); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_priv_ap_dynamic_wep_3 (void) +test_priv_ap_dynamic_wep_3(void) { - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0 }, - { NULL } }; - const KeyData src_8021x[] = { - { NM_SETTING_802_1X_EAP, "peap", 0 }, - { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, - { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Ensure that a basic connection specifying 'shared' auth and an 802.1x - * setting is rejected, as 802.1x is incompatible with 'shared' auth. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - fill_8021x (src, src_8021x); - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); - /* Expect failure; shared is not compatible with dynamic WEP */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); - - g_object_unref (src); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0}, {NULL}}; + const KeyData src_8021x[] = {{NM_SETTING_802_1X_EAP, "peap", 0}, + {NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0}, + {NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Ensure that a basic connection specifying 'shared' auth and an 802.1x + * setting is rejected, as 802.1x is incompatible with 'shared' auth. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + fill_8021x(src, src_8021x); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + src, + &error); + /* Expect failure; shared is not compatible with dynamic WEP */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_unref(src); } /*****************************************************************************/ static void -test_priv_ap_wpa_psk_connection_1 (void) +test_priv_ap_wpa_psk_connection_1(void) { - /* Test that a basic WPA-PSK connection is rejected when completion is - * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN - * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. - */ - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + /* Test that a basic WPA-PSK connection is rejected when completion is + * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN + * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. + */ + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void -test_priv_ap_wpa_psk_connection_2 (void) +test_priv_ap_wpa_psk_connection_2(void) { - /* Test that a basic WPA-PSK connection is rejected when completion is - * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN - * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. - */ - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - TRUE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + /* Test that a basic WPA-PSK connection is rejected when completion is + * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN + * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. + */ + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void -test_priv_ap_wpa_psk_connection_3 (void) +test_priv_ap_wpa_psk_connection_3(void) { - /* Test that a basic WPA-PSK connection specifying only the auth algorithm - * is rejected when completion is attempted with an AP with just the Privacy - * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP - * or LEAP, not WPA. - */ - test_ap_wpa_psk_connection_base (NULL, "open", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + /* Test that a basic WPA-PSK connection specifying only the auth algorithm + * is rejected when completion is attempted with an AP with just the Privacy + * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP + * or LEAP, not WPA. + */ + test_ap_wpa_psk_connection_base(NULL, + "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void -test_priv_ap_wpa_psk_connection_4 (void) +test_priv_ap_wpa_psk_connection_4(void) { - /* Test that a basic WPA-PSK connection specifying only the auth algorithm - * is rejected when completion is attempted with an AP with just the Privacy - * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP - * or LEAP, not WPA. Second, 'shared' auth is incompatible with WPA. - */ - test_ap_wpa_psk_connection_base (NULL, "shared", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + /* Test that a basic WPA-PSK connection specifying only the auth algorithm + * is rejected when completion is attempted with an AP with just the Privacy + * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP + * or LEAP, not WPA. Second, 'shared' auth is incompatible with WPA. + */ + test_ap_wpa_psk_connection_base(NULL, + "shared", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void -test_priv_ap_wpa_psk_connection_5 (void) +test_priv_ap_wpa_psk_connection_5(void) { - /* Test that a WPA-PSK connection specifying both the key management and - * auth algorithm is rejected when completion is attempted with an AP with - * just the Privacy bit set. Lack of WPA/RSN flags means the AP provides - * Static/Dynamic WEP or LEAP, not WPA. - */ - test_ap_wpa_psk_connection_base ("wpa-psk", "open", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + /* Test that a WPA-PSK connection specifying both the key management and + * auth algorithm is rejected when completion is attempted with an AP with + * just the Privacy bit set. Lack of WPA/RSN flags means the AP provides + * Static/Dynamic WEP or LEAP, not WPA. + */ + test_ap_wpa_psk_connection_base("wpa-psk", + "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } /*****************************************************************************/ static void -test_wpa_ap_empty_connection (gconstpointer data) +test_wpa_ap_empty_connection(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *src, *expected; - const char *bssid = "01:02:03:04:05:06"; - const char *ssid = "blahblah"; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that a basic WPA-PSK connection specifying just key management and - * the auth algorithm is completed successfully when given an AP with WPA - * or RSN flags. - */ - - src = nm_simple_connection_new (); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, src, &error); - - /* WPA connection expected */ - expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA); - fill_wsec (expected, exp_wsec); - COMPARE (src, expected, success, error, 0, 0); - - g_object_unref (src); - g_object_unref (expected); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *src, *expected; + const char * bssid = "01:02:03:04:05:06"; + const char * ssid = "blahblah"; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that a basic WPA-PSK connection specifying just key management and + * the auth algorithm is completed successfully when given an AP with WPA + * or RSN flags. + */ + + src = nm_simple_connection_new(); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + src, + &error); + + /* WPA connection expected */ + expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + fill_wsec(expected, exp_wsec); + COMPARE(src, expected, success, error, 0, 0); + + g_object_unref(src); + g_object_unref(expected); } /*****************************************************************************/ static void -test_wpa_ap_leap_connection_1 (gconstpointer data) +test_wpa_ap_leap_connection_1(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *src; - const char *ssid = "blahblah"; - const char *bssid = "01:02:03:04:05:06"; - const char *leap_username = "Bill Smith"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that completion of a LEAP connection with a WPA-enabled AP is - * rejected since WPA APs (usually) do not support LEAP. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection (ssid, bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - src, &error); - /* Expect failure here; WPA APs don't support old-school LEAP */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); - - g_object_unref (src); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *src; + const char * ssid = "blahblah"; + const char * bssid = "01:02:03:04:05:06"; + const char * leap_username = "Bill Smith"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that completion of a LEAP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support LEAP. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection(ssid, + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + src, + &error); + /* Expect failure here; WPA APs don't support old-school LEAP */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_unref(src); } /*****************************************************************************/ static void -test_wpa_ap_leap_connection_2 (gconstpointer data) +test_wpa_ap_leap_connection_2(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that completion of a LEAP connection with a WPA-enabled AP is - * rejected since WPA APs (usually) do not support LEAP. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - src, &error); - /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); - - g_object_unref (src); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0}, + {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that completion of a LEAP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support LEAP. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + src, + &error); + /* We expect failure here, we need a LEAP username */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_unref(src); } /*****************************************************************************/ static void -test_wpa_ap_dynamic_wep_connection (gconstpointer data) +test_wpa_ap_dynamic_wep_connection(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *src; - const char *bssid = "01:02:03:04:05:06"; - const KeyData src_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, - { NULL } }; - gboolean success; - GError *error = NULL; - - /* Test that completion of a Dynamic WEP connection with a WPA-enabled AP is - * rejected since WPA APs (usually) do not support Dynamic WEP. - */ - - src = nm_simple_connection_new (); - fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection ("blahblah", bssid, - NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - src, &error); - /* We expect failure here since Dynamic WEP is incompatible with WPA */ - COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); - - g_object_unref (src); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *src; + const char * bssid = "01:02:03:04:05:06"; + const KeyData src_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0}, {NULL}}; + gboolean success; + GError * error = NULL; + + /* Test that completion of a Dynamic WEP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support Dynamic WEP. + */ + + src = nm_simple_connection_new(); + fill_wifi_empty(src); + fill_wsec(src, src_wsec); + success = complete_connection("blahblah", + bssid, + NM_802_11_MODE_INFRA, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + src, + &error); + /* We expect failure here since Dynamic WEP is incompatible with WPA */ + COMPARE(src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + g_object_unref(src); } /*****************************************************************************/ static void -test_wpa_ap_wpa_psk_connection_1 (gconstpointer data) +test_wpa_ap_wpa_psk_connection_1(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *expected; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - - expected = nm_simple_connection_new (); - fill_wsec (expected, exp_wsec); - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - expected); - g_object_unref (expected); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *expected; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + + expected = nm_simple_connection_new(); + fill_wsec(expected, exp_wsec); + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); + g_object_unref(expected); } static void -test_wpa_ap_wpa_psk_connection_2 (gconstpointer data) +test_wpa_ap_wpa_psk_connection_2(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *expected; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - - expected = nm_simple_connection_new (); - fill_wsec (expected, exp_wsec); - test_ap_wpa_psk_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - TRUE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - expected); - g_object_unref (expected); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *expected; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + + expected = nm_simple_connection_new(); + fill_wsec(expected, exp_wsec); + test_ap_wpa_psk_connection_base(NULL, + NULL, + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); + g_object_unref(expected); } static void -test_wpa_ap_wpa_psk_connection_3 (gconstpointer data) +test_wpa_ap_wpa_psk_connection_3(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *expected; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - - expected = nm_simple_connection_new (); - fill_wsec (expected, exp_wsec); - test_ap_wpa_psk_connection_base (NULL, "open", - NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - expected); - g_object_unref (expected); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *expected; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + + expected = nm_simple_connection_new(); + fill_wsec(expected, exp_wsec); + test_ap_wpa_psk_connection_base(NULL, + "open", + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); + g_object_unref(expected); } static void -test_wpa_ap_wpa_psk_connection_4 (gconstpointer data) +test_wpa_ap_wpa_psk_connection_4(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - test_ap_wpa_psk_connection_base (NULL, "shared", - NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - NULL); + guint idx = GPOINTER_TO_UINT(data); + test_ap_wpa_psk_connection_base(NULL, + "shared", + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void -test_wpa_ap_wpa_psk_connection_5 (gconstpointer data) +test_wpa_ap_wpa_psk_connection_5(gconstpointer data) { - guint idx = GPOINTER_TO_UINT (data); - NMConnection *expected; - const KeyData exp_wsec[] = { - { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, - { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, - { NULL } }; - - expected = nm_simple_connection_new (); - fill_wsec (expected, exp_wsec); - test_ap_wpa_psk_connection_base ("wpa-psk", "open", - NM_802_11_AP_FLAGS_PRIVACY, - wpa_flags_for_idx (idx), - rsn_flags_for_idx (idx), - FALSE, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - expected); - g_object_unref (expected); + guint idx = GPOINTER_TO_UINT(data); + NMConnection *expected; + const KeyData exp_wsec[] = {{NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0}, + {NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0}, + {NULL}}; + + expected = nm_simple_connection_new(); + fill_wsec(expected, exp_wsec); + test_ap_wpa_psk_connection_base("wpa-psk", + "open", + NM_802_11_AP_FLAGS_PRIVACY, + wpa_flags_for_idx(idx), + rsn_flags_for_idx(idx), + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); + g_object_unref(expected); } /*****************************************************************************/ static void -test_strength_dbm (void) +test_strength_dbm(void) { - /* boundary conditions first */ - g_assert_cmpint (nm_wifi_utils_level_to_quality (-1), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-40), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-30), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-100), ==, 0); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-200), ==, 0); - - g_assert_cmpint (nm_wifi_utils_level_to_quality (-81), ==, 32); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-92), ==, 14); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-74), ==, 44); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-81), ==, 32); - g_assert_cmpint (nm_wifi_utils_level_to_quality (-66), ==, 57); + /* boundary conditions first */ + g_assert_cmpint(nm_wifi_utils_level_to_quality(-1), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-40), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-30), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-100), ==, 0); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-200), ==, 0); + + g_assert_cmpint(nm_wifi_utils_level_to_quality(-81), ==, 32); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-92), ==, 14); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-74), ==, 44); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-81), ==, 32); + g_assert_cmpint(nm_wifi_utils_level_to_quality(-66), ==, 57); } static void -test_strength_percent (void) +test_strength_percent(void) { - int i; + int i; - /* boundary conditions first */ - g_assert_cmpint (nm_wifi_utils_level_to_quality (0), ==, 0); - g_assert_cmpint (nm_wifi_utils_level_to_quality (100), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (110), ==, 100); + /* boundary conditions first */ + g_assert_cmpint(nm_wifi_utils_level_to_quality(0), ==, 0); + g_assert_cmpint(nm_wifi_utils_level_to_quality(100), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(110), ==, 100); - for (i = 0; i <= 100; i++) - g_assert_cmpint (nm_wifi_utils_level_to_quality (i), ==, i); + for (i = 0; i <= 100; i++) + g_assert_cmpint(nm_wifi_utils_level_to_quality(i), ==, i); } static void -test_strength_wext (void) +test_strength_wext(void) { - /* boundary conditions that we assume aren't WEXT first */ - g_assert_cmpint (nm_wifi_utils_level_to_quality (256), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (110), ==, 100); - - /* boundary conditions that we assume are WEXT */ - g_assert_cmpint (nm_wifi_utils_level_to_quality (111), ==, 0); - g_assert_cmpint (nm_wifi_utils_level_to_quality (150), ==, 0); - g_assert_cmpint (nm_wifi_utils_level_to_quality (225), ==, 100); - g_assert_cmpint (nm_wifi_utils_level_to_quality (255), ==, 100); - - g_assert_cmpint (nm_wifi_utils_level_to_quality (157), ==, 2); - g_assert_cmpint (nm_wifi_utils_level_to_quality (200), ==, 74); - g_assert_cmpint (nm_wifi_utils_level_to_quality (215), ==, 99); + /* boundary conditions that we assume aren't WEXT first */ + g_assert_cmpint(nm_wifi_utils_level_to_quality(256), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(110), ==, 100); + + /* boundary conditions that we assume are WEXT */ + g_assert_cmpint(nm_wifi_utils_level_to_quality(111), ==, 0); + g_assert_cmpint(nm_wifi_utils_level_to_quality(150), ==, 0); + g_assert_cmpint(nm_wifi_utils_level_to_quality(225), ==, 100); + g_assert_cmpint(nm_wifi_utils_level_to_quality(255), ==, 100); + + g_assert_cmpint(nm_wifi_utils_level_to_quality(157), ==, 2); + g_assert_cmpint(nm_wifi_utils_level_to_quality(200), ==, 74); + g_assert_cmpint(nm_wifi_utils_level_to_quality(215), ==, 99); } -#define _assert_strength_in_range(x) \ - ({ \ - guint32 _x = (x); \ - g_assert_cmpint (_x, >=, 0); \ - g_assert_cmpint (_x, <=, 100); \ - }) +#define _assert_strength_in_range(x) \ + ({ \ + guint32 _x = (x); \ + g_assert_cmpint(_x, >=, 0); \ + g_assert_cmpint(_x, <=, 100); \ + }) static void -test_strength_all (void) +test_strength_all(void) { - int val; - - for (val = -200; val < 300; val++) - _assert_strength_in_range (nm_wifi_utils_level_to_quality (val)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MININT)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MAXINT)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MININT32)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MAXINT32)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MININT16)); - _assert_strength_in_range (nm_wifi_utils_level_to_quality (G_MAXINT16)); + int val; + + for (val = -200; val < 300; val++) + _assert_strength_in_range(nm_wifi_utils_level_to_quality(val)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MININT)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MAXINT)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MININT32)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MAXINT32)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MININT16)); + _assert_strength_in_range(nm_wifi_utils_level_to_quality(G_MAXINT16)); } /*****************************************************************************/ static void -do_test_ssids_options_to_ptrarray (const char *const*ssids) +do_test_ssids_options_to_ptrarray(const char *const *ssids) { - GVariantBuilder builder; - gs_unref_variant GVariant *variant = NULL; - gs_unref_ptrarray GPtrArray *ssids_arr = NULL; - gs_free_error GError *error = NULL; - gsize len; - gsize i; - - g_assert (ssids); - - len = NM_PTRARRAY_LEN (ssids); - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); - for (i = 0; i < len; i++) { - const char *ssid = ssids[i]; - - g_variant_builder_add (&builder, - "@ay", - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ssid, strlen (ssid), 1)); - } - variant = g_variant_builder_end (&builder); - - if (nmtst_get_rand_bool ()) - g_variant_ref_sink (variant); - - ssids_arr = nmtst_ssids_options_to_ptrarray (variant, &error); - g_assert (!error); - if (len == 0) { - g_assert (!ssids_arr); - return; - } - g_assert_cmpint (len, ==, ssids_arr->len); - for (i = 0; i < len; i++) { - const char *ssid = ssids[i]; - GBytes *bytes = ssids_arr->pdata[i]; - - g_assert (nm_utils_gbytes_equal_mem (bytes, - ssid, - strlen (ssid))); - } + GVariantBuilder builder; + gs_unref_variant GVariant *variant = NULL; + gs_unref_ptrarray GPtrArray *ssids_arr = NULL; + gs_free_error GError *error = NULL; + gsize len; + gsize i; + + g_assert(ssids); + + len = NM_PTRARRAY_LEN(ssids); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("aay")); + for (i = 0; i < len; i++) { + const char *ssid = ssids[i]; + + g_variant_builder_add( + &builder, + "@ay", + g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, ssid, strlen(ssid), 1)); + } + variant = g_variant_builder_end(&builder); + + if (nmtst_get_rand_bool()) + g_variant_ref_sink(variant); + + ssids_arr = nmtst_ssids_options_to_ptrarray(variant, &error); + g_assert(!error); + if (len == 0) { + g_assert(!ssids_arr); + return; + } + g_assert_cmpint(len, ==, ssids_arr->len); + for (i = 0; i < len; i++) { + const char *ssid = ssids[i]; + GBytes * bytes = ssids_arr->pdata[i]; + + g_assert(nm_utils_gbytes_equal_mem(bytes, ssid, strlen(ssid))); + } } static void -test_ssids_options_to_ptrarray (void) +test_ssids_options_to_ptrarray(void) { - do_test_ssids_options_to_ptrarray (NM_PTRARRAY_EMPTY (const char *)); - do_test_ssids_options_to_ptrarray (NM_MAKE_STRV ("ab")); - do_test_ssids_options_to_ptrarray (NM_MAKE_STRV ("ab", "cd", "fsdfdsf")); + do_test_ssids_options_to_ptrarray(NM_PTRARRAY_EMPTY(const char *)); + do_test_ssids_options_to_ptrarray(NM_MAKE_STRV("ab")); + do_test_ssids_options_to_ptrarray(NM_MAKE_STRV("ab", "cd", "fsdfdsf")); } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) +main(int argc, char **argv) { - gsize i; - - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); - - g_test_add_func ("/wifi/lock_bssid", - test_lock_bssid); - - /* Open AP tests; make sure that connections to be completed that have - * various security-related settings already set cause the completion - * to fail. - */ - g_test_add_func ("/wifi/open_ap/empty_connection", - test_open_ap_empty_connection); - g_test_add_data_func ("/wifi/open_ap/leap_connection/1", - (gconstpointer) TRUE, - test_open_ap_leap_connection_1); - g_test_add_data_func ("/wifi/open_ap/leap_connection/1_no_add_wifi", - (gconstpointer) FALSE, - test_open_ap_leap_connection_1); - g_test_add_func ("/wifi/open_ap/leap_connection/2", - test_open_ap_leap_connection_2); - g_test_add_data_func ("/wifi/open_ap/wep_connection_true", - (gconstpointer) TRUE, - test_open_ap_wep_connection); - g_test_add_data_func ("/wifi/open_ap/wep_connection_false", - (gconstpointer) FALSE, - test_open_ap_wep_connection); - - g_test_add_func ("/wifi/open_ap/wpa_psk_connection/1", - test_open_ap_wpa_psk_connection_1); - g_test_add_func ("/wifi/open_ap/wpa_psk_connection/2", - test_open_ap_wpa_psk_connection_2); - g_test_add_func ("/wifi/open_ap/wpa_psk_connection/3", - test_open_ap_wpa_psk_connection_3); - g_test_add_func ("/wifi/open_ap/wpa_psk_connection/4", - test_open_ap_wpa_psk_connection_4); - g_test_add_func ("/wifi/open_ap/wpa_psk_connection/5", - test_open_ap_wpa_psk_connection_5); - - g_test_add_data_func ("/wifi/open_ap/wpa_eap_connection/1", - (gconstpointer) IDX_OPEN, - test_ap_wpa_eap_connection_1); - g_test_add_data_func ("/wifi/open_ap/wpa_eap_connection/2", - (gconstpointer) IDX_OPEN, - test_ap_wpa_eap_connection_2); - g_test_add_data_func ("/wifi/open_ap/wpa_eap_connection/3", - (gconstpointer) IDX_OPEN, - test_ap_wpa_eap_connection_3); - g_test_add_data_func ("/wifi/open_ap/wpa_eap_connection/4", - (gconstpointer) IDX_OPEN, - test_ap_wpa_eap_connection_4); - g_test_add_data_func ("/wifi/open_ap/wpa_eap_connection/5", - (gconstpointer) IDX_OPEN, - test_ap_wpa_eap_connection_5); - - /* WEP AP tests */ - g_test_add_func ("/wifi/priv_ap/empty_connection", - test_priv_ap_empty_connection); - g_test_add_data_func ("/wifi/priv_ap/leap_connection/1", - (gconstpointer) FALSE, - test_priv_ap_leap_connection_1); - g_test_add_func ("/wifi/priv_ap/leap_connection/2", - test_priv_ap_leap_connection_2); - - g_test_add_func ("/wifi/priv_ap/dynamic_wep/1", - test_priv_ap_dynamic_wep_1); - g_test_add_func ("/wifi/priv_ap/dynamic_wep/2", - test_priv_ap_dynamic_wep_2); - g_test_add_func ("/wifi/priv_ap/dynamic_wep/3", - test_priv_ap_dynamic_wep_3); - - g_test_add_func ("/wifi/priv_ap/wpa_psk_connection/1", - test_priv_ap_wpa_psk_connection_1); - g_test_add_func ("/wifi/priv_ap/wpa_psk_connection/2", - test_priv_ap_wpa_psk_connection_2); - g_test_add_func ("/wifi/priv_ap/wpa_psk_connection/3", - test_priv_ap_wpa_psk_connection_3); - g_test_add_func ("/wifi/priv_ap/wpa_psk_connection/4", - test_priv_ap_wpa_psk_connection_4); - g_test_add_func ("/wifi/priv_ap/wpa_psk_connection/5", - test_priv_ap_wpa_psk_connection_5); - - g_test_add_data_func ("/wifi/priv_ap/wpa_eap_connection/1", - (gconstpointer) IDX_PRIV, - test_ap_wpa_eap_connection_1); - g_test_add_data_func ("/wifi/priv_ap/wpa_eap_connection/2", - (gconstpointer) IDX_PRIV, - test_ap_wpa_eap_connection_2); - g_test_add_data_func ("/wifi/priv_ap/wpa_eap_connection/3", - (gconstpointer) IDX_PRIV, - test_ap_wpa_eap_connection_3); - g_test_add_data_func ("/wifi/priv_ap/wpa_eap_connection/4", - (gconstpointer) IDX_PRIV, - test_ap_wpa_eap_connection_4); - g_test_add_data_func ("/wifi/priv_ap/wpa_eap_connection/5", - (gconstpointer) IDX_PRIV, - test_ap_wpa_eap_connection_5); - -#define ADD_FUNC(func) do { \ - char *name_idx = g_strdup_printf ("/wifi/wpa_psk/" G_STRINGIFY (func) "/%zd", i); \ - g_test_add_data_func (name_idx, (gconstpointer) i, func); \ - g_free (name_idx); \ - } while (0) - - /* WPA-PSK tests */ - for (i = IDX_WPA_PSK_PTKIP_GTKIP; i <= IDX_WPA_RSN_PSK_PCCMP_GCCMP; i++) { - ADD_FUNC(test_wpa_ap_empty_connection); - ADD_FUNC(test_wpa_ap_leap_connection_1); - ADD_FUNC(test_wpa_ap_leap_connection_2); - ADD_FUNC(test_wpa_ap_dynamic_wep_connection); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); - ADD_FUNC(test_ap_wpa_eap_connection_1); - ADD_FUNC(test_ap_wpa_eap_connection_2); - ADD_FUNC(test_ap_wpa_eap_connection_3); - ADD_FUNC(test_ap_wpa_eap_connection_4); - ADD_FUNC(test_ap_wpa_eap_connection_5); - } + gsize i; + + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); + + g_test_add_func("/wifi/lock_bssid", test_lock_bssid); + + /* Open AP tests; make sure that connections to be completed that have + * various security-related settings already set cause the completion + * to fail. + */ + g_test_add_func("/wifi/open_ap/empty_connection", test_open_ap_empty_connection); + g_test_add_data_func("/wifi/open_ap/leap_connection/1", + (gconstpointer) TRUE, + test_open_ap_leap_connection_1); + g_test_add_data_func("/wifi/open_ap/leap_connection/1_no_add_wifi", + (gconstpointer) FALSE, + test_open_ap_leap_connection_1); + g_test_add_func("/wifi/open_ap/leap_connection/2", test_open_ap_leap_connection_2); + g_test_add_data_func("/wifi/open_ap/wep_connection_true", + (gconstpointer) TRUE, + test_open_ap_wep_connection); + g_test_add_data_func("/wifi/open_ap/wep_connection_false", + (gconstpointer) FALSE, + test_open_ap_wep_connection); + + g_test_add_func("/wifi/open_ap/wpa_psk_connection/1", test_open_ap_wpa_psk_connection_1); + g_test_add_func("/wifi/open_ap/wpa_psk_connection/2", test_open_ap_wpa_psk_connection_2); + g_test_add_func("/wifi/open_ap/wpa_psk_connection/3", test_open_ap_wpa_psk_connection_3); + g_test_add_func("/wifi/open_ap/wpa_psk_connection/4", test_open_ap_wpa_psk_connection_4); + g_test_add_func("/wifi/open_ap/wpa_psk_connection/5", test_open_ap_wpa_psk_connection_5); + + g_test_add_data_func("/wifi/open_ap/wpa_eap_connection/1", + (gconstpointer) IDX_OPEN, + test_ap_wpa_eap_connection_1); + g_test_add_data_func("/wifi/open_ap/wpa_eap_connection/2", + (gconstpointer) IDX_OPEN, + test_ap_wpa_eap_connection_2); + g_test_add_data_func("/wifi/open_ap/wpa_eap_connection/3", + (gconstpointer) IDX_OPEN, + test_ap_wpa_eap_connection_3); + g_test_add_data_func("/wifi/open_ap/wpa_eap_connection/4", + (gconstpointer) IDX_OPEN, + test_ap_wpa_eap_connection_4); + g_test_add_data_func("/wifi/open_ap/wpa_eap_connection/5", + (gconstpointer) IDX_OPEN, + test_ap_wpa_eap_connection_5); + + /* WEP AP tests */ + g_test_add_func("/wifi/priv_ap/empty_connection", test_priv_ap_empty_connection); + g_test_add_data_func("/wifi/priv_ap/leap_connection/1", + (gconstpointer) FALSE, + test_priv_ap_leap_connection_1); + g_test_add_func("/wifi/priv_ap/leap_connection/2", test_priv_ap_leap_connection_2); + + g_test_add_func("/wifi/priv_ap/dynamic_wep/1", test_priv_ap_dynamic_wep_1); + g_test_add_func("/wifi/priv_ap/dynamic_wep/2", test_priv_ap_dynamic_wep_2); + g_test_add_func("/wifi/priv_ap/dynamic_wep/3", test_priv_ap_dynamic_wep_3); + + g_test_add_func("/wifi/priv_ap/wpa_psk_connection/1", test_priv_ap_wpa_psk_connection_1); + g_test_add_func("/wifi/priv_ap/wpa_psk_connection/2", test_priv_ap_wpa_psk_connection_2); + g_test_add_func("/wifi/priv_ap/wpa_psk_connection/3", test_priv_ap_wpa_psk_connection_3); + g_test_add_func("/wifi/priv_ap/wpa_psk_connection/4", test_priv_ap_wpa_psk_connection_4); + g_test_add_func("/wifi/priv_ap/wpa_psk_connection/5", test_priv_ap_wpa_psk_connection_5); + + g_test_add_data_func("/wifi/priv_ap/wpa_eap_connection/1", + (gconstpointer) IDX_PRIV, + test_ap_wpa_eap_connection_1); + g_test_add_data_func("/wifi/priv_ap/wpa_eap_connection/2", + (gconstpointer) IDX_PRIV, + test_ap_wpa_eap_connection_2); + g_test_add_data_func("/wifi/priv_ap/wpa_eap_connection/3", + (gconstpointer) IDX_PRIV, + test_ap_wpa_eap_connection_3); + g_test_add_data_func("/wifi/priv_ap/wpa_eap_connection/4", + (gconstpointer) IDX_PRIV, + test_ap_wpa_eap_connection_4); + g_test_add_data_func("/wifi/priv_ap/wpa_eap_connection/5", + (gconstpointer) IDX_PRIV, + test_ap_wpa_eap_connection_5); + +#define ADD_FUNC(func) \ + do { \ + char *name_idx = g_strdup_printf("/wifi/wpa_psk/" G_STRINGIFY(func) "/%zd", i); \ + g_test_add_data_func(name_idx, (gconstpointer) i, func); \ + g_free(name_idx); \ + } while (0) + + /* WPA-PSK tests */ + for (i = IDX_WPA_PSK_PTKIP_GTKIP; i <= IDX_WPA_RSN_PSK_PCCMP_GCCMP; i++) { + ADD_FUNC(test_wpa_ap_empty_connection); + ADD_FUNC(test_wpa_ap_leap_connection_1); + ADD_FUNC(test_wpa_ap_leap_connection_2); + ADD_FUNC(test_wpa_ap_dynamic_wep_connection); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); + ADD_FUNC(test_ap_wpa_eap_connection_1); + ADD_FUNC(test_ap_wpa_eap_connection_2); + ADD_FUNC(test_ap_wpa_eap_connection_3); + ADD_FUNC(test_ap_wpa_eap_connection_4); + ADD_FUNC(test_ap_wpa_eap_connection_5); + } #undef ADD_FUNC -#define ADD_FUNC(func) do { \ - char *name_idx = g_strdup_printf ("/wifi/rsn_psk/" G_STRINGIFY (func) "/%zd", i); \ - g_test_add_data_func (name_idx, (gconstpointer) i, func); \ - g_free (name_idx); \ - } while (0) - - /* RSN-PSK tests */ - for (i = IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP; i <= IDX_RSN_PSK_PTKIP_PCCMP_GTKIP; i++) { - ADD_FUNC(test_wpa_ap_empty_connection); - ADD_FUNC(test_wpa_ap_leap_connection_1); - ADD_FUNC(test_wpa_ap_leap_connection_2); - ADD_FUNC(test_wpa_ap_dynamic_wep_connection); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); - ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); - ADD_FUNC(test_ap_wpa_eap_connection_1); - ADD_FUNC(test_ap_wpa_eap_connection_2); - ADD_FUNC(test_ap_wpa_eap_connection_3); - ADD_FUNC(test_ap_wpa_eap_connection_4); - ADD_FUNC(test_ap_wpa_eap_connection_5); - } +#define ADD_FUNC(func) \ + do { \ + char *name_idx = g_strdup_printf("/wifi/rsn_psk/" G_STRINGIFY(func) "/%zd", i); \ + g_test_add_data_func(name_idx, (gconstpointer) i, func); \ + g_free(name_idx); \ + } while (0) + + /* RSN-PSK tests */ + for (i = IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP; i <= IDX_RSN_PSK_PTKIP_PCCMP_GTKIP; i++) { + ADD_FUNC(test_wpa_ap_empty_connection); + ADD_FUNC(test_wpa_ap_leap_connection_1); + ADD_FUNC(test_wpa_ap_leap_connection_2); + ADD_FUNC(test_wpa_ap_dynamic_wep_connection); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_1); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_2); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_3); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_4); + ADD_FUNC(test_wpa_ap_wpa_psk_connection_5); + ADD_FUNC(test_ap_wpa_eap_connection_1); + ADD_FUNC(test_ap_wpa_eap_connection_2); + ADD_FUNC(test_ap_wpa_eap_connection_3); + ADD_FUNC(test_ap_wpa_eap_connection_4); + ADD_FUNC(test_ap_wpa_eap_connection_5); + } #undef ADD_FUNC - /* Scanned signal strength conversion tests */ - g_test_add_func ("/wifi/strength/dbm", - test_strength_dbm); - g_test_add_func ("/wifi/strength/percent", - test_strength_percent); - g_test_add_func ("/wifi/strength/wext", - test_strength_wext); - g_test_add_func ("/wifi/strength/all", - test_strength_all); + /* Scanned signal strength conversion tests */ + g_test_add_func("/wifi/strength/dbm", test_strength_dbm); + g_test_add_func("/wifi/strength/percent", test_strength_percent); + g_test_add_func("/wifi/strength/wext", test_strength_wext); + g_test_add_func("/wifi/strength/all", test_strength_all); - g_test_add_func ("/wifi/ssids_options_to_ptrarray", test_ssids_options_to_ptrarray); + g_test_add_func("/wifi/ssids_options_to_ptrarray", test_ssids_options_to_ptrarray); - return g_test_run (); + return g_test_run(); } diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index a2f2e7a6..f77de85a 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2019 Red Hat, Inc. */ @@ -21,929 +21,937 @@ _LOG_DECLARE_SELF(NMDeviceModem); /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceModem, - PROP_MODEM, - PROP_CAPABILITIES, - PROP_CURRENT_CAPABILITIES, - PROP_DEVICE_ID, - PROP_OPERATOR_CODE, - PROP_APN, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceModem, + PROP_MODEM, + PROP_CAPABILITIES, + PROP_CURRENT_CAPABILITIES, + PROP_DEVICE_ID, + PROP_OPERATOR_CODE, + PROP_APN, ); typedef struct { - NMModem *modem; - NMDeviceModemCapabilities caps; - NMDeviceModemCapabilities current_caps; - char *device_id; - char *operator_code; - char *apn; - bool rf_enabled:1; - NMDeviceStageState stage1_state:3; + NMModem * modem; + NMDeviceModemCapabilities caps; + NMDeviceModemCapabilities current_caps; + char * device_id; + char * operator_code; + char * apn; + bool rf_enabled : 1; + NMDeviceStageState stage1_state : 3; } NMDeviceModemPrivate; struct _NMDeviceModem { - NMDevice parent; - NMDeviceModemPrivate _priv; + NMDevice parent; + NMDeviceModemPrivate _priv; }; struct _NMDeviceModemClass { - NMDeviceClass parent; + NMDeviceClass parent; }; -G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) +G_DEFINE_TYPE(NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) -#define NM_DEVICE_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMDevice) +#define NM_DEVICE_MODEM_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMDevice) /*****************************************************************************/ static void -ppp_failed (NMModem *modem, - guint i_reason, - gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDeviceStateReason reason = i_reason; - - switch (nm_device_get_state (device)) { - case NM_DEVICE_STATE_PREPARE: - case NM_DEVICE_STATE_CONFIG: - case NM_DEVICE_STATE_NEED_AUTH: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - break; - case NM_DEVICE_STATE_IP_CONFIG: - case NM_DEVICE_STATE_IP_CHECK: - case NM_DEVICE_STATE_SECONDARIES: - case NM_DEVICE_STATE_ACTIVATED: - if (nm_device_activate_ip4_state_in_conf (device)) - nm_device_activate_schedule_ip_config_timeout (device, AF_INET); - else if (nm_device_activate_ip6_state_in_conf (device)) - nm_device_activate_schedule_ip_config_timeout (device, AF_INET6); - else if (nm_device_activate_ip4_state_done (device)) { - nm_device_ip_method_failed (device, - AF_INET, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else if (nm_device_activate_ip6_state_done (device)) { - nm_device_ip_method_failed (device, - AF_INET6, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else { - _LOGW (LOGD_MB, "PPP failure in unexpected state %u", (guint) nm_device_get_state (device)); - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } - break; - default: - break; - } +ppp_failed(NMModem *modem, guint i_reason, gpointer user_data) +{ + NMDevice * device = NM_DEVICE(user_data); + NMDeviceModem * self = NM_DEVICE_MODEM(user_data); + NMDeviceStateReason reason = i_reason; + + switch (nm_device_get_state(device)) { + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, reason); + break; + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + if (nm_device_activate_ip4_state_in_conf(device)) + nm_device_activate_schedule_ip_config_timeout(device, AF_INET); + else if (nm_device_activate_ip6_state_in_conf(device)) + nm_device_activate_schedule_ip_config_timeout(device, AF_INET6); + else if (nm_device_activate_ip4_state_done(device)) { + nm_device_ip_method_failed(device, + AF_INET, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else if (nm_device_activate_ip6_state_done(device)) { + nm_device_ip_method_failed(device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW(LOGD_MB, + "PPP failure in unexpected state %u", + (guint) nm_device_get_state(device)); + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + break; + default: + break; + } } static void -modem_prepare_result (NMModem *modem, - gboolean success, - guint i_reason, - gpointer user_data) -{ - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - NMDevice *device = NM_DEVICE (self); - NMDeviceStateReason reason = i_reason; - - if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE - || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) { - nm_assert_not_reached (); - success = FALSE; - } - - if (!success) { - /* There are several reasons to block autoconnection at device level: - * - * - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense - * to retry the connection with the same PIN. This error also makes autoconnection - * blocked at settings level, so not even a modem unplug and replug will allow - * autoconnection again. It is somewhat redundant to block autoconnection at - * both device and setting level really. - * - * - SIM wrong or not inserted: If the modem is reporting a SIM not inserted error, - * we can block autoconnection at device level, so that if the same device is - * unplugged and replugged with a SIM (or if a SIM hotplug event happens in MM, - * recreating the device completely), we can try the autoconnection again. - * - * - Modem initialization failed: For some reason unknown to NM, the modem wasn't - * initialized correctly, which leads to an unusable device. A device unplug and - * replug may solve the issue, so make it a device-level autoconnection blocking - * reason. - */ - switch (nm_device_state_reason_check (reason)) { - case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: - case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: - case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: - nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN); - break; - case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: - case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: - nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING); - break; - case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: - nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED); - break; - default: - break; - } - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - return; - } - - priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); +modem_prepare_result(NMModem *modem, gboolean success, guint i_reason, gpointer user_data) +{ + NMDeviceModem * self = NM_DEVICE_MODEM(user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + NMDevice * device = NM_DEVICE(self); + NMDeviceStateReason reason = i_reason; + + if (nm_device_get_state(device) != NM_DEVICE_STATE_PREPARE + || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) { + nm_assert_not_reached(); + success = FALSE; + } + + if (!success) { + /* There are several reasons to block autoconnection at device level: + * + * - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense + * to retry the connection with the same PIN. This error also makes autoconnection + * blocked at settings level, so not even a modem unplug and replug will allow + * autoconnection again. It is somewhat redundant to block autoconnection at + * both device and setting level really. + * + * - SIM wrong or not inserted: If the modem is reporting a SIM not inserted error, + * we can block autoconnection at device level, so that if the same device is + * unplugged and replugged with a SIM (or if a SIM hotplug event happens in MM, + * recreating the device completely), we can try the autoconnection again. + * + * - Modem initialization failed: For some reason unknown to NM, the modem wasn't + * initialized correctly, which leads to an unusable device. A device unplug and + * replug may solve the issue, so make it a device-level autoconnection blocking + * reason. + */ + switch (nm_device_state_reason_check(reason)) { + case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: + case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: + case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: + nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN); + break; + case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: + case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: + nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_SIM_MISSING); + break; + case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: + nm_device_autoconnect_blocked_set(device, NM_DEVICE_AUTOCONNECT_BLOCKED_INIT_FAILED); + break; + default: + break; + } + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, reason); + return; + } + + priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -modem_auth_requested (NMModem *modem, gpointer user_data) +modem_auth_requested(NMModem *modem, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled - * during activation. - */ - if (!nm_device_is_activating (device)) - return; + /* Auth requests (PIN, PAP/CHAP passwords, etc) only get handled + * during activation. + */ + if (!nm_device_is_activating(device)) + return; - nm_device_state_changed (device, - NM_DEVICE_STATE_NEED_AUTH, - NM_DEVICE_STATE_REASON_NONE); + nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); } static void -modem_auth_result (NMModem *modem, GError *error, gpointer user_data) +modem_auth_result(NMModem *modem, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDevice * device = NM_DEVICE(user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_NEED_AUTH); - if (error) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } + if (error) { + nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); + return; + } - priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; - nm_device_activate_schedule_stage1_device_prepare (device, FALSE); + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; + nm_device_activate_schedule_stage1_device_prepare(device, FALSE); } static void -modem_ip4_config_result (NMModem *modem, - NMIP4Config *config, - GError *error, - gpointer user_data) +modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDevice *device = NM_DEVICE (self); + NMDeviceModem *self = NM_DEVICE_MODEM(user_data); + NMDevice * device = NM_DEVICE(self); - g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); + g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE); - if (error) { - _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", - error->message); - nm_device_ip_method_failed (device, - AF_INET, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else { - nm_device_set_dev2_ip_config (device, AF_INET, NM_IP_CONFIG_CAST (config)); - nm_device_activate_schedule_ip_config_result (device, AF_INET, NULL); - } + if (error) { + _LOGW(LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message); + nm_device_ip_method_failed(device, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG_CAST(config)); + nm_device_activate_schedule_ip_config_result(device, AF_INET, NULL); + } } static void -modem_ip6_config_result (NMModem *modem, - NMIP6Config *config, - gboolean do_slaac, - GError *error, - gpointer user_data) -{ - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDevice *device = NM_DEVICE (self); - NMActStageReturn ret; - NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - gs_unref_object NMIP6Config *ignored = NULL; - gboolean got_config = !!config; - - g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); - - if (error) { - _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", - error->message); - nm_device_ip_method_failed (device, - AF_INET6, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return; - } - - /* Re-enable IPv6 on the interface */ - nm_device_sysctl_ip_conf_set (device, AF_INET6, "disable_ipv6", "0"); - - if (config) - nm_device_set_dev2_ip_config (device, AF_INET6, NM_IP_CONFIG_CAST (config)); - - if (do_slaac == FALSE) { - if (got_config) - nm_device_activate_schedule_ip_config_result (device, AF_INET6, NULL); - else { - _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); - nm_device_ip_method_failed (device, - AF_INET6, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } - return; - } - - /* Start SLAAC now that we have a link-local address from the modem */ - ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip_config_start (device, AF_INET6, (gpointer *) &ignored, &failure_reason); - - nm_assert (ignored == NULL); - - switch (ret) { - case NM_ACT_STAGE_RETURN_FAILURE: - nm_device_ip_method_failed (device, AF_INET6, failure_reason); - break; - case NM_ACT_STAGE_RETURN_IP_FAIL: - /* all done */ - nm_device_activate_schedule_ip_config_result (device, AF_INET6, NULL); - break; - case NM_ACT_STAGE_RETURN_POSTPONE: - /* let SLAAC run */ - break; - default: - /* Should never get here since we've assured that the IPv6 method - * will either be "auto" or "ignored" when starting IPv6 configuration. - */ - nm_assert_not_reached (); - } +modem_ip6_config_result(NMModem * modem, + NMIP6Config *config, + gboolean do_slaac, + GError * error, + gpointer user_data) +{ + NMDeviceModem * self = NM_DEVICE_MODEM(user_data); + NMDevice * device = NM_DEVICE(self); + NMActStageReturn ret; + NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; + gs_unref_object NMIP6Config *ignored = NULL; + gboolean got_config = !!config; + + g_return_if_fail(nm_device_activate_ip6_state_in_conf(device) == TRUE); + + if (error) { + _LOGW(LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message); + nm_device_ip_method_failed(device, AF_INET6, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + /* Re-enable IPv6 on the interface */ + nm_device_sysctl_ip_conf_set(device, AF_INET6, "disable_ipv6", "0"); + + if (config) + nm_device_set_dev2_ip_config(device, AF_INET6, NM_IP_CONFIG_CAST(config)); + + if (do_slaac == FALSE) { + if (got_config) + nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL); + else { + _LOGW(LOGD_MB | LOGD_IP6, + "retrieving IPv6 configuration failed: SLAAC not requested and no addresses"); + nm_device_ip_method_failed(device, + AF_INET6, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } + return; + } + + /* Start SLAAC now that we have a link-local address from the modem */ + ret = + NM_DEVICE_CLASS(nm_device_modem_parent_class) + ->act_stage3_ip_config_start(device, AF_INET6, (gpointer *) &ignored, &failure_reason); + + nm_assert(ignored == NULL); + + switch (ret) { + case NM_ACT_STAGE_RETURN_FAILURE: + nm_device_ip_method_failed(device, AF_INET6, failure_reason); + break; + case NM_ACT_STAGE_RETURN_IP_FAIL: + /* all done */ + nm_device_activate_schedule_ip_config_result(device, AF_INET6, NULL); + break; + case NM_ACT_STAGE_RETURN_POSTPONE: + /* let SLAAC run */ + break; + default: + /* Should never get here since we've assured that the IPv6 method + * will either be "auto" or "ignored" when starting IPv6 configuration. + */ + nm_assert_not_reached(); + } } static void -ip_ifindex_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) +ip_ifindex_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE(user_data); - if (!nm_device_is_activating (device)) - return; + if (!nm_device_is_activating(device)) + return; - if (!nm_device_set_ip_ifindex (device, - nm_modem_get_ip_ifindex (modem))) { - nm_device_state_changed (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return; - } + if (!nm_device_set_ip_ifindex(device, nm_modem_get_ip_ifindex(modem))) { + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } - /* Disable IPv6 immediately on the interface since NM handles IPv6 - * internally, and leaving it enabled could allow the kernel's IPv6 - * RA handling code to run before NM is ready. - */ - nm_device_sysctl_ip_conf_set (device, AF_INET6, "disable_ipv6", "1"); + /* Disable IPv6 immediately on the interface since NM handles IPv6 + * internally, and leaving it enabled could allow the kernel's IPv6 + * RA handling code to run before NM is ready. + */ + nm_device_sysctl_ip_conf_set(device, AF_INET6, "disable_ipv6", "1"); } static void -operator_code_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) +operator_code_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - const char *operator_code = nm_modem_get_operator_code (modem); + NMDeviceModem * self = NM_DEVICE_MODEM(user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + const char * operator_code = nm_modem_get_operator_code(modem); - if (g_strcmp0 (priv->operator_code, operator_code) != 0) { - g_free (priv->operator_code); - priv->operator_code = g_strdup (operator_code); - _notify (self, PROP_OPERATOR_CODE); - } + if (g_strcmp0(priv->operator_code, operator_code) != 0) { + g_free(priv->operator_code); + priv->operator_code = g_strdup(operator_code); + _notify(self, PROP_OPERATOR_CODE); + } } static void -apn_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) +apn_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - const char *apn = nm_modem_get_apn (modem); + NMDeviceModem * self = NM_DEVICE_MODEM(user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + const char * apn = nm_modem_get_apn(modem); - if (g_strcmp0 (priv->apn, apn) != 0) { - g_free (priv->apn); - priv->apn = g_strdup (apn); - _notify (self, PROP_APN); - } + if (g_strcmp0(priv->apn, apn) != 0) { + g_free(priv->apn); + priv->apn = g_strdup(apn); + _notify(self, PROP_APN); + } } static void -ids_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) +ids_changed_cb(NMModem *modem, GParamSpec *pspec, gpointer user_data) { - nm_device_recheck_available_connections (NM_DEVICE (user_data)); + nm_device_recheck_available_connections(NM_DEVICE(user_data)); } static void -modem_state_cb (NMModem *modem, - int new_state_i, - int old_state_i, - gpointer user_data) -{ - NMModemState new_state = new_state_i; - NMModemState old_state = old_state_i; - NMDevice *device = NM_DEVICE (user_data); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMDeviceState dev_state = nm_device_get_state (device); - - if (new_state <= NM_MODEM_STATE_DISABLING && - old_state > NM_MODEM_STATE_DISABLING && - priv->rf_enabled) { - /* Called when the ModemManager modem enabled state is changed externally - * to NetworkManager (eg something using MM's D-Bus API directly). - */ - if (nm_device_is_activating (device) || dev_state == NM_DEVICE_STATE_ACTIVATED) { - /* user-initiated action, hence DISCONNECTED not FAILED */ - nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - return; - } - } - - if (new_state < NM_MODEM_STATE_CONNECTING && - old_state >= NM_MODEM_STATE_CONNECTING && - dev_state >= NM_DEVICE_STATE_NEED_AUTH && - dev_state <= NM_DEVICE_STATE_ACTIVATED) { - /* Fail the device if the modem disconnects unexpectedly while the - * device is activating/activated. */ - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return; - } - - if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) { - /* If the modem is now unlocked, enable/disable it according to the - * device's enabled/disabled state. - */ - nm_modem_set_mm_enabled (priv->modem, priv->rf_enabled); - - if (dev_state == NM_DEVICE_STATE_NEED_AUTH) { - /* The modem was unlocked externally to NetworkManager, - deactivate so the default connection can be - automatically activated again */ - nm_device_state_changed (device, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_MODEM_AVAILABLE); - } - - /* Now allow connections without a PIN to be available */ - nm_device_recheck_available_connections (device); - } - - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, - NM_DEVICE_STATE_REASON_MODEM_FAILED); +modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_data) +{ + NMModemState new_state = new_state_i; + NMModemState old_state = old_state_i; + NMDevice * device = NM_DEVICE(user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + NMDeviceState dev_state = nm_device_get_state(device); + + if (new_state <= NM_MODEM_STATE_DISABLING && old_state > NM_MODEM_STATE_DISABLING + && priv->rf_enabled) { + /* Called when the ModemManager modem enabled state is changed externally + * to NetworkManager (eg something using MM's D-Bus API directly). + */ + if (nm_device_is_activating(device) || dev_state == NM_DEVICE_STATE_ACTIVATED) { + /* user-initiated action, hence DISCONNECTED not FAILED */ + nm_device_state_changed(device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + return; + } + } + + if (new_state < NM_MODEM_STATE_CONNECTING && old_state >= NM_MODEM_STATE_CONNECTING + && dev_state >= NM_DEVICE_STATE_NEED_AUTH && dev_state <= NM_DEVICE_STATE_ACTIVATED) { + /* Fail the device if the modem disconnects unexpectedly while the + * device is activating/activated. */ + nm_device_state_changed(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return; + } + + if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) { + /* If the modem is now unlocked, enable/disable it according to the + * device's enabled/disabled state. + */ + nm_modem_set_mm_enabled(priv->modem, priv->rf_enabled); + + if (dev_state == NM_DEVICE_STATE_NEED_AUTH) { + /* The modem was unlocked externally to NetworkManager, + * deactivate so the default connection can be + * automatically activated again */ + nm_device_state_changed(device, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE); + } + + /* Now allow connections without a PIN to be available */ + nm_device_recheck_available_connections(device); + } + + nm_device_queue_recheck_available(device, + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, + NM_DEVICE_STATE_REASON_MODEM_FAILED); } static void -modem_removed_cb (NMModem *modem, gpointer user_data) +modem_removed_cb(NMModem *modem, gpointer user_data) { - g_signal_emit_by_name (NM_DEVICE (user_data), NM_DEVICE_REMOVED); + g_signal_emit_by_name(NM_DEVICE(user_data), NM_DEVICE_REMOVED); } /*****************************************************************************/ static gboolean -owns_iface (NMDevice *device, const char *iface) +owns_iface(NMDevice *device, const char *iface) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - g_return_val_if_fail (priv->modem, FALSE); + g_return_val_if_fail(priv->modem, FALSE); - return nm_modem_owns_port (priv->modem, iface); + return nm_modem_owns_port(priv->modem, iface); } /*****************************************************************************/ static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason) +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason) { - NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + NMDeviceModem * self = NM_DEVICE_MODEM(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); - g_return_if_fail (priv->modem); + g_return_if_fail(priv->modem); - if (new_state == NM_DEVICE_STATE_UNAVAILABLE && - old_state < NM_DEVICE_STATE_UNAVAILABLE) { - /* Log initial modem state */ - _LOGI (LOGD_MB, "modem state '%s'", - nm_modem_state_to_string (nm_modem_get_state (priv->modem))); - } - nm_modem_device_state_changed (priv->modem, new_state, old_state); + if (new_state == NM_DEVICE_STATE_UNAVAILABLE && old_state < NM_DEVICE_STATE_UNAVAILABLE) { + /* Log initial modem state */ + _LOGI(LOGD_MB, + "modem state '%s'", + nm_modem_state_to_string(nm_modem_get_state(priv->modem))); + } + nm_modem_device_state_changed(priv->modem, new_state, old_state); } static NMDeviceCapabilities -get_generic_capabilities (NMDevice *device) +get_generic_capabilities(NMDevice *device) { - return NM_DEVICE_CAP_IS_NON_KERNEL; + return NM_DEVICE_CAP_IS_NON_KERNEL; } static const char * -get_type_description (NMDevice *device) +get_type_description(NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - if (NM_FLAGS_HAS (priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)) - return "gsm"; - if (NM_FLAGS_HAS (priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) - return "cdma"; - return NM_DEVICE_CLASS (nm_device_modem_parent_class)->get_type_description (device); + if (NM_FLAGS_HAS(priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)) + return "gsm"; + if (NM_FLAGS_HAS(priv->current_caps, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) + return "cdma"; + return NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_type_description(device); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) -{ - GError *local = NULL; - - if (!NM_DEVICE_CLASS (nm_device_modem_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - if (!nm_modem_check_connection_compatible (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - connection, - error ? &local : NULL)) { - if (error) { - g_set_error (error, - NM_UTILS_ERROR, - g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE) - ? NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE - : NM_UTILS_ERROR_UNKNOWN, - "modem is incompatible with connection: %s", - local->message); - g_error_free (local); - } - return FALSE; - } - return TRUE; +check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + GError *local = NULL; + + if (!NM_DEVICE_CLASS(nm_device_modem_parent_class) + ->check_connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_modem_check_connection_compatible(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, + connection, + error ? &local : NULL)) { + if (error) { + g_set_error(error, + NM_UTILS_ERROR, + g_error_matches(local, + NM_UTILS_ERROR, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE) + ? NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE + : NM_UTILS_ERROR_UNKNOWN, + "modem is incompatible with connection: %s", + local->message); + g_error_free(local); + } + return FALSE; + } + return TRUE; } static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) -{ - NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - NMModemState state; - - if (!priv->rf_enabled) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "RFKILL for modem enabled"); - return FALSE; - } - - if (!priv->modem) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem not available"); - return FALSE; - } - - state = nm_modem_get_state (priv->modem); - if (state <= NM_MODEM_STATE_INITIALIZING) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem not initialized"); - return FALSE; - } - - if (state == NM_MODEM_STATE_LOCKED) { - if (!nm_connection_get_setting_gsm (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem is locked without pin available"); - return FALSE; - } - } - - return TRUE; +check_connection_available(NMDevice * device, + NMConnection * connection, + NMDeviceCheckConAvailableFlags flags, + const char * specific_object, + GError ** error) +{ + NMDeviceModem * self = NM_DEVICE_MODEM(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + NMModemState state; + + if (!priv->rf_enabled) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "RFKILL for modem enabled"); + return FALSE; + } + + if (!priv->modem) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "modem not available"); + return FALSE; + } + + state = nm_modem_get_state(priv->modem); + if (state <= NM_MODEM_STATE_INITIALIZING) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "modem not initialized"); + return FALSE; + } + + if (state == NM_MODEM_STATE_LOCKED) { + if (!nm_connection_get_setting_gsm(connection)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "modem is locked without pin available"); + return FALSE; + } + } + + return TRUE; } static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - return nm_modem_complete_connection (priv->modem, - nm_device_get_iface (device), - connection, - existing_connections, - error); + return nm_modem_complete_connection(priv->modem, + nm_device_get_iface(device), + connection, + existing_connections, + error); } static void -deactivate (NMDevice *device) +deactivate(NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - nm_modem_deactivate (priv->modem, device); - priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; + nm_modem_deactivate(priv->modem, device); + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; } /*****************************************************************************/ static void -modem_deactivate_async_cb (NMModem *modem, - GError *error, - gpointer user_data) +modem_deactivate_async_cb(NMModem *modem, GError *error, gpointer user_data) { - gs_unref_object NMDevice *self = NULL; - NMDeviceDeactivateCallback callback; - gpointer callback_user_data; + gs_unref_object NMDevice * self = NULL; + NMDeviceDeactivateCallback callback; + gpointer callback_user_data; - nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data); - callback (self, error, callback_user_data); + nm_utils_user_data_unpack(user_data, &self, &callback, &callback_user_data); + callback(self, error, callback_user_data); } static void -deactivate_async (NMDevice *self, - GCancellable *cancellable, - NMDeviceDeactivateCallback callback, - gpointer user_data) +deactivate_async(NMDevice * self, + GCancellable * cancellable, + NMDeviceDeactivateCallback callback, + gpointer user_data) { - nm_assert (G_IS_CANCELLABLE (cancellable)); - nm_assert (callback); + nm_assert(G_IS_CANCELLABLE(cancellable)); + nm_assert(callback); - nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE (self)->modem, - self, - cancellable, - modem_deactivate_async_cb, - nm_utils_user_data_pack (g_object_ref (self), - callback, - user_data)); + nm_modem_deactivate_async(NM_DEVICE_MODEM_GET_PRIVATE(self)->modem, + self, + cancellable, + modem_deactivate_async_cb, + nm_utils_user_data_pack(g_object_ref(self), callback, user_data)); } /*****************************************************************************/ static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMActRequest *req; + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + NMActRequest * req; - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); - if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) { - priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; - return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - req, - out_failure_reason); - } + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) { + priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; + return nm_modem_act_stage1_prepare(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, + req, + out_failure_reason); + } - if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) - return NM_ACT_STAGE_RETURN_POSTPONE; + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; - nm_assert (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED); - return NM_ACT_STAGE_RETURN_SUCCESS; + nm_assert(priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED); + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) { - nm_modem_act_stage2_config (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem); - return NM_ACT_STAGE_RETURN_SUCCESS; + nm_modem_act_stage2_config(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem); + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn -act_stage3_ip_config_start (NMDevice *device, - int addr_family, - gpointer *out_config, - NMDeviceStateReason *out_failure_reason) +act_stage3_ip_config_start(NMDevice * device, + int addr_family, + gpointer * out_config, + NMDeviceStateReason *out_failure_reason) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start (priv->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), - out_failure_reason); - } else { - return nm_modem_stage3_ip6_config_start (priv->modem, - device, - out_failure_reason); - } + if (addr_family == AF_INET) { + return nm_modem_stage3_ip4_config_start(priv->modem, + device, + NM_DEVICE_CLASS(nm_device_modem_parent_class), + out_failure_reason); + } else { + return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); + } } static void -ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) +ip4_config_pre_commit(NMDevice *device, NMIP4Config *config) { - nm_modem_ip4_pre_commit (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device, config); + nm_modem_ip4_pre_commit(NM_DEVICE_MODEM_GET_PRIVATE(device)->modem, device, config); } static gboolean -get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid) +get_ip_iface_identifier(NMDevice *device, NMUtilsIPv6IfaceId *out_iid) { - NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - gboolean success; + NMDeviceModem * self = NM_DEVICE_MODEM(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + gboolean success; - g_return_val_if_fail (priv->modem, FALSE); - success = nm_modem_get_iid (priv->modem, out_iid); - if (!success) - success = NM_DEVICE_CLASS (nm_device_modem_parent_class)->get_ip_iface_identifier (device, out_iid); - return success; + g_return_val_if_fail(priv->modem, FALSE); + success = nm_modem_get_iid(priv->modem, out_iid); + if (!success) + success = + NM_DEVICE_CLASS(nm_device_modem_parent_class)->get_ip_iface_identifier(device, out_iid); + return success; } /*****************************************************************************/ static gboolean -get_enabled (NMDevice *device) +get_enabled(NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMModemState modem_state = nm_modem_get_state (priv->modem); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + NMModemState modem_state = nm_modem_get_state(priv->modem); - return priv->rf_enabled && (modem_state >= NM_MODEM_STATE_LOCKED); + return priv->rf_enabled && (modem_state >= NM_MODEM_STATE_LOCKED); } static void -set_enabled (NMDevice *device, gboolean enabled) +set_enabled(NMDevice *device, gboolean enabled) { - NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + NMDeviceModem * self = NM_DEVICE_MODEM(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); - /* Called only by the Manager in response to rfkill switch changes or - * global user WWAN enable/disable preference changes. - */ - priv->rf_enabled = enabled; + /* Called only by the Manager in response to rfkill switch changes or + * global user WWAN enable/disable preference changes. + */ + priv->rf_enabled = enabled; - if (priv->modem) { - /* Sync the ModemManager modem enabled/disabled with rfkill/user preference */ - nm_modem_set_mm_enabled (priv->modem, enabled); - } + if (priv->modem) { + /* Sync the ModemManager modem enabled/disabled with rfkill/user preference */ + nm_modem_set_mm_enabled(priv->modem, enabled); + } - if (enabled == FALSE) { - nm_device_state_changed (device, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_NONE); - } + if (enabled == FALSE) { + nm_device_state_changed(device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NONE); + } } static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { - NMDeviceModem *self = NM_DEVICE_MODEM (device); - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); - NMModemState modem_state; + NMDeviceModem * self = NM_DEVICE_MODEM(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); + NMModemState modem_state; - if (!priv->rf_enabled) - return FALSE; + if (!priv->rf_enabled) + return FALSE; - g_assert (priv->modem); - modem_state = nm_modem_get_state (priv->modem); - if (modem_state <= NM_MODEM_STATE_INITIALIZING) - return FALSE; + g_assert(priv->modem); + modem_state = nm_modem_get_state(priv->modem); + if (modem_state <= NM_MODEM_STATE_INITIALIZING) + return FALSE; - return TRUE; + return TRUE; } /*****************************************************************************/ static void -set_modem (NMDeviceModem *self, NMModem *modem) +set_modem(NMDeviceModem *self, NMModem *modem) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(self); - g_return_if_fail (modem != NULL); + g_return_if_fail(modem != NULL); - priv->modem = nm_modem_claim (modem); + priv->modem = nm_modem_claim(modem); - g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); - g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); - g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); - g_signal_connect (modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK (modem_ip6_config_result), self); - g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); - g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); - g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); - g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); + g_signal_connect(modem, NM_MODEM_PPP_FAILED, G_CALLBACK(ppp_failed), self); + g_signal_connect(modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK(modem_prepare_result), self); + g_signal_connect(modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK(modem_ip4_config_result), self); + g_signal_connect(modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK(modem_ip6_config_result), self); + g_signal_connect(modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK(modem_auth_requested), self); + g_signal_connect(modem, NM_MODEM_AUTH_RESULT, G_CALLBACK(modem_auth_result), self); + g_signal_connect(modem, NM_MODEM_STATE_CHANGED, G_CALLBACK(modem_state_cb), self); + g_signal_connect(modem, NM_MODEM_REMOVED, G_CALLBACK(modem_removed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_IP_IFINDEX, G_CALLBACK (ip_ifindex_changed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_DEVICE_ID, G_CALLBACK (ids_changed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_SIM_ID, G_CALLBACK (ids_changed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_SIM_OPERATOR_ID, G_CALLBACK (ids_changed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_OPERATOR_CODE, G_CALLBACK (operator_code_changed_cb), self); - g_signal_connect (modem, "notify::" NM_MODEM_APN, G_CALLBACK (apn_changed_cb), self); + g_signal_connect(modem, + "notify::" NM_MODEM_IP_IFINDEX, + G_CALLBACK(ip_ifindex_changed_cb), + self); + g_signal_connect(modem, "notify::" NM_MODEM_DEVICE_ID, G_CALLBACK(ids_changed_cb), self); + g_signal_connect(modem, "notify::" NM_MODEM_SIM_ID, G_CALLBACK(ids_changed_cb), self); + g_signal_connect(modem, "notify::" NM_MODEM_SIM_OPERATOR_ID, G_CALLBACK(ids_changed_cb), self); + g_signal_connect(modem, + "notify::" NM_MODEM_OPERATOR_CODE, + G_CALLBACK(operator_code_changed_cb), + self); + g_signal_connect(modem, "notify::" NM_MODEM_APN, G_CALLBACK(apn_changed_cb), self); } static guint32 -get_dhcp_timeout_for_device (NMDevice *device, int addr_family) +get_dhcp_timeout_for_device(NMDevice *device, int addr_family) { - /* DHCP is always done by the modem firmware, not by the network, and - * by the time we get around to DHCP the firmware should already know - * the IP addressing details. So the DHCP timeout can be much shorter. - */ - return 15; + /* DHCP is always done by the modem firmware, not by the network, and + * by the time we get around to DHCP the firmware should already know + * the IP addressing details. So the DHCP timeout can be much shorter. + */ + return 15; } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MODEM: - g_value_set_object (value, priv->modem); - break; - case PROP_CAPABILITIES: - g_value_set_uint (value, priv->caps); - break; - case PROP_CURRENT_CAPABILITIES: - g_value_set_uint (value, priv->current_caps); - break; - case PROP_DEVICE_ID: - g_value_set_string (value, priv->device_id); - break; - case PROP_OPERATOR_CODE: - g_value_set_string (value, priv->operator_code); - break; - case PROP_APN: - g_value_set_string (value, priv->apn); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODEM: + g_value_set_object(value, priv->modem); + break; + case PROP_CAPABILITIES: + g_value_set_uint(value, priv->caps); + break; + case PROP_CURRENT_CAPABILITIES: + g_value_set_uint(value, priv->current_caps); + break; + case PROP_DEVICE_ID: + g_value_set_string(value, priv->device_id); + break; + case PROP_OPERATOR_CODE: + g_value_set_string(value, priv->operator_code); + break; + case PROP_APN: + g_value_set_string(value, priv->apn); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_MODEM: - /* construct-only */ - set_modem (NM_DEVICE_MODEM (object), g_value_get_object (value)); - break; - case PROP_CAPABILITIES: - priv->caps = g_value_get_uint (value); - break; - case PROP_CURRENT_CAPABILITIES: - priv->current_caps = g_value_get_uint (value); - break; - case PROP_DEVICE_ID: - /* construct-only */ - priv->device_id = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODEM: + /* construct-only */ + set_modem(NM_DEVICE_MODEM(object), g_value_get_object(value)); + break; + case PROP_CAPABILITIES: + priv->caps = g_value_get_uint(value); + break; + case PROP_CURRENT_CAPABILITIES: + priv->current_caps = g_value_get_uint(value); + break; + case PROP_DEVICE_ID: + /* construct-only */ + priv->device_id = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_device_modem_init (NMDeviceModem *self) -{ -} +nm_device_modem_init(NMDeviceModem *self) +{} NMDevice * -nm_device_modem_new (NMModem *modem) -{ - NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; - NMDeviceModemCapabilities current_caps = NM_DEVICE_MODEM_CAPABILITY_NONE; - - g_return_val_if_fail (NM_IS_MODEM (modem), NULL); - - /* Load capabilities */ - nm_modem_get_capabilities (modem, &caps, ¤t_caps); - - return g_object_new (NM_TYPE_DEVICE_MODEM, - NM_DEVICE_UDI, nm_modem_get_path (modem), - NM_DEVICE_IFACE, nm_modem_get_uid (modem), - NM_DEVICE_DRIVER, nm_modem_get_driver (modem), - NM_DEVICE_TYPE_DESC, "Broadband", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM, - NM_DEVICE_RFKILL_TYPE, RFKILL_TYPE_WWAN, - NM_DEVICE_MODEM_MODEM, modem, - NM_DEVICE_MODEM_CAPABILITIES, caps, - NM_DEVICE_MODEM_CURRENT_CAPABILITIES, current_caps, - NM_DEVICE_MODEM_DEVICE_ID, nm_modem_get_device_id (modem), - NULL); +nm_device_modem_new(NMModem *modem) +{ + NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; + NMDeviceModemCapabilities current_caps = NM_DEVICE_MODEM_CAPABILITY_NONE; + + g_return_val_if_fail(NM_IS_MODEM(modem), NULL); + + /* Load capabilities */ + nm_modem_get_capabilities(modem, &caps, ¤t_caps); + + return g_object_new(NM_TYPE_DEVICE_MODEM, + NM_DEVICE_UDI, + nm_modem_get_path(modem), + NM_DEVICE_IFACE, + nm_modem_get_uid(modem), + NM_DEVICE_DRIVER, + nm_modem_get_driver(modem), + NM_DEVICE_TYPE_DESC, + "Broadband", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_MODEM, + NM_DEVICE_RFKILL_TYPE, + RFKILL_TYPE_WWAN, + NM_DEVICE_MODEM_MODEM, + modem, + NM_DEVICE_MODEM_CAPABILITIES, + caps, + NM_DEVICE_MODEM_CURRENT_CAPABILITIES, + current_caps, + NM_DEVICE_MODEM_DEVICE_ID, + nm_modem_get_device_id(modem), + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(object); - if (priv->modem) { - g_signal_handlers_disconnect_by_data (priv->modem, NM_DEVICE_MODEM (object)); - nm_clear_pointer (&priv->modem, nm_modem_unclaim); - } + if (priv->modem) { + g_signal_handlers_disconnect_by_data(priv->modem, NM_DEVICE_MODEM(object)); + nm_clear_pointer(&priv->modem, nm_modem_unclaim); + } - nm_clear_g_free (&priv->device_id); - nm_clear_g_free (&priv->operator_code); - nm_clear_g_free (&priv->apn); + nm_clear_g_free(&priv->device_id); + nm_clear_g_free(&priv->operator_code); + nm_clear_g_free(&priv->apn); - G_OBJECT_CLASS (nm_device_modem_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_device_modem_parent_class)->dispose(object); } static const NMDBusInterfaceInfoExtended interface_info_device_modem = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_MODEM, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( - &nm_signal_info_property_changed_legacy, - ), - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ModemCapabilities", "u", NM_DEVICE_MODEM_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CurrentCapabilities", "u", NM_DEVICE_MODEM_CURRENT_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("DeviceId", "s", NM_DEVICE_MODEM_DEVICE_ID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("OperatorCode", "s", NM_DEVICE_MODEM_OPERATOR_CODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Apn", "s", NM_DEVICE_MODEM_APN), - ), - ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_MODEM, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ModemCapabilities", + "u", + NM_DEVICE_MODEM_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CurrentCapabilities", + "u", + NM_DEVICE_MODEM_CURRENT_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceId", + "s", + NM_DEVICE_MODEM_DEVICE_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("OperatorCode", + "s", + NM_DEVICE_MODEM_OPERATOR_CODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Apn", "s", NM_DEVICE_MODEM_APN), ), ), + .legacy_property_changed = TRUE, }; static void -nm_device_modem_class_init (NMDeviceModemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_modem); - - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_type_description = get_type_description; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->deactivate_async = deactivate_async; - device_class->deactivate = deactivate; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; - device_class->ip4_config_pre_commit = ip4_config_pre_commit; - device_class->get_enabled = get_enabled; - device_class->set_enabled = set_enabled; - device_class->owns_iface = owns_iface; - device_class->is_available = is_available; - device_class->get_ip_iface_identifier = get_ip_iface_identifier; - device_class->get_configured_mtu = nm_modem_get_configured_mtu; - device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; - - device_class->state_changed = device_state_changed; - - obj_properties[PROP_MODEM] = - g_param_spec_object (NM_DEVICE_MODEM_MODEM, "", "", - NM_TYPE_MODEM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CURRENT_CAPABILITIES] = - g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_DEVICE_ID] = - g_param_spec_string (NM_DEVICE_MODEM_DEVICE_ID, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_OPERATOR_CODE] = - g_param_spec_string (NM_DEVICE_MODEM_OPERATOR_CODE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_APN] = - g_param_spec_string (NM_DEVICE_MODEM_APN, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +nm_device_modem_class_init(NMDeviceModemClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass * device_class = NM_DEVICE_CLASS(klass); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_modem); + + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->get_type_description = get_type_description; + device_class->check_connection_compatible = check_connection_compatible; + device_class->check_connection_available = check_connection_available; + device_class->complete_connection = complete_connection; + device_class->deactivate_async = deactivate_async; + device_class->deactivate = deactivate; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->act_stage2_config = act_stage2_config; + device_class->act_stage3_ip_config_start = act_stage3_ip_config_start; + device_class->ip4_config_pre_commit = ip4_config_pre_commit; + device_class->get_enabled = get_enabled; + device_class->set_enabled = set_enabled; + device_class->owns_iface = owns_iface; + device_class->is_available = is_available; + device_class->get_ip_iface_identifier = get_ip_iface_identifier; + device_class->get_configured_mtu = nm_modem_get_configured_mtu; + device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; + + device_class->state_changed = device_state_changed; + + obj_properties[PROP_MODEM] = + g_param_spec_object(NM_DEVICE_MODEM_MODEM, + "", + "", + NM_TYPE_MODEM, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_MODEM_CAPABILITIES, + "", + "", + 0, + G_MAXUINT32, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CURRENT_CAPABILITIES] = + g_param_spec_uint(NM_DEVICE_MODEM_CURRENT_CAPABILITIES, + "", + "", + 0, + G_MAXUINT32, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_DEVICE_ID] = + g_param_spec_string(NM_DEVICE_MODEM_DEVICE_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_OPERATOR_CODE] = + g_param_spec_string(NM_DEVICE_MODEM_OPERATOR_CODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_APN] = g_param_spec_string(NM_DEVICE_MODEM_APN, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/wwan/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h index 842096e2..caabeb6c 100644 --- a/src/devices/wwan/nm-device-modem.h +++ b/src/devices/wwan/nm-device-modem.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2011 Red Hat, Inc. */ @@ -9,25 +9,28 @@ #include "devices/nm-device.h" #include "nm-modem.h" -#define NM_TYPE_DEVICE_MODEM (nm_device_modem_get_type ()) -#define NM_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModem)) -#define NM_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) -#define NM_IS_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MODEM)) -#define NM_IS_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MODEM)) -#define NM_DEVICE_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) - -#define NM_DEVICE_MODEM_MODEM "modem" -#define NM_DEVICE_MODEM_CAPABILITIES "modem-capabilities" +#define NM_TYPE_DEVICE_MODEM (nm_device_modem_get_type()) +#define NM_DEVICE_MODEM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModem)) +#define NM_DEVICE_MODEM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) +#define NM_IS_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_MODEM)) +#define NM_IS_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_MODEM)) +#define NM_DEVICE_MODEM_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) + +#define NM_DEVICE_MODEM_MODEM "modem" +#define NM_DEVICE_MODEM_CAPABILITIES "modem-capabilities" #define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities" #define NM_DEVICE_MODEM_DEVICE_ID "device-id" #define NM_DEVICE_MODEM_OPERATOR_CODE "operator-code" #define NM_DEVICE_MODEM_APN "apn" -typedef struct _NMDeviceModem NMDeviceModem; +typedef struct _NMDeviceModem NMDeviceModem; typedef struct _NMDeviceModemClass NMDeviceModemClass; -GType nm_device_modem_get_type (void); +GType nm_device_modem_get_type(void); -NMDevice *nm_device_modem_new (NMModem *modem); +NMDevice *nm_device_modem_new(NMModem *modem); #endif /* __NETWORKMANAGER_DEVICE_MODEM_H__ */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 0929adaf..633878ce 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 Aleksander Morgado */ @@ -21,20 +21,20 @@ #define NM_MODEM_BROADBAND_MODEM "modem" static gboolean -MODEM_CAPS_3GPP (MMModemCapability caps) +MODEM_CAPS_3GPP(MMModemCapability caps) { - G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* MM_MODEM_CAPABILITY_LTE_ADVANCED is marked as deprecated since ModemManager 1.14.0. - * - * The flag probably was never used, it certainly isn't used since 1.14.0. - * - * Still, just to be sure, there is no harm in checking it here. Suppress the - * warning, it should have no bad effect. - */ - return NM_FLAGS_ANY (caps, ( MM_MODEM_CAPABILITY_GSM_UMTS - | MM_MODEM_CAPABILITY_LTE - | MM_MODEM_CAPABILITY_LTE_ADVANCED)); - G_GNUC_END_IGNORE_DEPRECATIONS + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + /* MM_MODEM_CAPABILITY_LTE_ADVANCED is marked as deprecated since ModemManager 1.14.0. + * + * The flag probably was never used, it certainly isn't used since 1.14.0. + * + * Still, just to be sure, there is no harm in checking it here. Suppress the + * warning, it should have no bad effect. + */ + return NM_FLAGS_ANY(caps, + (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE + | MM_MODEM_CAPABILITY_LTE_ADVANCED)); + G_GNUC_END_IGNORE_DEPRECATIONS } #define MODEM_CAPS_3GPP2(caps) (caps & (MM_MODEM_CAPABILITY_CDMA_EVDO)) @@ -45,1584 +45,1578 @@ MODEM_CAPS_3GPP (MMModemCapability caps) /*****************************************************************************/ typedef enum { - CONNECT_STEP_FIRST, - CONNECT_STEP_WAIT_FOR_SIM, - CONNECT_STEP_UNLOCK, - CONNECT_STEP_WAIT_FOR_READY, - CONNECT_STEP_CONNECT, - CONNECT_STEP_LAST, + CONNECT_STEP_FIRST, + CONNECT_STEP_WAIT_FOR_SIM, + CONNECT_STEP_UNLOCK, + CONNECT_STEP_WAIT_FOR_READY, + CONNECT_STEP_CONNECT, + CONNECT_STEP_LAST, } ConnectStep; typedef struct { - NMModemBroadband *self; - ConnectStep step; - - MMModemCapability caps; - NMConnection *connection; - GCancellable *cancellable; - MMSimpleConnectProperties *connect_properties; - GArray *ip_types; - guint ip_types_i; - guint ip_type_tries; - GError *first_error; + NMModemBroadband *self; + ConnectStep step; + + MMModemCapability caps; + NMConnection * connection; + GCancellable * cancellable; + MMSimpleConnectProperties *connect_properties; + GArray * ip_types; + guint ip_types_i; + guint ip_type_tries; + GError * first_error; } ConnectContext; /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_MODEM, -); +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_MODEM, ); typedef struct { - /* The modem object from dbus */ - MMObject *modem_object; - /* Per-interface objects */ - MMModem *modem_iface; - MMModem3gpp *modem_3gpp_iface; - MMModemSimple *simple_iface; - MMSim *sim_iface; + /* The modem object from dbus */ + MMObject *modem_object; + /* Per-interface objects */ + MMModem * modem_iface; + MMModem3gpp * modem_3gpp_iface; + MMModemSimple *simple_iface; + MMSim * sim_iface; - /* Connection setup */ - ConnectContext *ctx; + /* Connection setup */ + ConnectContext *ctx; - MMBearer *bearer; - MMBearerIpConfig *ipv4_config; - MMBearerIpConfig *ipv6_config; + MMBearer * bearer; + MMBearerIpConfig *ipv4_config; + MMBearerIpConfig *ipv6_config; - guint idle_id_ip4; - guint idle_id_ip6; + guint idle_id_ip4; + guint idle_id_ip6; - guint32 pin_tries; + guint32 pin_tries; } NMModemBroadbandPrivate; struct _NMModemBroadband { - NMModem parent; - NMModemBroadbandPrivate _priv; + NMModem parent; + NMModemBroadbandPrivate _priv; }; struct _NMModemBroadbandClass { - NMModemClass parent; + NMModemClass parent; }; -G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) +G_DEFINE_TYPE(NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) -#define NM_MODEM_BROADBAND_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMModemBroadband, NM_IS_MODEM_BROADBAND) +#define NM_MODEM_BROADBAND_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMModemBroadband, NM_IS_MODEM_BROADBAND) /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_MB #define _NMLOG_PREFIX_NAME "modem-broadband" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - const NMLogLevel _level = (level); \ - \ - if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ - NMModemBroadband *const __self = (self); \ - char __prefix_name[128]; \ - const char *__uid; \ - \ - _nm_log (_level, (_NMLOG_DOMAIN), 0, NULL, \ - ((__self && __self->_priv.ctx) \ - ? nm_connection_get_uuid (__self->_priv.ctx->connection) \ - : NULL), \ - "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - (__self \ - ? ({ \ - ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ - ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ - : "(null)"); \ - }) \ - : "") \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, (_NMLOG_DOMAIN))) { \ + NMModemBroadband *const __self = (self); \ + char __prefix_name[128]; \ + const char * __uid; \ + \ + _nm_log(_level, \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + ((__self && __self->_priv.ctx) \ + ? nm_connection_get_uuid(__self->_priv.ctx->connection) \ + : NULL), \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self ? ({ \ + ((__uid = nm_modem_get_uid((NMModem *) __self)) \ + ? nm_sprintf_buf(__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ static NMDeviceStateReason -translate_mm_error (NMModemBroadband *self, GError *error) +translate_mm_error(NMModemBroadband *self, GError *error) { - NMDeviceStateReason reason; - - g_return_val_if_fail (error != NULL, NM_DEVICE_STATE_REASON_UNKNOWN); - - if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_CARRIER)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; - else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_DIALTONE)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; - else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_BUSY)) - reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; - else if (g_error_matches (error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_ANSWER)) - reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; - else if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD)) - reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT; - else { - /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ - _LOGD ("unmapped error detected: '%s'", error->message); - reason = NM_DEVICE_STATE_REASON_UNKNOWN; - } - - return reason; + NMDeviceStateReason reason; + + g_return_val_if_fail(error != NULL, NM_DEVICE_STATE_REASON_UNKNOWN); + + if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_CARRIER)) + reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; + else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_DIALTONE)) + reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; + else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_BUSY)) + reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; + else if (g_error_matches(error, MM_CONNECTION_ERROR, MM_CONNECTION_ERROR_NO_ANSWER)) + reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; + else if (g_error_matches(error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; + else if (g_error_matches(error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; + else if (g_error_matches(error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK)) + reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; + else if (g_error_matches(error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; + else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; + else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; + else if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG)) + reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; + else if (g_error_matches(error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD)) + reason = NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT; + else { + /* unable to map the ModemManager error to a NM_DEVICE_STATE_REASON */ + _LOGD("unmapped error detected: '%s'", error->message); + reason = NM_DEVICE_STATE_REASON_UNKNOWN; + } + + return reason; } /*****************************************************************************/ static void -get_capabilities (NMModem *_self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) +get_capabilities(NMModem * _self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - MMModemCapability all_supported = MM_MODEM_CAPABILITY_NONE; - MMModemCapability *supported; - guint n_supported; + NMModemBroadband * self = NM_MODEM_BROADBAND(_self); + MMModemCapability all_supported = MM_MODEM_CAPABILITY_NONE; + MMModemCapability *supported; + guint n_supported; - /* For now, we don't care about the capability combinations, just merge all - * combinations in a single mask */ - if (mm_modem_get_supported_capabilities (self->_priv.modem_iface, &supported, &n_supported)) { - guint i; + /* For now, we don't care about the capability combinations, just merge all + * combinations in a single mask */ + if (mm_modem_get_supported_capabilities(self->_priv.modem_iface, &supported, &n_supported)) { + guint i; - for (i = 0; i < n_supported; i++) - all_supported |= supported[i]; + for (i = 0; i < n_supported; i++) + all_supported |= supported[i]; - g_free (supported); - } + g_free(supported); + } - *modem_caps = (NMDeviceModemCapabilities) all_supported; - *current_caps = (NMDeviceModemCapabilities) mm_modem_get_current_capabilities (self->_priv.modem_iface); + *modem_caps = (NMDeviceModemCapabilities) all_supported; + *current_caps = + (NMDeviceModemCapabilities) mm_modem_get_current_capabilities(self->_priv.modem_iface); } static gboolean -owns_port (NMModem *_self, const char *iface) +owns_port(NMModem *_self, const char *iface) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - const MMModemPortInfo *ports = NULL; - guint n_ports = 0, i; - - mm_modem_peek_ports (self->_priv.modem_iface, &ports, &n_ports); - for (i = 0; i < n_ports; i++) { - if (nm_streq0 (iface, ports[i].name)) - return TRUE; - } - return FALSE; + NMModemBroadband * self = NM_MODEM_BROADBAND(_self); + const MMModemPortInfo *ports = NULL; + guint n_ports = 0, i; + + mm_modem_peek_ports(self->_priv.modem_iface, &ports, &n_ports); + for (i = 0; i < n_ports; i++) { + if (nm_streq0(iface, ports[i].name)) + return TRUE; + } + return FALSE; } /*****************************************************************************/ static void -ask_for_pin (NMModemBroadband *self) +ask_for_pin(NMModemBroadband *self) { - guint32 tries; + guint32 tries; - tries = self->_priv.pin_tries++; - nm_modem_get_secrets (NM_MODEM (self), - NM_SETTING_GSM_SETTING_NAME, - tries ? TRUE : FALSE, - NM_SETTING_GSM_PIN); + tries = self->_priv.pin_tries++; + nm_modem_get_secrets(NM_MODEM(self), + NM_SETTING_GSM_SETTING_NAME, + tries ? TRUE : FALSE, + NM_SETTING_GSM_PIN); } static NMModemIPMethod -get_bearer_ip_method (MMBearerIpConfig *config) +get_bearer_ip_method(MMBearerIpConfig *config) { - MMBearerIpMethod mm_method; - - mm_method = mm_bearer_ip_config_get_method (config); - if (mm_method == MM_BEARER_IP_METHOD_PPP) - return NM_MODEM_IP_METHOD_PPP; - else if (mm_method == MM_BEARER_IP_METHOD_STATIC) - return NM_MODEM_IP_METHOD_STATIC; - else if (mm_method == MM_BEARER_IP_METHOD_DHCP) - return NM_MODEM_IP_METHOD_AUTO; - return NM_MODEM_IP_METHOD_UNKNOWN; + MMBearerIpMethod mm_method; + + mm_method = mm_bearer_ip_config_get_method(config); + if (mm_method == MM_BEARER_IP_METHOD_PPP) + return NM_MODEM_IP_METHOD_PPP; + else if (mm_method == MM_BEARER_IP_METHOD_STATIC) + return NM_MODEM_IP_METHOD_STATIC; + else if (mm_method == MM_BEARER_IP_METHOD_DHCP) + return NM_MODEM_IP_METHOD_AUTO; + return NM_MODEM_IP_METHOD_UNKNOWN; } static MMSimpleConnectProperties * -create_cdma_connect_properties (NMConnection *connection) +create_cdma_connect_properties(NMConnection *connection) { - MMSimpleConnectProperties *properties; + MMSimpleConnectProperties *properties; - properties = mm_simple_connect_properties_new (); + properties = mm_simple_connect_properties_new(); -#if !MM_CHECK_VERSION (1, 9, 1) - { - NMSettingCdma *setting; - const char *str; +#if !MM_CHECK_VERSION(1, 9, 1) + { + NMSettingCdma *setting; + const char * str; - setting = nm_connection_get_setting_cdma (connection); - str = nm_setting_cdma_get_number (setting); - if (str) - mm_simple_connect_properties_set_number (properties, str); - } + setting = nm_connection_get_setting_cdma(connection); + str = nm_setting_cdma_get_number(setting); + if (str) + mm_simple_connect_properties_set_number(properties, str); + } #endif - return properties; + return properties; } static MMSimpleConnectProperties * -create_gsm_connect_properties (NMConnection *connection, - const char *apn, - const char *username, - const char *password) +create_gsm_connect_properties(NMConnection *connection, + const char * apn, + const char * username, + const char * password) { - NMSettingGsm *setting; - NMSettingPpp *s_ppp; - MMSimpleConnectProperties *properties; - const char *str; - - setting = nm_connection_get_setting_gsm (connection); - - properties = mm_simple_connect_properties_new (); - - mm_simple_connect_properties_set_apn (properties, apn ?: ""); - if (username) - mm_simple_connect_properties_set_user (properties, username); - if (password) - mm_simple_connect_properties_set_password (properties, password); - - str = nm_setting_gsm_get_network_id (setting); - if (str) - mm_simple_connect_properties_set_operator_id (properties, str); - - str = nm_setting_gsm_get_pin (setting); - if (str) - mm_simple_connect_properties_set_pin (properties, str); - - /* Roaming */ - if (nm_setting_gsm_get_home_only (setting)) - mm_simple_connect_properties_set_allow_roaming (properties, FALSE); - - /* For IpMethod == STATIC or DHCP */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - MMBearerAllowedAuth allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN; - - if (nm_setting_ppp_get_noauth (s_ppp)) - allowed_auth = MM_BEARER_ALLOWED_AUTH_NONE; - if (!nm_setting_ppp_get_refuse_pap (s_ppp)) - allowed_auth |= MM_BEARER_ALLOWED_AUTH_PAP; - if (!nm_setting_ppp_get_refuse_chap (s_ppp)) - allowed_auth |= MM_BEARER_ALLOWED_AUTH_CHAP; - if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) - allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAP; - if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) - allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAPV2; - if (!nm_setting_ppp_get_refuse_eap (s_ppp)) - allowed_auth |= MM_BEARER_ALLOWED_AUTH_EAP; - - mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); - } - - return properties; + NMSettingGsm * setting; + NMSettingPpp * s_ppp; + MMSimpleConnectProperties *properties; + const char * str; + + setting = nm_connection_get_setting_gsm(connection); + + properties = mm_simple_connect_properties_new(); + + mm_simple_connect_properties_set_apn(properties, apn ?: ""); + if (username) + mm_simple_connect_properties_set_user(properties, username); + if (password) + mm_simple_connect_properties_set_password(properties, password); + + str = nm_setting_gsm_get_network_id(setting); + if (str) + mm_simple_connect_properties_set_operator_id(properties, str); + + str = nm_setting_gsm_get_pin(setting); + if (str) + mm_simple_connect_properties_set_pin(properties, str); + + /* Roaming */ + if (nm_setting_gsm_get_home_only(setting)) + mm_simple_connect_properties_set_allow_roaming(properties, FALSE); + + /* For IpMethod == STATIC or DHCP */ + s_ppp = nm_connection_get_setting_ppp(connection); + if (s_ppp) { + MMBearerAllowedAuth allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN; + + if (nm_setting_ppp_get_noauth(s_ppp)) + allowed_auth = MM_BEARER_ALLOWED_AUTH_NONE; + if (!nm_setting_ppp_get_refuse_pap(s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_PAP; + if (!nm_setting_ppp_get_refuse_chap(s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_CHAP; + if (!nm_setting_ppp_get_refuse_mschap(s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAP; + if (!nm_setting_ppp_get_refuse_mschapv2(s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAPV2; + if (!nm_setting_ppp_get_refuse_eap(s_ppp)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_EAP; + + mm_simple_connect_properties_set_allowed_auth(properties, allowed_auth); + } + + return properties; } static void -connect_context_clear (NMModemBroadband *self) +connect_context_clear(NMModemBroadband *self) { - if (self->_priv.ctx) { - ConnectContext *ctx = self->_priv.ctx; - - g_clear_error (&ctx->first_error); - nm_clear_pointer (&ctx->ip_types, g_array_unref); - nm_clear_g_cancellable (&ctx->cancellable); - g_clear_object (&ctx->connection); - g_clear_object (&ctx->connect_properties); - g_clear_object (&ctx->self); - g_slice_free (ConnectContext, ctx); - self->_priv.ctx = NULL; - } + if (self->_priv.ctx) { + ConnectContext *ctx = self->_priv.ctx; + + g_clear_error(&ctx->first_error); + nm_clear_pointer(&ctx->ip_types, g_array_unref); + nm_clear_g_cancellable(&ctx->cancellable); + g_clear_object(&ctx->connection); + g_clear_object(&ctx->connect_properties); + g_clear_object(&ctx->self); + g_slice_free(ConnectContext, ctx); + self->_priv.ctx = NULL; + } } -static void connect_context_step (NMModemBroadband *self); +static void connect_context_step(NMModemBroadband *self); static void -connect_ready (MMModemSimple *simple_iface, - GAsyncResult *res, - NMModemBroadband *self) +connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { - ConnectContext *ctx; - GError *error = NULL; - NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; - NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; - MMBearer *bearer; - - bearer = mm_modem_simple_connect_finish (simple_iface, res, &error); - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free (error); - return; - } - - ctx = self->_priv.ctx; - - if (!ctx) - return; - - self->_priv.bearer = bearer; - - if (!self->_priv.bearer) { - if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || - (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) && - mm_modem_get_unlock_required (self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN)) { - g_error_free (error); - - /* Request PIN */ - ask_for_pin (self); - connect_context_clear (self); - return; - } - - /* Save the error, if it's the first one */ - if (!ctx->first_error) { - /* Strip remote error info before saving it */ - if (g_dbus_error_is_remote_error (error)) - g_dbus_error_strip_remote_error (error); - ctx->first_error = error; - } else - g_clear_error (&error); - - if ( ctx->ip_type_tries == 0 - && g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY)) { - /* Try one more time */ - ctx->ip_type_tries++; - } else { - /* If the modem/provider lies and the IP type we tried isn't supported, - * retry with the next one, if any. - */ - ctx->ip_types_i++; - ctx->ip_type_tries = 0; - } - connect_context_step (self); - return; - } - - /* Grab IP configurations */ - self->_priv.ipv4_config = mm_bearer_get_ipv4_config (self->_priv.bearer); - if (self->_priv.ipv4_config) - ip4_method = get_bearer_ip_method (self->_priv.ipv4_config); - - self->_priv.ipv6_config = mm_bearer_get_ipv6_config (self->_priv.bearer); - if (self->_priv.ipv6_config) - ip6_method = get_bearer_ip_method (self->_priv.ipv6_config); - - if (!nm_modem_set_data_port (NM_MODEM (self), - NM_PLATFORM_GET, - mm_bearer_get_interface (self->_priv.bearer), - ip4_method, - ip6_method, - mm_bearer_get_ip_timeout (self->_priv.bearer), - &error)) { - _LOGW ("failed to connect modem: %s", error->message); - g_error_free (error); - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - connect_context_clear (self); - return; - } - - ctx->step++; - connect_context_step (self); + ConnectContext *ctx; + GError * error = NULL; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; + MMBearer * bearer; + + bearer = mm_modem_simple_connect_finish(simple_iface, res, &error); + + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free(error); + return; + } + + ctx = self->_priv.ctx; + + if (!ctx) + return; + + self->_priv.bearer = bearer; + + if (!self->_priv.bearer) { + if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) + || (g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) + && mm_modem_get_unlock_required(self->_priv.modem_iface) + == MM_MODEM_LOCK_SIM_PIN)) { + g_error_free(error); + + /* Request PIN */ + ask_for_pin(self); + connect_context_clear(self); + return; + } + + /* Save the error, if it's the first one */ + if (!ctx->first_error) { + /* Strip remote error info before saving it */ + if (g_dbus_error_is_remote_error(error)) + g_dbus_error_strip_remote_error(error); + ctx->first_error = error; + } else + g_clear_error(&error); + + if (ctx->ip_type_tries == 0 && g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY)) { + /* Try one more time */ + ctx->ip_type_tries++; + } else { + /* If the modem/provider lies and the IP type we tried isn't supported, + * retry with the next one, if any. + */ + ctx->ip_types_i++; + ctx->ip_type_tries = 0; + } + connect_context_step(self); + return; + } + + /* Grab IP configurations */ + self->_priv.ipv4_config = mm_bearer_get_ipv4_config(self->_priv.bearer); + if (self->_priv.ipv4_config) + ip4_method = get_bearer_ip_method(self->_priv.ipv4_config); + + self->_priv.ipv6_config = mm_bearer_get_ipv6_config(self->_priv.bearer); + if (self->_priv.ipv6_config) + ip6_method = get_bearer_ip_method(self->_priv.ipv6_config); + + if (!nm_modem_set_data_port(NM_MODEM(self), + NM_PLATFORM_GET, + mm_bearer_get_interface(self->_priv.bearer), + ip4_method, + ip6_method, + mm_bearer_get_ip_timeout(self->_priv.bearer), + &error)) { + _LOGW("failed to connect modem: %s", error->message); + g_error_free(error); + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + connect_context_clear(self); + return; + } + + ctx->step++; + connect_context_step(self); } static void -send_pin_ready (MMSim *sim, GAsyncResult *result, NMModemBroadband *self) +send_pin_ready(MMSim *sim, GAsyncResult *result, NMModemBroadband *self) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - mm_sim_send_pin_finish (sim, result, &error); + mm_sim_send_pin_finish(sim, result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - if (!self->_priv.ctx || self->_priv.ctx->step != CONNECT_STEP_UNLOCK) - g_return_if_reached (); + if (!self->_priv.ctx || self->_priv.ctx->step != CONNECT_STEP_UNLOCK) + g_return_if_reached(); - if (error) { - if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) || - (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) && - mm_modem_get_unlock_required (self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN)) - ask_for_pin (self); - else - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, translate_mm_error (self, error)); - return; - } + if (error) { + if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) + || (g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_UNAUTHORIZED) + && mm_modem_get_unlock_required(self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN)) + ask_for_pin(self); + else + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, translate_mm_error(self, error)); + return; + } - self->_priv.ctx->step++; - connect_context_step (self); + self->_priv.ctx->step++; + connect_context_step(self); } static void -find_gsm_apn_cb (const char *apn, - const char *username, - const char *password, - const char *gateway, - const char *auth_method, - const GSList *dns, - GError *error, - gpointer user_data) +find_gsm_apn_cb(const char * apn, + const char * username, + const char * password, + const char * gateway, + const char * auth_method, + const GSList *dns, + GError * error, + gpointer user_data) { - NMModemBroadband *self = user_data; - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self); - ConnectContext *ctx = priv->ctx; - - if (error) { - _LOGW ("failed to connect '%s': APN not found: %s", - nm_connection_get_id (ctx->connection), error->message); - - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_GSM_APN_FAILED); - connect_context_clear (self); - return; - } - - /* Blank APN ("") means the default subscription APN */ - ctx->connect_properties = create_gsm_connect_properties (ctx->connection, - apn, - username, - password); - g_return_if_fail (ctx->connect_properties); - connect_context_step (self); + NMModemBroadband * self = user_data; + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); + ConnectContext * ctx = priv->ctx; + + if (error) { + _LOGW("failed to connect '%s': APN not found: %s", + nm_connection_get_id(ctx->connection), + error->message); + + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_GSM_APN_FAILED); + connect_context_clear(self); + return; + } + + /* Blank APN ("") means the default subscription APN */ + ctx->connect_properties = + create_gsm_connect_properties(ctx->connection, apn, username, password); + g_return_if_fail(ctx->connect_properties); + connect_context_step(self); } static gboolean -try_create_connect_properties (NMModemBroadband *self) +try_create_connect_properties(NMModemBroadband *self) { - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self); - ConnectContext *ctx = priv->ctx; - - if (MODEM_CAPS_3GPP (ctx->caps)) { - NMSettingGsm *s_gsm = nm_connection_get_setting_gsm (ctx->connection); - - if (!s_gsm || nm_setting_gsm_get_auto_config (s_gsm)) { - gs_unref_object MMModem3gpp *modem_3gpp = NULL; - const char *network_id = NULL; - - s_gsm = nm_connection_get_setting_gsm (ctx->connection); - if (s_gsm) - network_id = nm_setting_gsm_get_network_id (s_gsm); - if (!network_id) { - if (mm_modem_get_state (self->_priv.modem_iface) < MM_MODEM_STATE_REGISTERED) - return FALSE; - modem_3gpp = mm_object_get_modem_3gpp (priv->modem_object); - network_id = mm_modem_3gpp_get_operator_code (modem_3gpp); - } - if (!network_id) { - _LOGW ("failed to connect '%s': unable to determine the network id", - nm_connection_get_id (ctx->connection)); - goto out; - } - - nm_service_providers_find_gsm_apn (MOBILE_BROADBAND_PROVIDER_INFO_DATABASE, - network_id, - ctx->cancellable, - find_gsm_apn_cb, - self); - } else { - ctx->connect_properties = create_gsm_connect_properties (ctx->connection, - nm_setting_gsm_get_apn (s_gsm), - nm_setting_gsm_get_username (s_gsm), - nm_setting_gsm_get_password (s_gsm)); - g_return_val_if_fail (ctx->connect_properties, TRUE); - } - - return TRUE; - } else if (MODEM_CAPS_3GPP2 (ctx->caps)) { - ctx->connect_properties = create_cdma_connect_properties (ctx->connection); - g_return_val_if_fail (ctx->connect_properties, FALSE); - return TRUE; - } else { - _LOGW ("failed to connect '%s': not a mobile broadband modem", - nm_connection_get_id (ctx->connection)); - } + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); + ConnectContext * ctx = priv->ctx; + + if (MODEM_CAPS_3GPP(ctx->caps)) { + NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection); + + if (!s_gsm || nm_setting_gsm_get_auto_config(s_gsm)) { + gs_unref_object MMModem3gpp *modem_3gpp = NULL; + const char * network_id = NULL; + + s_gsm = nm_connection_get_setting_gsm(ctx->connection); + if (s_gsm) + network_id = nm_setting_gsm_get_network_id(s_gsm); + if (!network_id) { + if (mm_modem_get_state(self->_priv.modem_iface) < MM_MODEM_STATE_REGISTERED) + return FALSE; + modem_3gpp = mm_object_get_modem_3gpp(priv->modem_object); + network_id = mm_modem_3gpp_get_operator_code(modem_3gpp); + } + if (!network_id) { + _LOGW("failed to connect '%s': unable to determine the network id", + nm_connection_get_id(ctx->connection)); + goto out; + } + + nm_service_providers_find_gsm_apn(MOBILE_BROADBAND_PROVIDER_INFO_DATABASE, + network_id, + ctx->cancellable, + find_gsm_apn_cb, + self); + } else { + ctx->connect_properties = + create_gsm_connect_properties(ctx->connection, + nm_setting_gsm_get_apn(s_gsm), + nm_setting_gsm_get_username(s_gsm), + nm_setting_gsm_get_password(s_gsm)); + g_return_val_if_fail(ctx->connect_properties, TRUE); + } + + return TRUE; + } else if (MODEM_CAPS_3GPP2(ctx->caps)) { + ctx->connect_properties = create_cdma_connect_properties(ctx->connection); + g_return_val_if_fail(ctx->connect_properties, FALSE); + return TRUE; + } else { + _LOGW("failed to connect '%s': not a mobile broadband modem", + nm_connection_get_id(ctx->connection)); + } out: - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); - connect_context_clear (self); - return TRUE; + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + connect_context_clear(self); + return TRUE; } static void -connect_context_step (NMModemBroadband *self) +connect_context_step(NMModemBroadband *self) { - ConnectContext *ctx = self->_priv.ctx; - - switch (ctx->step) { - case CONNECT_STEP_FIRST: - ctx->step++; - /* fall-through */ - - case CONNECT_STEP_WAIT_FOR_SIM: - if (MODEM_CAPS_3GPP (ctx->caps) && !self->_priv.sim_iface) { - /* Have to wait for the SIM to show up */ - break; - } - ctx->step++; - /* fall-through */ - - case CONNECT_STEP_UNLOCK: - if ( MODEM_CAPS_3GPP (ctx->caps) - && mm_modem_get_unlock_required (self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN) { - NMSettingGsm *s_gsm = nm_connection_get_setting_gsm (ctx->connection); - const char *pin = nm_setting_gsm_get_pin (s_gsm); - - /* If we have a PIN already, send it. If we don't, get it. */ - if (pin) { - mm_sim_send_pin (self->_priv.sim_iface, - pin, - ctx->cancellable, - (GAsyncReadyCallback) send_pin_ready, - self); - } else { - ask_for_pin (self); - } - break; - } - ctx->step++; - /* fall-through */ - case CONNECT_STEP_WAIT_FOR_READY: { - GError *error = NULL; - - if (mm_modem_get_state (self->_priv.modem_iface) <= MM_MODEM_STATE_LOCKED) - break; - - if (!try_create_connect_properties (self)) - break; - - if (!self->_priv.ctx) - break; - - /* Build up list of IP types that we need to use in the retries */ - ctx->ip_types = nm_modem_get_connection_ip_type (NM_MODEM (self), ctx->connection, &error); - if (!ctx->ip_types) { - _LOGW ("failed to connect '%s': %s", - nm_connection_get_id (ctx->connection), - error->message); - g_clear_error (&error); - - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); - connect_context_clear (self); - break; - } - - ctx->step++; - } - /* fall-through */ - case CONNECT_STEP_CONNECT: - if (!ctx->connect_properties) - break; - - if (ctx->ip_types_i < ctx->ip_types->len) { - NMModemIPType current; - - current = g_array_index (ctx->ip_types, NMModemIPType, ctx->ip_types_i); - - if (current == NM_MODEM_IP_TYPE_IPV4) - mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV4); - else if (current == NM_MODEM_IP_TYPE_IPV6) - mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV6); - else if (current == NM_MODEM_IP_TYPE_IPV4V6) - mm_simple_connect_properties_set_ip_type (ctx->connect_properties, MM_BEARER_IP_FAMILY_IPV4V6); - else - g_return_if_reached (); - - _nm_modem_set_apn (NM_MODEM (self), mm_simple_connect_properties_get_apn (ctx->connect_properties)); - - _LOGD ("launching connection with ip type '%s' (try %d)", - nm_modem_ip_type_to_string (current), - ctx->ip_type_tries + 1); - - mm_modem_simple_connect (self->_priv.simple_iface, - ctx->connect_properties, - ctx->cancellable, - (GAsyncReadyCallback) connect_ready, - self); - break; - } - - ctx->step++; - /* fall-through */ - - case CONNECT_STEP_LAST: - if (self->_priv.ipv4_config || self->_priv.ipv6_config) - nm_modem_emit_prepare_result (NM_MODEM (self), TRUE, NM_DEVICE_STATE_REASON_NONE); - else { - /* If we have a saved error from a previous attempt, use it */ - if (!ctx->first_error) - ctx->first_error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "invalid bearer IP configuration"); - - _LOGW ("failed to connect modem: %s", - ctx->first_error->message); - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, translate_mm_error (self, ctx->first_error)); - } - - connect_context_clear (self); - break; - } + ConnectContext *ctx = self->_priv.ctx; + + switch (ctx->step) { + case CONNECT_STEP_FIRST: + ctx->step++; + /* fall-through */ + + case CONNECT_STEP_WAIT_FOR_SIM: + if (MODEM_CAPS_3GPP(ctx->caps) && !self->_priv.sim_iface) { + /* Have to wait for the SIM to show up */ + break; + } + ctx->step++; + /* fall-through */ + + case CONNECT_STEP_UNLOCK: + if (MODEM_CAPS_3GPP(ctx->caps) + && mm_modem_get_unlock_required(self->_priv.modem_iface) == MM_MODEM_LOCK_SIM_PIN) { + NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection); + const char * pin = nm_setting_gsm_get_pin(s_gsm); + + /* If we have a PIN already, send it. If we don't, get it. */ + if (pin) { + mm_sim_send_pin(self->_priv.sim_iface, + pin, + ctx->cancellable, + (GAsyncReadyCallback) send_pin_ready, + self); + } else { + ask_for_pin(self); + } + break; + } + ctx->step++; + /* fall-through */ + case CONNECT_STEP_WAIT_FOR_READY: + { + GError *error = NULL; + + if (mm_modem_get_state(self->_priv.modem_iface) <= MM_MODEM_STATE_LOCKED) + break; + + if (!try_create_connect_properties(self)) + break; + + if (!self->_priv.ctx) + break; + + /* Build up list of IP types that we need to use in the retries */ + ctx->ip_types = nm_modem_get_connection_ip_type(NM_MODEM(self), ctx->connection, &error); + if (!ctx->ip_types) { + _LOGW("failed to connect '%s': %s", + nm_connection_get_id(ctx->connection), + error->message); + g_clear_error(&error); + + nm_modem_emit_prepare_result(NM_MODEM(self), + FALSE, + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + connect_context_clear(self); + break; + } + + ctx->step++; + } + /* fall-through */ + case CONNECT_STEP_CONNECT: + if (!ctx->connect_properties) + break; + + if (ctx->ip_types_i < ctx->ip_types->len) { + NMModemIPType current; + + current = g_array_index(ctx->ip_types, NMModemIPType, ctx->ip_types_i); + + if (current == NM_MODEM_IP_TYPE_IPV4) + mm_simple_connect_properties_set_ip_type(ctx->connect_properties, + MM_BEARER_IP_FAMILY_IPV4); + else if (current == NM_MODEM_IP_TYPE_IPV6) + mm_simple_connect_properties_set_ip_type(ctx->connect_properties, + MM_BEARER_IP_FAMILY_IPV6); + else if (current == NM_MODEM_IP_TYPE_IPV4V6) + mm_simple_connect_properties_set_ip_type(ctx->connect_properties, + MM_BEARER_IP_FAMILY_IPV4V6); + else + g_return_if_reached(); + + _nm_modem_set_apn(NM_MODEM(self), + mm_simple_connect_properties_get_apn(ctx->connect_properties)); + + _LOGD("launching connection with ip type '%s' (try %d)", + nm_modem_ip_type_to_string(current), + ctx->ip_type_tries + 1); + + mm_modem_simple_connect(self->_priv.simple_iface, + ctx->connect_properties, + ctx->cancellable, + (GAsyncReadyCallback) connect_ready, + self); + break; + } + + ctx->step++; + /* fall-through */ + + case CONNECT_STEP_LAST: + if (self->_priv.ipv4_config || self->_priv.ipv6_config) + nm_modem_emit_prepare_result(NM_MODEM(self), TRUE, NM_DEVICE_STATE_REASON_NONE); + else { + /* If we have a saved error from a previous attempt, use it */ + if (!ctx->first_error) + ctx->first_error = g_error_new_literal(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "invalid bearer IP configuration"); + + _LOGW("failed to connect modem: %s", ctx->first_error->message); + nm_modem_emit_prepare_result(NM_MODEM(self), + FALSE, + translate_mm_error(self, ctx->first_error)); + } + + connect_context_clear(self); + break; + } } static NMActStageReturn -modem_act_stage1_prepare (NMModem *_self, - NMConnection *connection, - NMDeviceStateReason *out_failure_reason) +modem_act_stage1_prepare(NMModem * _self, + NMConnection * connection, + NMDeviceStateReason *out_failure_reason) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - - /* Make sure we can get the Simple interface from the modem */ - if (!self->_priv.simple_iface) { - self->_priv.simple_iface = mm_object_get_modem_simple (self->_priv.modem_object); - if (!self->_priv.simple_iface) { - _LOGW ("cannot access the Simple mobile broadband modem interface"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - - connect_context_clear (self); - - /* Allocate new context for this connect stage attempt */ - self->_priv.ctx = g_slice_new0 (ConnectContext); - self->_priv.ctx->caps = mm_modem_get_current_capabilities (self->_priv.modem_iface); - self->_priv.ctx->cancellable = g_cancellable_new (); - self->_priv.ctx->connection = g_object_ref (connection); - - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (self->_priv.simple_iface), MODEM_CONNECT_TIMEOUT_SECS * 1000); - connect_context_step (self); - - return NM_ACT_STAGE_RETURN_POSTPONE; + NMModemBroadband *self = NM_MODEM_BROADBAND(_self); + + /* Make sure we can get the Simple interface from the modem */ + if (!self->_priv.simple_iface) { + self->_priv.simple_iface = mm_object_get_modem_simple(self->_priv.modem_object); + if (!self->_priv.simple_iface) { + _LOGW("cannot access the Simple mobile broadband modem interface"); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + } + + connect_context_clear(self); + + /* Allocate new context for this connect stage attempt */ + self->_priv.ctx = g_slice_new0(ConnectContext); + self->_priv.ctx->caps = mm_modem_get_current_capabilities(self->_priv.modem_iface); + self->_priv.ctx->cancellable = g_cancellable_new(); + self->_priv.ctx->connection = g_object_ref(connection); + + g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(self->_priv.simple_iface), + MODEM_CONNECT_TIMEOUT_SECS * 1000); + connect_context_step(self); + + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ static gboolean -check_connection_compatible_with_modem (NMModem *_self, NMConnection *connection, GError **error) +check_connection_compatible_with_modem(NMModem *_self, NMConnection *connection, GError **error) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - MMModemCapability modem_caps; - - modem_caps = mm_modem_get_current_capabilities (self->_priv.modem_iface); - - if (MODEM_CAPS_3GPP (modem_caps)) { - if (!_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, error)) - return FALSE; - - return TRUE; - } - - if (MODEM_CAPS_3GPP2 (modem_caps)) { - if (!_nm_connection_check_main_setting (connection, NM_SETTING_CDMA_SETTING_NAME, error)) - return FALSE; - - return TRUE; - } - - if ( !_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, NULL) - && !_nm_connection_check_main_setting (connection, NM_SETTING_CDMA_SETTING_NAME, NULL)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "connection type %s is not supported by modem", - nm_connection_get_connection_type (connection)); - return FALSE; - } - - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem lacks capabilities for %s profile", - nm_connection_get_connection_type (connection)); - return FALSE; + NMModemBroadband *self = NM_MODEM_BROADBAND(_self); + MMModemCapability modem_caps; + + modem_caps = mm_modem_get_current_capabilities(self->_priv.modem_iface); + + if (MODEM_CAPS_3GPP(modem_caps)) { + if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, error)) + return FALSE; + + return TRUE; + } + + if (MODEM_CAPS_3GPP2(modem_caps)) { + if (!_nm_connection_check_main_setting(connection, NM_SETTING_CDMA_SETTING_NAME, error)) + return FALSE; + + return TRUE; + } + + if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, NULL) + && !_nm_connection_check_main_setting(connection, NM_SETTING_CDMA_SETTING_NAME, NULL)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "connection type %s is not supported by modem", + nm_connection_get_connection_type(connection)); + return FALSE; + } + + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "modem lacks capabilities for %s profile", + nm_connection_get_connection_type(connection)); + return FALSE; } /*****************************************************************************/ static gboolean -complete_connection (NMModem *modem, - const char *iface, - NMConnection *connection, - NMConnection *const*existing_connections, - GError **error) +complete_connection(NMModem * modem, + const char * iface, + NMConnection * connection, + NMConnection *const *existing_connections, + GError ** error) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - MMModemCapability modem_caps; - NMSettingPpp *s_ppp; - - modem_caps = mm_modem_get_current_capabilities (self->_priv.modem_iface); - - /* PPP settings common to 3GPP and 3GPP2 */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (!s_ppp) { - s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); - g_object_set (G_OBJECT (s_ppp), - NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, - NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - } - - if (MODEM_CAPS_3GPP (modem_caps)) { - NMSettingGsm *s_gsm; - - s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm) { - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - g_object_set (G_OBJECT (s_gsm), - NM_SETTING_GSM_AUTO_CONFIG, TRUE, - NULL); - } - - if (!nm_setting_gsm_get_device_id (s_gsm)) { - g_object_set (G_OBJECT (s_gsm), - NM_SETTING_GSM_DEVICE_ID, nm_modem_get_device_id (modem), - NULL); - } - - nm_utils_complete_generic (NM_PLATFORM_GET, - connection, - NM_SETTING_GSM_SETTING_NAME, - existing_connections, - NULL, - _("GSM connection"), - NULL, - NULL, - FALSE); /* No IPv6 yet by default */ - - return TRUE; - } - - if (MODEM_CAPS_3GPP2 (modem_caps)) { - NMSettingCdma *s_cdma; - - s_cdma = nm_connection_get_setting_cdma (connection); - if (!s_cdma) { - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - } - - if (!nm_setting_cdma_get_number (s_cdma)) - g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); - - nm_utils_complete_generic (NM_PLATFORM_GET, - connection, - NM_SETTING_CDMA_SETTING_NAME, - existing_connections, - NULL, - _("CDMA connection"), - NULL, - iface, - FALSE); /* No IPv6 yet by default */ - - return TRUE; - } - - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Device is not a mobile broadband modem"); - return FALSE; + NMModemBroadband *self = NM_MODEM_BROADBAND(modem); + MMModemCapability modem_caps; + NMSettingPpp * s_ppp; + + modem_caps = mm_modem_get_current_capabilities(self->_priv.modem_iface); + + /* PPP settings common to 3GPP and 3GPP2 */ + s_ppp = nm_connection_get_setting_ppp(connection); + if (!s_ppp) { + s_ppp = (NMSettingPpp *) nm_setting_ppp_new(); + g_object_set(G_OBJECT(s_ppp), + NM_SETTING_PPP_LCP_ECHO_FAILURE, + 5, + NM_SETTING_PPP_LCP_ECHO_INTERVAL, + 30, + NULL); + nm_connection_add_setting(connection, NM_SETTING(s_ppp)); + } + + if (MODEM_CAPS_3GPP(modem_caps)) { + NMSettingGsm *s_gsm; + + s_gsm = nm_connection_get_setting_gsm(connection); + if (!s_gsm) { + s_gsm = (NMSettingGsm *) nm_setting_gsm_new(); + nm_connection_add_setting(connection, NM_SETTING(s_gsm)); + g_object_set(G_OBJECT(s_gsm), NM_SETTING_GSM_AUTO_CONFIG, TRUE, NULL); + } + + if (!nm_setting_gsm_get_device_id(s_gsm)) { + g_object_set(G_OBJECT(s_gsm), + NM_SETTING_GSM_DEVICE_ID, + nm_modem_get_device_id(modem), + NULL); + } + + nm_utils_complete_generic(NM_PLATFORM_GET, + connection, + NM_SETTING_GSM_SETTING_NAME, + existing_connections, + NULL, + _("GSM connection"), + NULL, + NULL, + FALSE); /* No IPv6 yet by default */ + + return TRUE; + } + + if (MODEM_CAPS_3GPP2(modem_caps)) { + NMSettingCdma *s_cdma; + + s_cdma = nm_connection_get_setting_cdma(connection); + if (!s_cdma) { + s_cdma = (NMSettingCdma *) nm_setting_cdma_new(); + nm_connection_add_setting(connection, NM_SETTING(s_cdma)); + } + + if (!nm_setting_cdma_get_number(s_cdma)) + g_object_set(G_OBJECT(s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); + + nm_utils_complete_generic(NM_PLATFORM_GET, + connection, + NM_SETTING_CDMA_SETTING_NAME, + existing_connections, + NULL, + _("CDMA connection"), + NULL, + iface, + FALSE); /* No IPv6 yet by default */ + + return TRUE; + } + + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Device is not a mobile broadband modem"); + return FALSE; } /*****************************************************************************/ static gboolean -get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) +get_user_pass(NMModem *modem, NMConnection *connection, const char **user, const char **pass) { - NMSettingGsm *s_gsm; - NMSettingCdma *s_cdma; - - s_gsm = nm_connection_get_setting_gsm (connection); - s_cdma = nm_connection_get_setting_cdma (connection); - if (!s_gsm && !s_cdma) - return FALSE; - - if (user) { - if (s_gsm) - *user = nm_setting_gsm_get_username (s_gsm); - else if (s_cdma) - *user = nm_setting_cdma_get_username (s_cdma); - } - if (pass) { - if (s_gsm) - *pass = nm_setting_gsm_get_password (s_gsm); - else if (s_cdma) - *pass = nm_setting_cdma_get_password (s_cdma); - } - - return TRUE; + NMSettingGsm * s_gsm; + NMSettingCdma *s_cdma; + + s_gsm = nm_connection_get_setting_gsm(connection); + s_cdma = nm_connection_get_setting_cdma(connection); + if (!s_gsm && !s_cdma) + return FALSE; + + if (user) { + if (s_gsm) + *user = nm_setting_gsm_get_username(s_gsm); + else if (s_cdma) + *user = nm_setting_cdma_get_username(s_cdma); + } + if (pass) { + if (s_gsm) + *pass = nm_setting_gsm_get_password(s_gsm); + else if (s_cdma) + *pass = nm_setting_cdma_get_password(s_cdma); + } + + return TRUE; } /*****************************************************************************/ /* Query/Update enabled state */ static void -set_power_state_low_ready (MMModem *modem, - GAsyncResult *result, - NMModemBroadband *self) +set_power_state_low_ready(MMModem *modem, GAsyncResult *result, NMModemBroadband *self) { - GError *error = NULL; + GError *error = NULL; - if (!mm_modem_set_power_state_finish (modem, result, &error)) { - /* Log but ignore errors; not all modems support low power state */ - _LOGD ("failed to set modem low power state: %s", - NM_G_ERROR_MSG (error)); - g_clear_error (&error); - } + if (!mm_modem_set_power_state_finish(modem, result, &error)) { + /* Log but ignore errors; not all modems support low power state */ + _LOGD("failed to set modem low power state: %s", NM_G_ERROR_MSG(error)); + g_clear_error(&error); + } - /* Balance refcount */ - g_object_unref (self); + /* Balance refcount */ + g_object_unref(self); } static void -modem_disable_ready (MMModem *modem_iface, - GAsyncResult *res, - NMModemBroadband *self) +modem_disable_ready(MMModem *modem_iface, GAsyncResult *res, NMModemBroadband *self) { - GError *error = NULL; - - if (mm_modem_disable_finish (modem_iface, res, &error)) { - /* Once disabled, move to low-power mode */ - mm_modem_set_power_state (modem_iface, - MM_MODEM_POWER_STATE_LOW, - NULL, - (GAsyncReadyCallback) set_power_state_low_ready, - g_object_ref (self)); - } else { - _LOGW ("failed to disable modem: %s", - NM_G_ERROR_MSG (error)); - nm_modem_set_prev_state (NM_MODEM (self), "disable failed"); - g_clear_error (&error); - } - - /* Balance refcount */ - g_object_unref (self); + GError *error = NULL; + + if (mm_modem_disable_finish(modem_iface, res, &error)) { + /* Once disabled, move to low-power mode */ + mm_modem_set_power_state(modem_iface, + MM_MODEM_POWER_STATE_LOW, + NULL, + (GAsyncReadyCallback) set_power_state_low_ready, + g_object_ref(self)); + } else { + _LOGW("failed to disable modem: %s", NM_G_ERROR_MSG(error)); + nm_modem_set_prev_state(NM_MODEM(self), "disable failed"); + g_clear_error(&error); + } + + /* Balance refcount */ + g_object_unref(self); } static void -modem_enable_ready (MMModem *modem_iface, - GAsyncResult *res, - NMModemBroadband *self) +modem_enable_ready(MMModem *modem_iface, GAsyncResult *res, NMModemBroadband *self) { - GError *error = NULL; + GError *error = NULL; - if (!mm_modem_enable_finish (modem_iface, res, &error)) { - _LOGW ("failed to enable modem: %s", - NM_G_ERROR_MSG (error)); - nm_modem_set_prev_state (NM_MODEM (self), "enable failed"); - g_clear_error (&error); - } + if (!mm_modem_enable_finish(modem_iface, res, &error)) { + _LOGW("failed to enable modem: %s", NM_G_ERROR_MSG(error)); + nm_modem_set_prev_state(NM_MODEM(self), "enable failed"); + g_clear_error(&error); + } - /* Balance refcount */ - g_object_unref (self); + /* Balance refcount */ + g_object_unref(self); } static void -set_mm_enabled (NMModem *_self, - gboolean enabled) +set_mm_enabled(NMModem *_self, gboolean enabled) { - NMModemBroadband *self = NM_MODEM_BROADBAND (_self); - - if (enabled) { - mm_modem_enable (self->_priv.modem_iface, - NULL, /* cancellable */ - (GAsyncReadyCallback)modem_enable_ready, - g_object_ref (self)); - } else { - mm_modem_disable (self->_priv.modem_iface, - NULL, /* cancellable */ - (GAsyncReadyCallback)modem_disable_ready, - g_object_ref (self)); - } + NMModemBroadband *self = NM_MODEM_BROADBAND(_self); + + if (enabled) { + mm_modem_enable(self->_priv.modem_iface, + NULL, /* cancellable */ + (GAsyncReadyCallback) modem_enable_ready, + g_object_ref(self)); + } else { + mm_modem_disable(self->_priv.modem_iface, + NULL, /* cancellable */ + (GAsyncReadyCallback) modem_disable_ready, + g_object_ref(self)); + } } /*****************************************************************************/ /* IPv4 method static */ static gboolean -static_stage3_ip4_done (NMModemBroadband *self) +static_stage3_ip4_done(NMModemBroadband *self) { - GError *error = NULL; - gs_unref_object NMIP4Config *config = NULL; - const char *data_port; - const char *address_string; - const char *gw_string; - guint32 address_network; - guint32 gw = 0; - NMPlatformIP4Address address; - const char **dns; - guint i; - guint32 ip4_route_table, ip4_route_metric; - NMPlatformIP4Route *r; - guint32 mtu_n; - - g_return_val_if_fail (self->_priv.ipv4_config, FALSE); - g_return_val_if_fail (self->_priv.bearer, FALSE); - - self->_priv.idle_id_ip4 = 0; - - _LOGI ("IPv4 static configuration:"); - - /* Fully fail if invalid IP address retrieved */ - address_string = mm_bearer_ip_config_get_address (self->_priv.ipv4_config); - if ( !address_string - || !nm_utils_parse_inaddr_bin (AF_INET, address_string, NULL, &address_network)) { - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s", - nm_modem_get_uid (NM_MODEM (self)), - NM_PRINT_FMT_QUOTE_STRING (address_string)); - goto out; - } - - /* Missing gateway not a hard failure */ - gw_string = mm_bearer_ip_config_get_gateway (self->_priv.ipv4_config); - if ( gw_string - && !nm_utils_parse_inaddr_bin (AF_INET, gw_string, NULL, &gw)) { - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"", - nm_modem_get_uid (NM_MODEM (self)), - gw_string); - goto out; - } - - data_port = mm_bearer_get_interface (self->_priv.bearer); - g_return_val_if_fail (data_port, FALSE); - config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET), - nm_platform_link_get_ifindex (NM_PLATFORM_GET, data_port)); - - memset (&address, 0, sizeof (address)); - address.address = address_network; - address.peer_address = address_network; - address.plen = mm_bearer_ip_config_get_prefix (self->_priv.ipv4_config); - address.addr_source = NM_IP_CONFIG_SOURCE_WWAN; - if (address.plen <= 32) - nm_ip4_config_add_address (config, &address); - - _LOGI (" address %s/%d", address_string, address.plen); - - nm_modem_get_route_parameters (NM_MODEM (self), - &ip4_route_table, - &ip4_route_metric, - NULL, - NULL); - r = &(NMPlatformIP4Route) { - .rt_source = NM_IP_CONFIG_SOURCE_WWAN, - .gateway = gw, - .table_coerced = nm_platform_route_table_coerce (ip4_route_table), - .metric = ip4_route_metric, - }; - nm_ip4_config_add_route (config, r, NULL); - _LOGI (" gateway %s", gw_string); - - /* DNS servers */ - dns = mm_bearer_ip_config_get_dns (self->_priv.ipv4_config); - for (i = 0; dns && dns[i]; i++) { - if ( nm_utils_parse_inaddr_bin (AF_INET, dns[i], NULL, &address_network) - && address_network > 0) { - nm_ip4_config_add_nameserver (config, address_network); - _LOGI (" DNS %s", dns[i]); - } - } + GError * error = NULL; + gs_unref_object NMIP4Config *config = NULL; + const char * data_port; + const char * address_string; + const char * gw_string; + guint32 address_network; + guint32 gw = 0; + NMPlatformIP4Address address; + const char ** dns; + guint i; + guint32 ip4_route_table, ip4_route_metric; + NMPlatformIP4Route * r; + guint32 mtu_n; + + g_return_val_if_fail(self->_priv.ipv4_config, FALSE); + g_return_val_if_fail(self->_priv.bearer, FALSE); + + self->_priv.idle_id_ip4 = 0; + + _LOGI("IPv4 static configuration:"); + + /* Fully fail if invalid IP address retrieved */ + address_string = mm_bearer_ip_config_get_address(self->_priv.ipv4_config); + if (!address_string + || !nm_utils_parse_inaddr_bin(AF_INET, address_string, NULL, &address_network)) { + error = + g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IP4 configuration failed: invalid address given %s%s%s", + nm_modem_get_uid(NM_MODEM(self)), + NM_PRINT_FMT_QUOTE_STRING(address_string)); + goto out; + } + + /* Missing gateway not a hard failure */ + gw_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv4_config); + if (gw_string && !nm_utils_parse_inaddr_bin(AF_INET, gw_string, NULL, &gw)) { + error = + g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IP4 configuration failed: invalid gateway address \"%s\"", + nm_modem_get_uid(NM_MODEM(self)), + gw_string); + goto out; + } + + data_port = mm_bearer_get_interface(self->_priv.bearer); + g_return_val_if_fail(data_port, FALSE); + config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), + nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port)); + + memset(&address, 0, sizeof(address)); + address.address = address_network; + address.peer_address = address_network; + address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv4_config); + address.addr_source = NM_IP_CONFIG_SOURCE_WWAN; + if (address.plen <= 32) + nm_ip4_config_add_address(config, &address); + + _LOGI(" address %s/%d", address_string, address.plen); + + nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL); + r = &(NMPlatformIP4Route){ + .rt_source = NM_IP_CONFIG_SOURCE_WWAN, + .gateway = gw, + .table_coerced = nm_platform_route_table_coerce(ip4_route_table), + .metric = ip4_route_metric, + }; + nm_ip4_config_add_route(config, r, NULL); + _LOGI(" gateway %s", gw_string); + + /* DNS servers */ + dns = mm_bearer_ip_config_get_dns(self->_priv.ipv4_config); + for (i = 0; dns && dns[i]; i++) { + if (nm_utils_parse_inaddr_bin(AF_INET, dns[i], NULL, &address_network) + && address_network > 0) { + nm_ip4_config_add_nameserver(config, address_network); + _LOGI(" DNS %s", dns[i]); + } + } #if MM_CHECK_VERSION(1, 4, 0) - mtu_n = mm_bearer_ip_config_get_mtu (self->_priv.ipv4_config); - if (mtu_n) { - nm_ip4_config_set_mtu (config, mtu_n, NM_IP_CONFIG_SOURCE_WWAN); - _LOGI (" MTU %u", mtu_n); - } + mtu_n = mm_bearer_ip_config_get_mtu(self->_priv.ipv4_config); + if (mtu_n) { + nm_ip4_config_set_mtu(config, mtu_n, NM_IP_CONFIG_SOURCE_WWAN); + _LOGI(" MTU %u", mtu_n); + } #endif out: - g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, config, error); - g_clear_error (&error); - return FALSE; + g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, config, error); + g_clear_error(&error); + return FALSE; } static NMActStageReturn -static_stage3_ip4_config_start (NMModem *modem, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason) +static_stage3_ip4_config_start(NMModem * modem, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self); + NMModemBroadband * self = NM_MODEM_BROADBAND(modem); + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); - /* We schedule it in an idle just to follow the same logic as in the - * generic modem implementation. */ - nm_clear_g_source (&priv->idle_id_ip4); - priv->idle_id_ip4 = g_idle_add ((GSourceFunc) static_stage3_ip4_done, self); + /* We schedule it in an idle just to follow the same logic as in the + * generic modem implementation. */ + nm_clear_g_source(&priv->idle_id_ip4); + priv->idle_id_ip4 = g_idle_add((GSourceFunc) static_stage3_ip4_done, self); - return NM_ACT_STAGE_RETURN_POSTPONE; + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ /* IPv6 method static */ static gboolean -stage3_ip6_done (NMModemBroadband *self) +stage3_ip6_done(NMModemBroadband *self) { - GError *error = NULL; - NMIP6Config *config = NULL; - const char *data_port; - const char *address_string; - NMPlatformIP6Address address; - NMModemIPMethod ip_method; - const char **dns; - guint i; - - g_return_val_if_fail (self->_priv.ipv6_config, FALSE); - - self->_priv.idle_id_ip6 = 0; - memset (&address, 0, sizeof (address)); - - ip_method = get_bearer_ip_method (self->_priv.ipv6_config); - - address_string = mm_bearer_ip_config_get_address (self->_priv.ipv6_config); - if (!address_string) { - /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ - if (ip_method != NM_MODEM_IP_METHOD_AUTO) { - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: no address given", - nm_modem_get_uid (NM_MODEM (self))); - } - goto out; - } - - /* Fail if invalid IP address retrieved */ - if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", - nm_modem_get_uid (NM_MODEM (self)), - address_string); - goto out; - } - - _LOGI ("IPv6 base configuration:"); - - data_port = mm_bearer_get_interface (self->_priv.bearer); - g_return_val_if_fail (data_port, FALSE); - - config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET), - nm_platform_link_get_ifindex (NM_PLATFORM_GET, data_port)); - - address.plen = mm_bearer_ip_config_get_prefix (self->_priv.ipv6_config); - if (address.plen <= 128) - nm_ip6_config_add_address (config, &address); - - _LOGI (" address %s/%d", address_string, address.plen); - - address_string = mm_bearer_ip_config_get_gateway (self->_priv.ipv6_config); - if (address_string) { - guint32 ip6_route_table, ip6_route_metric; - - if (inet_pton (AF_INET6, address_string, &address.address) != 1) { - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", - nm_modem_get_uid (NM_MODEM (self)), - address_string); - goto out; - } - - nm_modem_get_route_parameters (NM_MODEM (self), - NULL, - NULL, - &ip6_route_table, - &ip6_route_metric); - { - const NMPlatformIP6Route r = { - .rt_source = NM_IP_CONFIG_SOURCE_WWAN, - .gateway = address.address, - .table_coerced = nm_platform_route_table_coerce (ip6_route_table), - .metric = ip6_route_metric, - }; - - _LOGI (" gateway %s", address_string); - nm_ip6_config_add_route (config, &r, NULL); - } - } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { - /* Gateway required for the 'static' method */ - error = g_error_new (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: missing gateway", - nm_modem_get_uid (NM_MODEM (self))); - goto out; - } - - /* DNS servers */ - dns = mm_bearer_ip_config_get_dns (self->_priv.ipv6_config); - for (i = 0; dns && dns[i]; i++) { - struct in6_addr addr; - - if (inet_pton (AF_INET6, dns[i], &addr)) { - nm_ip6_config_add_nameserver (config, &addr); - _LOGI (" DNS %s", dns[i]); - } - } + GError * error = NULL; + NMIP6Config * config = NULL; + const char * data_port; + const char * address_string; + NMPlatformIP6Address address; + NMModemIPMethod ip_method; + const char ** dns; + guint i; + + g_return_val_if_fail(self->_priv.ipv6_config, FALSE); + + self->_priv.idle_id_ip6 = 0; + memset(&address, 0, sizeof(address)); + + ip_method = get_bearer_ip_method(self->_priv.ipv6_config); + + address_string = mm_bearer_ip_config_get_address(self->_priv.ipv6_config); + if (!address_string) { + /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ + if (ip_method != NM_MODEM_IP_METHOD_AUTO) { + error = g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: no address given", + nm_modem_get_uid(NM_MODEM(self))); + } + goto out; + } + + /* Fail if invalid IP address retrieved */ + if (!inet_pton(AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", + nm_modem_get_uid(NM_MODEM(self)), + address_string); + goto out; + } + + _LOGI("IPv6 base configuration:"); + + data_port = mm_bearer_get_interface(self->_priv.bearer); + g_return_val_if_fail(data_port, FALSE); + + config = nm_ip6_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), + nm_platform_link_get_ifindex(NM_PLATFORM_GET, data_port)); + + address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config); + if (address.plen <= 128) + nm_ip6_config_add_address(config, &address); + + _LOGI(" address %s/%d", address_string, address.plen); + + address_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config); + if (address_string) { + guint32 ip6_route_table, ip6_route_metric; + + if (inet_pton(AF_INET6, address_string, &address.address) != 1) { + error = + g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", + nm_modem_get_uid(NM_MODEM(self)), + address_string); + goto out; + } + + nm_modem_get_route_parameters(NM_MODEM(self), + NULL, + NULL, + &ip6_route_table, + &ip6_route_metric); + { + const NMPlatformIP6Route r = { + .rt_source = NM_IP_CONFIG_SOURCE_WWAN, + .gateway = address.address, + .table_coerced = nm_platform_route_table_coerce(ip6_route_table), + .metric = ip6_route_metric, + }; + + _LOGI(" gateway %s", address_string); + nm_ip6_config_add_route(config, &r, NULL); + } + } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { + /* Gateway required for the 'static' method */ + error = g_error_new(NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: missing gateway", + nm_modem_get_uid(NM_MODEM(self))); + goto out; + } + + /* DNS servers */ + dns = mm_bearer_ip_config_get_dns(self->_priv.ipv6_config); + for (i = 0; dns && dns[i]; i++) { + struct in6_addr addr; + + if (inet_pton(AF_INET6, dns[i], &addr)) { + nm_ip6_config_add_nameserver(config, &addr); + _LOGI(" DNS %s", dns[i]); + } + } out: - nm_modem_emit_ip6_config_result (NM_MODEM (self), config, error); - g_clear_object (&config); - g_clear_error (&error); - return FALSE; + nm_modem_emit_ip6_config_result(NM_MODEM(self), config, error); + g_clear_object(&config); + g_clear_error(&error); + return FALSE; } static NMActStageReturn -stage3_ip6_config_request (NMModem *modem, NMDeviceStateReason *out_failure_reason) +stage3_ip6_config_request(NMModem *modem, NMDeviceStateReason *out_failure_reason) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self); + NMModemBroadband * self = NM_MODEM_BROADBAND(modem); + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); - /* We schedule it in an idle just to follow the same logic as in the - * generic modem implementation. */ - nm_clear_g_source (&priv->idle_id_ip6); - priv->idle_id_ip6 = g_idle_add ((GSourceFunc) stage3_ip6_done, self); + /* We schedule it in an idle just to follow the same logic as in the + * generic modem implementation. */ + nm_clear_g_source(&priv->idle_id_ip6); + priv->idle_id_ip6 = g_idle_add((GSourceFunc) stage3_ip6_done, self); - return NM_ACT_STAGE_RETURN_POSTPONE; + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ /* Disconnect */ typedef struct { - NMModemBroadband *self; - _NMModemDisconnectCallback callback; - gpointer callback_user_data; - GCancellable *cancellable; - gboolean warn; + NMModemBroadband * self; + _NMModemDisconnectCallback callback; + gpointer callback_user_data; + GCancellable * cancellable; + gboolean warn; } DisconnectContext; static void -disconnect_context_complete (DisconnectContext *ctx, GError *error) +disconnect_context_complete(DisconnectContext *ctx, GError *error) { - if (ctx->callback) - ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data); - nm_g_object_unref (ctx->cancellable); - g_object_unref (ctx->self); - g_slice_free (DisconnectContext, ctx); + if (ctx->callback) + ctx->callback(NM_MODEM(ctx->self), error, ctx->callback_user_data); + nm_g_object_unref(ctx->cancellable); + g_object_unref(ctx->self); + g_slice_free(DisconnectContext, ctx); } static void -disconnect_context_complete_on_idle (gpointer user_data, - GCancellable *cancellable) +disconnect_context_complete_on_idle(gpointer user_data, GCancellable *cancellable) { - DisconnectContext *ctx = user_data; - gs_free_error GError *cancelled_error = NULL; + DisconnectContext *ctx = user_data; + gs_free_error GError *cancelled_error = NULL; - g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error); - disconnect_context_complete (ctx, cancelled_error); + g_cancellable_set_error_if_cancelled(cancellable, &cancelled_error); + disconnect_context_complete(ctx, cancelled_error); } static void -simple_disconnect_ready (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +simple_disconnect_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) { - MMModemSimple *modem_iface = MM_MODEM_SIMPLE (source_object); - DisconnectContext *ctx = user_data; - gs_free_error GError *error = NULL; + MMModemSimple * modem_iface = MM_MODEM_SIMPLE(source_object); + DisconnectContext *ctx = user_data; + gs_free_error GError *error = NULL; - if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) { - if ( ctx->warn - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { - NMModemBroadband *self = ctx->self; + if (!mm_modem_simple_disconnect_finish(modem_iface, res, &error)) { + if (ctx->warn && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { + NMModemBroadband *self = ctx->self; - _LOGW ("failed to disconnect modem: %s", - error->message); - } - } + _LOGW("failed to disconnect modem: %s", error->message); + } + } - disconnect_context_complete (ctx, error); + disconnect_context_complete(ctx, error); } static void -disconnect (NMModem *modem, - gboolean warn, - GCancellable *cancellable, - _NMModemDisconnectCallback callback, - gpointer user_data) +disconnect(NMModem * modem, + gboolean warn, + GCancellable * cancellable, + _NMModemDisconnectCallback callback, + gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - DisconnectContext *ctx; - - connect_context_clear (self); - _nm_modem_set_apn (NM_MODEM (self), NULL); - - ctx = g_slice_new0 (DisconnectContext); - ctx->self = g_object_ref (self); - ctx->cancellable = nm_g_object_ref (cancellable); - ctx->callback = callback; - ctx->callback_user_data = user_data; - - /* Don't bother warning on FAILED since the modem is already gone */ - ctx->warn = warn; - - /* Already cancelled or no simple-iface? We are done. */ - if ( !ctx->self->_priv.simple_iface - || g_cancellable_is_cancelled (cancellable)) { - nm_utils_invoke_on_idle (cancellable, - disconnect_context_complete_on_idle, - ctx); - return; - } - - _LOGD ("notifying ModemManager about the modem disconnection"); - mm_modem_simple_disconnect (self->_priv.simple_iface, - NULL, /* bearer path; if NULL given ALL get disconnected */ - cancellable, - simple_disconnect_ready, - ctx); + NMModemBroadband * self = NM_MODEM_BROADBAND(modem); + DisconnectContext *ctx; + + connect_context_clear(self); + _nm_modem_set_apn(NM_MODEM(self), NULL); + + ctx = g_slice_new0(DisconnectContext); + ctx->self = g_object_ref(self); + ctx->cancellable = nm_g_object_ref(cancellable); + ctx->callback = callback; + ctx->callback_user_data = user_data; + + /* Don't bother warning on FAILED since the modem is already gone */ + ctx->warn = warn; + + /* Already cancelled or no simple-iface? We are done. */ + if (!ctx->self->_priv.simple_iface || g_cancellable_is_cancelled(cancellable)) { + nm_utils_invoke_on_idle(cancellable, disconnect_context_complete_on_idle, ctx); + return; + } + + _LOGD("notifying ModemManager about the modem disconnection"); + mm_modem_simple_disconnect(self->_priv.simple_iface, + NULL, /* bearer path; if NULL given ALL get disconnected */ + cancellable, + simple_disconnect_ready, + ctx); } /*****************************************************************************/ static void -deactivate_cleanup (NMModem *modem, - NMDevice *device, - gboolean stop_ppp_manager) +deactivate_cleanup(NMModem *modem, NMDevice *device, gboolean stop_ppp_manager) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); + NMModemBroadband *self = NM_MODEM_BROADBAND(modem); - /* TODO: cancel SimpleConnect() if any */ + /* TODO: cancel SimpleConnect() if any */ - /* Cleanup IPv4 addresses and routes */ - g_clear_object (&self->_priv.ipv4_config); - g_clear_object (&self->_priv.ipv6_config); - g_clear_object (&self->_priv.bearer); + /* Cleanup IPv4 addresses and routes */ + g_clear_object(&self->_priv.ipv4_config); + g_clear_object(&self->_priv.ipv6_config); + g_clear_object(&self->_priv.bearer); - self->_priv.pin_tries = 0; + self->_priv.pin_tries = 0; - NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (modem, - device, - stop_ppp_manager); + NM_MODEM_CLASS(nm_modem_broadband_parent_class) + ->deactivate_cleanup(modem, device, stop_ppp_manager); } /*****************************************************************************/ -#define MAP_STATE(name) case MM_MODEM_STATE_##name: return NM_MODEM_STATE_##name; +#define MAP_STATE(name) \ + case MM_MODEM_STATE_##name: \ + return NM_MODEM_STATE_##name; static NMModemState -mm_state_to_nm (MMModemState mm_state) +mm_state_to_nm(MMModemState mm_state) { - switch (mm_state) { - MAP_STATE(UNKNOWN) - MAP_STATE(FAILED) - MAP_STATE(INITIALIZING) - MAP_STATE(LOCKED) - MAP_STATE(DISABLED) - MAP_STATE(DISABLING) - MAP_STATE(ENABLING) - MAP_STATE(ENABLED) - MAP_STATE(SEARCHING) - MAP_STATE(REGISTERED) - MAP_STATE(DISCONNECTING) - MAP_STATE(CONNECTING) - MAP_STATE(CONNECTED) - } - return NM_MODEM_STATE_UNKNOWN; + switch (mm_state) { + MAP_STATE(UNKNOWN) + MAP_STATE(FAILED) + MAP_STATE(INITIALIZING) + MAP_STATE(LOCKED) + MAP_STATE(DISABLED) + MAP_STATE(DISABLING) + MAP_STATE(ENABLING) + MAP_STATE(ENABLED) + MAP_STATE(SEARCHING) + MAP_STATE(REGISTERED) + MAP_STATE(DISCONNECTING) + MAP_STATE(CONNECTING) + MAP_STATE(CONNECTED) + } + return NM_MODEM_STATE_UNKNOWN; } static void -modem_state_changed (MMModem *modem, - MMModemState old_state, - MMModemState new_state, - MMModemStateChangeReason reason, - NMModemBroadband *self) +modem_state_changed(MMModem * modem, + MMModemState old_state, + MMModemState new_state, + MMModemStateChangeReason reason, + NMModemBroadband * self) { - /* After the SIM is unlocked MM1 will move the device to INITIALIZING which - * is an unavailable state. That makes state handling confusing here, so - * suppress this state change and let the modem move from LOCKED to DISABLED. - */ - if (new_state == MM_MODEM_STATE_INITIALIZING && old_state == MM_MODEM_STATE_LOCKED) - return; - - nm_modem_set_state (NM_MODEM (self), - mm_state_to_nm (new_state), - mm_modem_state_change_reason_get_string (reason)); - - if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_READY) - connect_context_step (self); + /* After the SIM is unlocked MM1 will move the device to INITIALIZING which + * is an unavailable state. That makes state handling confusing here, so + * suppress this state change and let the modem move from LOCKED to DISABLED. + */ + if (new_state == MM_MODEM_STATE_INITIALIZING && old_state == MM_MODEM_STATE_LOCKED) + return; + + nm_modem_set_state(NM_MODEM(self), + mm_state_to_nm(new_state), + mm_modem_state_change_reason_get_string(reason)); + + if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_READY) + connect_context_step(self); } /*****************************************************************************/ static NMModemIPType -mm_ip_family_to_nm (MMBearerIpFamily family) +mm_ip_family_to_nm(MMBearerIpFamily family) { - NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN; + NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN; - if (family & MM_BEARER_IP_FAMILY_IPV4) - nm_type |= NM_MODEM_IP_TYPE_IPV4; - if (family & MM_BEARER_IP_FAMILY_IPV6) - nm_type |= NM_MODEM_IP_TYPE_IPV6; - if (family & MM_BEARER_IP_FAMILY_IPV4V6) - nm_type |= MM_BEARER_IP_FAMILY_IPV4V6; + if (family & MM_BEARER_IP_FAMILY_IPV4) + nm_type |= NM_MODEM_IP_TYPE_IPV4; + if (family & MM_BEARER_IP_FAMILY_IPV6) + nm_type |= NM_MODEM_IP_TYPE_IPV6; + if (family & MM_BEARER_IP_FAMILY_IPV4V6) + nm_type |= MM_BEARER_IP_FAMILY_IPV4V6; - return nm_type; + return nm_type; } static void -get_sim_ready (MMModem *modem, - GAsyncResult *res, - NMModemBroadband *self) +get_sim_ready(MMModem *modem, GAsyncResult *res, NMModemBroadband *self) { - GError *error = NULL; - MMSim *new_sim; - - new_sim = mm_modem_get_sim_finish (modem, res, &error); - if (new_sim != self->_priv.sim_iface) { - g_clear_object (&self->_priv.sim_iface); - self->_priv.sim_iface = new_sim; - } else - g_clear_object (&new_sim); - - if (self->_priv.sim_iface) { - g_object_set (G_OBJECT (self), - NM_MODEM_SIM_ID, mm_sim_get_identifier (self->_priv.sim_iface), - NM_MODEM_SIM_OPERATOR_ID, mm_sim_get_operator_identifier (self->_priv.sim_iface), - NULL); - - /* If we're waiting for the SIM during a connect, proceed with the connect */ - if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_SIM) - connect_context_step (self); - } else { - _NMLOG (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND) - ? LOGL_INFO : LOGL_WARN, - "failed to retrieve SIM object: %s", - NM_G_ERROR_MSG (error)); - } - g_clear_error (&error); - g_object_unref (self); + GError *error = NULL; + MMSim * new_sim; + + new_sim = mm_modem_get_sim_finish(modem, res, &error); + if (new_sim != self->_priv.sim_iface) { + g_clear_object(&self->_priv.sim_iface); + self->_priv.sim_iface = new_sim; + } else + g_clear_object(&new_sim); + + if (self->_priv.sim_iface) { + g_object_set(G_OBJECT(self), + NM_MODEM_SIM_ID, + mm_sim_get_identifier(self->_priv.sim_iface), + NM_MODEM_SIM_OPERATOR_ID, + mm_sim_get_operator_identifier(self->_priv.sim_iface), + NULL); + + /* If we're waiting for the SIM during a connect, proceed with the connect */ + if (self->_priv.ctx && self->_priv.ctx->step == CONNECT_STEP_WAIT_FOR_SIM) + connect_context_step(self); + } else { + _NMLOG(g_error_matches(error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND) ? LOGL_INFO + : LOGL_WARN, + "failed to retrieve SIM object: %s", + NM_G_ERROR_MSG(error)); + } + g_clear_error(&error); + g_object_unref(self); } static void -sim_changed (MMModem *modem, GParamSpec *pspec, gpointer user_data) +sim_changed(MMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (user_data); - - g_return_if_fail (modem == self->_priv.modem_iface); - - if (mm_modem_get_sim_path (self->_priv.modem_iface)) { - mm_modem_get_sim (self->_priv.modem_iface, - NULL, /* cancellable */ - (GAsyncReadyCallback) get_sim_ready, - g_object_ref (self)); - } else - g_object_set (G_OBJECT (self), - NM_MODEM_SIM_ID, NULL, - NM_MODEM_SIM_OPERATOR_ID, NULL, - NULL); + NMModemBroadband *self = NM_MODEM_BROADBAND(user_data); + + g_return_if_fail(modem == self->_priv.modem_iface); + + if (mm_modem_get_sim_path(self->_priv.modem_iface)) { + mm_modem_get_sim(self->_priv.modem_iface, + NULL, /* cancellable */ + (GAsyncReadyCallback) get_sim_ready, + g_object_ref(self)); + } else + g_object_set(G_OBJECT(self), NM_MODEM_SIM_ID, NULL, NM_MODEM_SIM_OPERATOR_ID, NULL, NULL); } static void -supported_ip_families_changed (MMModem *modem, GParamSpec *pspec, gpointer user_data) +supported_ip_families_changed(MMModem *modem, GParamSpec *pspec, gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (user_data); + NMModemBroadband *self = NM_MODEM_BROADBAND(user_data); - g_return_if_fail (modem == self->_priv.modem_iface); + g_return_if_fail(modem == self->_priv.modem_iface); - g_object_set (G_OBJECT (self), - NM_MODEM_IP_TYPES, - mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem)), - NULL); + g_object_set(G_OBJECT(self), + NM_MODEM_IP_TYPES, + mm_ip_family_to_nm(mm_modem_get_supported_ip_families(modem)), + NULL); } static void -operator_code_changed (MMModem3gpp *modem_3gpp, GParamSpec *pspec, gpointer user_data) +operator_code_changed(MMModem3gpp *modem_3gpp, GParamSpec *pspec, gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (user_data); + NMModemBroadband *self = NM_MODEM_BROADBAND(user_data); - g_return_if_fail (modem_3gpp == self->_priv.modem_3gpp_iface); - _nm_modem_set_operator_code (NM_MODEM (self), mm_modem_3gpp_get_operator_code (modem_3gpp)); + g_return_if_fail(modem_3gpp == self->_priv.modem_3gpp_iface); + _nm_modem_set_operator_code(NM_MODEM(self), mm_modem_3gpp_get_operator_code(modem_3gpp)); } /*****************************************************************************/ static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMModemBroadband *self = NM_MODEM_BROADBAND (object); - - switch (prop_id) { - case PROP_MODEM: - g_value_set_object (value, self->_priv.modem_object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMModemBroadband *self = NM_MODEM_BROADBAND(object); + + switch (prop_id) { + case PROP_MODEM: + g_value_set_object(value, self->_priv.modem_object); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMModemBroadband *self = NM_MODEM_BROADBAND (object); - - switch (prop_id) { - case PROP_MODEM: - /* construct-only */ - self->_priv.modem_object = g_value_dup_object (value); - self->_priv.modem_iface = mm_object_get_modem (self->_priv.modem_object); - g_return_if_fail (self->_priv.modem_iface); - self->_priv.modem_3gpp_iface = mm_object_get_modem_3gpp (self->_priv.modem_object); - - g_signal_connect (self->_priv.modem_iface, - "state-changed", - G_CALLBACK (modem_state_changed), - self); - g_signal_connect (self->_priv.modem_iface, - "notify::sim", - G_CALLBACK (sim_changed), - self); - sim_changed (self->_priv.modem_iface, NULL, self); - g_signal_connect (self->_priv.modem_iface, - "notify::supported-ip-families", - G_CALLBACK (supported_ip_families_changed), - self); - - if (self->_priv.modem_3gpp_iface) { - g_signal_connect (self->_priv.modem_3gpp_iface, - "notify::operator-code", - G_CALLBACK (operator_code_changed), - self); - } - - /* Note: don't grab the Simple iface here; the Modem interface is the - * only one assumed to be always valid and available */ - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + NMModemBroadband *self = NM_MODEM_BROADBAND(object); + + switch (prop_id) { + case PROP_MODEM: + /* construct-only */ + self->_priv.modem_object = g_value_dup_object(value); + self->_priv.modem_iface = mm_object_get_modem(self->_priv.modem_object); + g_return_if_fail(self->_priv.modem_iface); + self->_priv.modem_3gpp_iface = mm_object_get_modem_3gpp(self->_priv.modem_object); + + g_signal_connect(self->_priv.modem_iface, + "state-changed", + G_CALLBACK(modem_state_changed), + self); + g_signal_connect(self->_priv.modem_iface, "notify::sim", G_CALLBACK(sim_changed), self); + sim_changed(self->_priv.modem_iface, NULL, self); + g_signal_connect(self->_priv.modem_iface, + "notify::supported-ip-families", + G_CALLBACK(supported_ip_families_changed), + self); + + if (self->_priv.modem_3gpp_iface) { + g_signal_connect(self->_priv.modem_3gpp_iface, + "notify::operator-code", + G_CALLBACK(operator_code_changed), + self); + } + + /* Note: don't grab the Simple iface here; the Modem interface is the + * only one assumed to be always valid and available */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_modem_broadband_init (NMModemBroadband *self) -{ -} +nm_modem_broadband_init(NMModemBroadband *self) +{} NMModem * -nm_modem_broadband_new (GObject *object, GError **error) +nm_modem_broadband_new(GObject *object, GError **error) { - MMObject *modem_object; - MMModem *modem_iface; - MMModem3gpp *modem_3gpp_iface; - const char *const*drivers; - const char *operator_code = NULL; - gs_free char *driver = NULL; - - g_return_val_if_fail (MM_IS_OBJECT (object), NULL); - modem_object = MM_OBJECT (object); - - /* Ensure we have the 'Modem' interface and the primary port at least */ - modem_iface = mm_object_peek_modem (modem_object); - g_return_val_if_fail (modem_iface, NULL); - g_return_val_if_fail (mm_modem_get_primary_port (modem_iface), NULL); - - /* Build a single string with all drivers listed */ - drivers = mm_modem_get_drivers (modem_iface); - if (drivers) - driver = g_strjoinv (", ", (char **) drivers); - - modem_3gpp_iface = mm_object_peek_modem_3gpp (modem_object); - if (modem_3gpp_iface) - operator_code = mm_modem_3gpp_get_operator_code (modem_3gpp_iface); - - return g_object_new (NM_TYPE_MODEM_BROADBAND, - NM_MODEM_PATH, mm_object_get_path (modem_object), - NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), - NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), - NM_MODEM_IP_TYPES, mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem_iface)), - NM_MODEM_STATE, (int) mm_state_to_nm (mm_modem_get_state (modem_iface)), - NM_MODEM_DEVICE_ID, mm_modem_get_device_identifier (modem_iface), - NM_MODEM_BROADBAND_MODEM, modem_object, - NM_MODEM_DRIVER, driver, - NM_MODEM_OPERATOR_CODE, operator_code, - NULL); + MMObject * modem_object; + MMModem * modem_iface; + MMModem3gpp * modem_3gpp_iface; + const char *const *drivers; + const char * operator_code = NULL; + gs_free char * driver = NULL; + + g_return_val_if_fail(MM_IS_OBJECT(object), NULL); + modem_object = MM_OBJECT(object); + + /* Ensure we have the 'Modem' interface and the primary port at least */ + modem_iface = mm_object_peek_modem(modem_object); + g_return_val_if_fail(modem_iface, NULL); + g_return_val_if_fail(mm_modem_get_primary_port(modem_iface), NULL); + + /* Build a single string with all drivers listed */ + drivers = mm_modem_get_drivers(modem_iface); + if (drivers) + driver = g_strjoinv(", ", (char **) drivers); + + modem_3gpp_iface = mm_object_peek_modem_3gpp(modem_object); + if (modem_3gpp_iface) + operator_code = mm_modem_3gpp_get_operator_code(modem_3gpp_iface); + + return g_object_new(NM_TYPE_MODEM_BROADBAND, + NM_MODEM_PATH, + mm_object_get_path(modem_object), + NM_MODEM_UID, + mm_modem_get_primary_port(modem_iface), + NM_MODEM_CONTROL_PORT, + mm_modem_get_primary_port(modem_iface), + NM_MODEM_IP_TYPES, + mm_ip_family_to_nm(mm_modem_get_supported_ip_families(modem_iface)), + NM_MODEM_STATE, + (int) mm_state_to_nm(mm_modem_get_state(modem_iface)), + NM_MODEM_DEVICE_ID, + mm_modem_get_device_identifier(modem_iface), + NM_MODEM_BROADBAND_MODEM, + modem_object, + NM_MODEM_DRIVER, + driver, + NM_MODEM_OPERATOR_CODE, + operator_code, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMModemBroadband *self = NM_MODEM_BROADBAND (object); - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE (self); + NMModemBroadband * self = NM_MODEM_BROADBAND(object); + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); - nm_clear_g_source (&priv->idle_id_ip4); - nm_clear_g_source (&priv->idle_id_ip6); + nm_clear_g_source(&priv->idle_id_ip4); + nm_clear_g_source(&priv->idle_id_ip6); - connect_context_clear (self); - g_clear_object (&self->_priv.ipv4_config); - g_clear_object (&self->_priv.ipv6_config); - g_clear_object (&self->_priv.bearer); + connect_context_clear(self); + g_clear_object(&self->_priv.ipv4_config); + g_clear_object(&self->_priv.ipv6_config); + g_clear_object(&self->_priv.bearer); - if (self->_priv.modem_iface) { - g_signal_handlers_disconnect_by_data (self->_priv.modem_iface, self); - g_clear_object (&self->_priv.modem_iface); - } + if (self->_priv.modem_iface) { + g_signal_handlers_disconnect_by_data(self->_priv.modem_iface, self); + g_clear_object(&self->_priv.modem_iface); + } - if (self->_priv.modem_3gpp_iface) { - g_signal_handlers_disconnect_by_data (self->_priv.modem_3gpp_iface, self); - g_clear_object (&self->_priv.modem_3gpp_iface); - } + if (self->_priv.modem_3gpp_iface) { + g_signal_handlers_disconnect_by_data(self->_priv.modem_3gpp_iface, self); + g_clear_object(&self->_priv.modem_3gpp_iface); + } - g_clear_object (&self->_priv.simple_iface); - g_clear_object (&self->_priv.sim_iface); - g_clear_object (&self->_priv.modem_object); + g_clear_object(&self->_priv.simple_iface); + g_clear_object(&self->_priv.sim_iface); + g_clear_object(&self->_priv.modem_object); - G_OBJECT_CLASS (nm_modem_broadband_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_modem_broadband_parent_class)->dispose(object); } static void -nm_modem_broadband_class_init (NMModemBroadbandClass *klass) +nm_modem_broadband_class_init(NMModemBroadbandClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMModemClass *modem_class = NM_MODEM_CLASS (klass); - - object_class->dispose = dispose; - object_class->get_property = get_property; - object_class->set_property = set_property; - - modem_class->get_capabilities = get_capabilities; - modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; - modem_class->stage3_ip6_config_request = stage3_ip6_config_request; - modem_class->disconnect = disconnect; - modem_class->deactivate_cleanup = deactivate_cleanup; - modem_class->set_mm_enabled = set_mm_enabled; - modem_class->get_user_pass = get_user_pass; - modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; - modem_class->complete_connection = complete_connection; - modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare; - modem_class->owns_port = owns_port; - - obj_properties[PROP_MODEM] = - g_param_spec_object (NM_MODEM_BROADBAND_MODEM, "", "", - MM_GDBUS_TYPE_OBJECT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMModemClass *modem_class = NM_MODEM_CLASS(klass); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + modem_class->get_capabilities = get_capabilities; + modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; + modem_class->stage3_ip6_config_request = stage3_ip6_config_request; + modem_class->disconnect = disconnect; + modem_class->deactivate_cleanup = deactivate_cleanup; + modem_class->set_mm_enabled = set_mm_enabled; + modem_class->get_user_pass = get_user_pass; + modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; + modem_class->complete_connection = complete_connection; + modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare; + modem_class->owns_port = owns_port; + + obj_properties[PROP_MODEM] = + g_param_spec_object(NM_MODEM_BROADBAND_MODEM, + "", + "", + MM_GDBUS_TYPE_OBJECT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index 43041e2b..5a822f6f 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2012 - Aleksander Morgado */ @@ -8,18 +8,22 @@ #include "nm-modem.h" -#define NM_TYPE_MODEM_BROADBAND (nm_modem_broadband_get_type ()) -#define NM_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadband)) -#define NM_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) -#define NM_IS_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_BROADBAND)) -#define NM_IS_MODEM_BROADBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_BROADBAND)) -#define NM_MODEM_BROADBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) +#define NM_TYPE_MODEM_BROADBAND (nm_modem_broadband_get_type()) +#define NM_MODEM_BROADBAND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadband)) +#define NM_MODEM_BROADBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) +#define NM_IS_MODEM_BROADBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_BROADBAND)) +#define NM_IS_MODEM_BROADBAND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_BROADBAND)) +#define NM_MODEM_BROADBAND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_BROADBAND, NMModemBroadbandClass)) -typedef struct _NMModemBroadband NMModemBroadband; +typedef struct _NMModemBroadband NMModemBroadband; typedef struct _NMModemBroadbandClass NMModemBroadbandClass; -GType nm_modem_broadband_get_type (void); +GType nm_modem_broadband_get_type(void); -NMModem *nm_modem_broadband_new (GObject *object, GError **error); +NMModem *nm_modem_broadband_new(GObject *object, GError **error); #endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */ diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index daccf68a..65f7c9f9 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. @@ -12,9 +12,9 @@ #include #if HAVE_LIBSYSTEMD -#include + #include #else -#define sd_booted() FALSE + #define sd_booted() FALSE #endif #include "nm-std-aux/nm-dbus-compat.h" @@ -22,560 +22,541 @@ #include "nm-modem-broadband.h" #if WITH_OFONO -#include "nm-modem-ofono.h" + #include "nm-modem-ofono.h" #endif #define MODEM_POKE_INTERVAL 120 /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMModemManager, - PROP_NAME_OWNER, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMModemManager, PROP_NAME_OWNER, ); enum { - MODEM_ADDED, - LAST_SIGNAL, + MODEM_ADDED, + LAST_SIGNAL, }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct { - GDBusConnection *dbus_connection; - - /* used during g_bus_get() and later during mm_manager_new(). */ - GCancellable *main_cancellable; - - struct { - MMManager *manager; - GCancellable *poke_cancellable; - gulong handle_name_owner_changed_id; - gulong handle_object_added_id; - gulong handle_object_removed_id; - guint relaunch_id; - - /* this only has one use: that the logging line about - * ModemManager available distinguishes between first-time - * and later name-owner-changed. */ - enum { - LOG_AVAILABLE_NOT_INITIALIZED = 0, - LOG_AVAILABLE_YES, - LOG_AVAILABLE_NO, - } log_available:3; - - GDBusProxy *proxy; - GCancellable *proxy_cancellable; - guint proxy_ref_count; - char *proxy_name_owner; - } modm; + GDBusConnection *dbus_connection; + + /* used during g_bus_get() and later during mm_manager_new(). */ + GCancellable *main_cancellable; + + struct { + MMManager * manager; + GCancellable *poke_cancellable; + gulong handle_name_owner_changed_id; + gulong handle_object_added_id; + gulong handle_object_removed_id; + guint relaunch_id; + + /* this only has one use: that the logging line about + * ModemManager available distinguishes between first-time + * and later name-owner-changed. */ + enum { + LOG_AVAILABLE_NOT_INITIALIZED = 0, + LOG_AVAILABLE_YES, + LOG_AVAILABLE_NO, + } log_available : 3; + + GDBusProxy * proxy; + GCancellable *proxy_cancellable; + guint proxy_ref_count; + char * proxy_name_owner; + } modm; #if WITH_OFONO - struct { - GDBusProxy *proxy; - GCancellable *cancellable; - } ofono; + struct { + GDBusProxy * proxy; + GCancellable *cancellable; + } ofono; #endif - GHashTable *modems; + GHashTable *modems; } NMModemManagerPrivate; struct _NMModemManager { - GObject parent; - NMModemManagerPrivate _priv; + GObject parent; + NMModemManagerPrivate _priv; }; struct _NMModemManagerClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMModemManager, nm_modem_manager, G_TYPE_OBJECT) -#define NM_MODEM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMModemManager, NM_IS_MODEM_MANAGER) +#define NM_MODEM_MANAGER_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMModemManager, NM_IS_MODEM_MANAGER) /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_MB -#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "modem-manager", __VA_ARGS__) +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "modem-manager", __VA_ARGS__) /*****************************************************************************/ -NM_DEFINE_SINGLETON_GETTER (NMModemManager, nm_modem_manager_get, NM_TYPE_MODEM_MANAGER); +NM_DEFINE_SINGLETON_GETTER(NMModemManager, nm_modem_manager_get, NM_TYPE_MODEM_MANAGER); /*****************************************************************************/ -static void modm_schedule_manager_relaunch (NMModemManager *self, - guint n_seconds); -static void modm_ensure_manager (NMModemManager *self); +static void modm_schedule_manager_relaunch(NMModemManager *self, guint n_seconds); +static void modm_ensure_manager(NMModemManager *self); /*****************************************************************************/ static void -handle_new_modem (NMModemManager *self, NMModem *modem) +handle_new_modem(NMModemManager *self, NMModem *modem) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - const char *path; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + const char * path; - path = nm_modem_get_path (modem); - if (g_hash_table_lookup (priv->modems, path)) { - g_warn_if_reached (); - return; - } + path = nm_modem_get_path(modem); + if (g_hash_table_lookup(priv->modems, path)) { + g_warn_if_reached(); + return; + } - /* Track the new modem */ - g_hash_table_insert (priv->modems, g_strdup (path), modem); - g_signal_emit (self, signals[MODEM_ADDED], 0, modem); + /* Track the new modem */ + g_hash_table_insert(priv->modems, g_strdup(path), modem); + g_signal_emit(self, signals[MODEM_ADDED], 0, modem); } static gboolean -remove_one_modem (gpointer key, gpointer value, gpointer user_data) +remove_one_modem(gpointer key, gpointer value, gpointer user_data) { - nm_modem_emit_removed (NM_MODEM (value)); - return TRUE; + nm_modem_emit_removed(NM_MODEM(value)); + return TRUE; } /*****************************************************************************/ NMModem ** -nm_modem_manager_get_modems (NMModemManager *self, - guint *out_len) +nm_modem_manager_get_modems(NMModemManager *self, guint *out_len) { - g_return_val_if_fail (NM_IS_MODEM_MANAGER (self), NULL); + g_return_val_if_fail(NM_IS_MODEM_MANAGER(self), NULL); - return (NMModem **) nm_utils_hash_values_to_array (NM_MODEM_MANAGER_GET_PRIVATE (self)->modems, - NULL, - NULL, - out_len); + return (NMModem **) nm_utils_hash_values_to_array(NM_MODEM_MANAGER_GET_PRIVATE(self)->modems, + NULL, + NULL, + out_len); } /*****************************************************************************/ static void -modm_clear_manager (NMModemManager *self) +modm_clear_manager(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - if (!priv->modm.manager) - return; - nm_clear_g_signal_handler (priv->modm.manager, &priv->modm.handle_name_owner_changed_id); - nm_clear_g_signal_handler (priv->modm.manager, &priv->modm.handle_object_added_id); - nm_clear_g_signal_handler (priv->modm.manager, &priv->modm.handle_object_removed_id); - g_clear_object (&priv->modm.manager); + if (!priv->modm.manager) + return; + nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_name_owner_changed_id); + nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_object_added_id); + nm_clear_g_signal_handler(priv->modm.manager, &priv->modm.handle_object_removed_id); + g_clear_object(&priv->modm.manager); } static void -modm_handle_object_added (MMManager *modem_manager, - MMObject *modem_object, - NMModemManager *self) -{ - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - const char *path; - MMModem *modem_iface; - NMModem *modem; - GError *error = NULL; - - /* Ensure we don't have the same modem already */ - path = mm_object_get_path (modem_object); - if (g_hash_table_lookup (priv->modems, path)) { - _LOGW ("modem with path %s already exists, ignoring", path); - return; - } - - /* Ensure we have the 'Modem' interface at least */ - modem_iface = mm_object_peek_modem (modem_object); - if (!modem_iface) { - _LOGW ("modem with path %s doesn't have the Modem interface, ignoring", path); - return; - } - - /* Ensure we have a primary port reported */ - if (!mm_modem_get_primary_port (modem_iface)) { - _LOGW ("modem with path %s has unknown primary port, ignoring", path); - return; - } - - /* Create a new modem object */ - modem = nm_modem_broadband_new (G_OBJECT (modem_object), &error); - if (modem) - handle_new_modem (self, modem); - else - _LOGW ("failed to create modem: %s", error->message); - g_clear_error (&error); +modm_handle_object_added(MMManager *modem_manager, MMObject *modem_object, NMModemManager *self) +{ + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + const char * path; + MMModem * modem_iface; + NMModem * modem; + GError * error = NULL; + + /* Ensure we don't have the same modem already */ + path = mm_object_get_path(modem_object); + if (g_hash_table_lookup(priv->modems, path)) { + _LOGW("modem with path %s already exists, ignoring", path); + return; + } + + /* Ensure we have the 'Modem' interface at least */ + modem_iface = mm_object_peek_modem(modem_object); + if (!modem_iface) { + _LOGW("modem with path %s doesn't have the Modem interface, ignoring", path); + return; + } + + /* Ensure we have a primary port reported */ + if (!mm_modem_get_primary_port(modem_iface)) { + _LOGW("modem with path %s has unknown primary port, ignoring", path); + return; + } + + /* Create a new modem object */ + modem = nm_modem_broadband_new(G_OBJECT(modem_object), &error); + if (modem) + handle_new_modem(self, modem); + else + _LOGW("failed to create modem: %s", error->message); + g_clear_error(&error); } static void -modm_handle_object_removed (MMManager *manager, - MMObject *modem_object, - NMModemManager *self) +modm_handle_object_removed(MMManager *manager, MMObject *modem_object, NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - NMModem *modem; - const char *path; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + NMModem * modem; + const char * path; - path = mm_object_get_path (modem_object); - modem = (NMModem *) g_hash_table_lookup (priv->modems, path); - if (!modem) - return; + path = mm_object_get_path(modem_object); + modem = (NMModem *) g_hash_table_lookup(priv->modems, path); + if (!modem) + return; - nm_modem_emit_removed (modem); - g_hash_table_remove (priv->modems, path); + nm_modem_emit_removed(modem); + g_hash_table_remove(priv->modems, path); } static void -modm_manager_available (NMModemManager *self) +modm_manager_available(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - GList *modems, *l; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + GList * modems, *l; - if (priv->modm.log_available != LOG_AVAILABLE_YES) { - _LOGI ("ModemManager %savailable", priv->modm.log_available ? "now " : ""); - priv->modm.log_available = LOG_AVAILABLE_YES; - } + if (priv->modm.log_available != LOG_AVAILABLE_YES) { + _LOGI("ModemManager %savailable", priv->modm.log_available ? "now " : ""); + priv->modm.log_available = LOG_AVAILABLE_YES; + } - /* Update initial modems list */ - modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->modm.manager)); - for (l = modems; l; l = g_list_next (l)) - modm_handle_object_added (priv->modm.manager, MM_OBJECT (l->data), self); - g_list_free_full (modems, (GDestroyNotify) g_object_unref); + /* Update initial modems list */ + modems = g_dbus_object_manager_get_objects(G_DBUS_OBJECT_MANAGER(priv->modm.manager)); + for (l = modems; l; l = g_list_next(l)) + modm_handle_object_added(priv->modm.manager, MM_OBJECT(l->data), self); + g_list_free_full(modems, (GDestroyNotify) g_object_unref); } static void -modm_handle_name_owner_changed (MMManager *modem_manager, - GParamSpec *pspec, - NMModemManager *self) +modm_handle_name_owner_changed(MMManager *modem_manager, GParamSpec *pspec, NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - char *name_owner; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + char * name_owner; - /* Quit poking, if any */ - nm_clear_g_source (&priv->modm.relaunch_id); + /* Quit poking, if any */ + nm_clear_g_source(&priv->modm.relaunch_id); - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager)); - if (!name_owner) { - if (priv->modm.log_available != LOG_AVAILABLE_NO) { - _LOGI ("ModemManager %savailable", priv->modm.log_available ? "no longer " : "not "); - priv->modm.log_available = LOG_AVAILABLE_NO; - } + name_owner = + g_dbus_object_manager_client_get_name_owner(G_DBUS_OBJECT_MANAGER_CLIENT(modem_manager)); + if (!name_owner) { + if (priv->modm.log_available != LOG_AVAILABLE_NO) { + _LOGI("ModemManager %savailable", priv->modm.log_available ? "no longer " : "not "); + priv->modm.log_available = LOG_AVAILABLE_NO; + } - /* If not managed by systemd, schedule relaunch */ - if (!sd_booted ()) - modm_schedule_manager_relaunch (self, 0); + /* If not managed by systemd, schedule relaunch */ + if (!sd_booted()) + modm_schedule_manager_relaunch(self, 0); - return; - } + return; + } - /* Available! */ - g_free (name_owner); + /* Available! */ + g_free(name_owner); - /* Hack alert: GDBusObjectManagerClient won't signal neither 'object-added' - * nor 'object-removed' if it was created while there was no ModemManager in - * the bus. This hack avoids this issue until we get a GIO with the fix - * included... */ - modm_clear_manager (self); - modm_ensure_manager (self); + /* Hack alert: GDBusObjectManagerClient won't signal neither 'object-added' + * nor 'object-removed' if it was created while there was no ModemManager in + * the bus. This hack avoids this issue until we get a GIO with the fix + * included... */ + modm_clear_manager(self); + modm_ensure_manager(self); - /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: - * modm_manager_available (self); - */ + /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: + * modm_manager_available (self); + */ } static void -modm_manager_poke_cb (GObject *connection, - GAsyncResult *res, - gpointer user_data) +modm_manager_poke_cb(GObject *connection, GAsyncResult *res, gpointer user_data) { - NMModemManager *self; - NMModemManagerPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *result = NULL; + NMModemManager * self; + NMModemManagerPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *result = NULL; - result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (connection), res, &error); + result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(connection), res, &error); - if ( !result - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + if (!result && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = user_data; - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + self = user_data; + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_clear_object (&priv->modm.poke_cancellable); + g_clear_object(&priv->modm.poke_cancellable); - if (error) { - _LOGW ("error poking ModemManager: %s", error->message); + if (error) { + _LOGW("error poking ModemManager: %s", error->message); - /* Don't reschedule poke is MM service doesn't exist. */ - if ( !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) - && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { - - /* Setup timeout to relaunch */ - modm_schedule_manager_relaunch (self, MODEM_POKE_INTERVAL); - } - } + /* Don't reschedule poke is MM service doesn't exist. */ + if (!g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) + && !g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { + /* Setup timeout to relaunch */ + modm_schedule_manager_relaunch(self, MODEM_POKE_INTERVAL); + } + } } static void -modm_manager_poke (NMModemManager *self) +modm_manager_poke(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - nm_clear_g_cancellable (&priv->modm.poke_cancellable); - priv->modm.poke_cancellable = g_cancellable_new (); + nm_clear_g_cancellable(&priv->modm.poke_cancellable); + priv->modm.poke_cancellable = g_cancellable_new(); - /* If there is no current owner right away, ensure we poke to get one */ - g_dbus_connection_call (priv->dbus_connection, - NM_MODEM_MANAGER_MM_DBUS_SERVICE, - NM_MODEM_MANAGER_MM_DBUS_PATH, - DBUS_INTERFACE_PEER, - "Ping", - NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->modm.poke_cancellable, - modm_manager_poke_cb, - self); + /* If there is no current owner right away, ensure we poke to get one */ + g_dbus_connection_call(priv->dbus_connection, + NM_MODEM_MANAGER_MM_DBUS_SERVICE, + NM_MODEM_MANAGER_MM_DBUS_PATH, + DBUS_INTERFACE_PEER, + "Ping", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->modm.poke_cancellable, + modm_manager_poke_cb, + self); } static void -modm_manager_check_name_owner (NMModemManager *self) +modm_manager_check_name_owner(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - gs_free char *name_owner = NULL; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + gs_free char * name_owner = NULL; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->modm.manager)); - if (name_owner) { - modm_manager_available (self); - return; - } + name_owner = g_dbus_object_manager_client_get_name_owner( + G_DBUS_OBJECT_MANAGER_CLIENT(priv->modm.manager)); + if (name_owner) { + modm_manager_available(self); + return; + } - /* If the lifecycle is not managed by systemd, poke */ - if (!sd_booted ()) - modm_manager_poke (self); + /* If the lifecycle is not managed by systemd, poke */ + if (!sd_booted()) + modm_manager_poke(self); } static void -modm_manager_new_cb (GObject *source, - GAsyncResult *res, - gpointer user_data) -{ - NMModemManager *self; - NMModemManagerPrivate *priv; - gs_free_error GError *error = NULL; - MMManager *modem_manager; - - modem_manager = mm_manager_new_finish (res, &error); - if ( !modem_manager - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = user_data; - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - - nm_assert (!priv->modm.manager); - - g_clear_object (&priv->main_cancellable); - - if (!modem_manager) { - /* We're not really supposed to get any error here. If we do get one, - * though, just re-schedule the MMManager creation after some time. - * During this period, name-owner changes won't be followed. */ - _LOGW ("error creating ModemManager client: %s", error->message); - /* Setup timeout to relaunch */ - modm_schedule_manager_relaunch (self, MODEM_POKE_INTERVAL); - return; - } - - priv->modm.manager = modem_manager; - - /* Setup signals in the GDBusObjectManagerClient */ - priv->modm.handle_name_owner_changed_id = - g_signal_connect (priv->modm.manager, - "notify::name-owner", - G_CALLBACK (modm_handle_name_owner_changed), - self); - priv->modm.handle_object_added_id = - g_signal_connect (priv->modm.manager, - "object-added", - G_CALLBACK (modm_handle_object_added), - self); - priv->modm.handle_object_removed_id = - g_signal_connect (priv->modm.manager, - "object-removed", - G_CALLBACK (modm_handle_object_removed), - self); - - modm_manager_check_name_owner (self); +modm_manager_new_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + NMModemManager * self; + NMModemManagerPrivate *priv; + gs_free_error GError *error = NULL; + MMManager * modem_manager; + + modem_manager = mm_manager_new_finish(res, &error); + if (!modem_manager && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = user_data; + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + + nm_assert(!priv->modm.manager); + + g_clear_object(&priv->main_cancellable); + + if (!modem_manager) { + /* We're not really supposed to get any error here. If we do get one, + * though, just re-schedule the MMManager creation after some time. + * During this period, name-owner changes won't be followed. */ + _LOGW("error creating ModemManager client: %s", error->message); + /* Setup timeout to relaunch */ + modm_schedule_manager_relaunch(self, MODEM_POKE_INTERVAL); + return; + } + + priv->modm.manager = modem_manager; + + /* Setup signals in the GDBusObjectManagerClient */ + priv->modm.handle_name_owner_changed_id = + g_signal_connect(priv->modm.manager, + "notify::name-owner", + G_CALLBACK(modm_handle_name_owner_changed), + self); + priv->modm.handle_object_added_id = g_signal_connect(priv->modm.manager, + "object-added", + G_CALLBACK(modm_handle_object_added), + self); + priv->modm.handle_object_removed_id = g_signal_connect(priv->modm.manager, + "object-removed", + G_CALLBACK(modm_handle_object_removed), + self); + + modm_manager_check_name_owner(self); } static void -modm_ensure_manager (NMModemManager *self) +modm_ensure_manager(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_assert (priv->dbus_connection); + g_assert(priv->dbus_connection); - /* Create the GDBusObjectManagerClient. We do not request to autostart, as - * we don't really want the MMManager creation to fail. We can always poke - * later on if we want to request the autostart */ - if (!priv->modm.manager) { - if (!priv->main_cancellable) - priv->main_cancellable = g_cancellable_new (); - mm_manager_new (priv->dbus_connection, - G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, - priv->main_cancellable, - modm_manager_new_cb, - self); - return; - } + /* Create the GDBusObjectManagerClient. We do not request to autostart, as + * we don't really want the MMManager creation to fail. We can always poke + * later on if we want to request the autostart */ + if (!priv->modm.manager) { + if (!priv->main_cancellable) + priv->main_cancellable = g_cancellable_new(); + mm_manager_new(priv->dbus_connection, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, + priv->main_cancellable, + modm_manager_new_cb, + self); + return; + } - /* If already available, recheck name owner! */ - modm_manager_check_name_owner (self); + /* If already available, recheck name owner! */ + modm_manager_check_name_owner(self); } static gboolean -modm_schedule_manager_relaunch_cb (NMModemManager *self) +modm_schedule_manager_relaunch_cb(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - priv->modm.relaunch_id = 0; - modm_ensure_manager (self); - return G_SOURCE_REMOVE; + priv->modm.relaunch_id = 0; + modm_ensure_manager(self); + return G_SOURCE_REMOVE; } static void -modm_schedule_manager_relaunch (NMModemManager *self, - guint n_seconds) +modm_schedule_manager_relaunch(NMModemManager *self, guint n_seconds) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - /* No need to pass an extra reference to self; timeout/idle will be - * cancelled if the object gets disposed. */ - if (n_seconds) - priv->modm.relaunch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)modm_schedule_manager_relaunch_cb, self); - else - priv->modm.relaunch_id = g_idle_add ((GSourceFunc)modm_schedule_manager_relaunch_cb, self); + /* No need to pass an extra reference to self; timeout/idle will be + * cancelled if the object gets disposed. */ + if (n_seconds) + priv->modm.relaunch_id = + g_timeout_add_seconds(n_seconds, (GSourceFunc) modm_schedule_manager_relaunch_cb, self); + else + priv->modm.relaunch_id = g_idle_add((GSourceFunc) modm_schedule_manager_relaunch_cb, self); } /*****************************************************************************/ static void -modm_proxy_name_owner_reset (NMModemManager *self) +modm_proxy_name_owner_reset(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - char *name = NULL; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + char * name = NULL; - if (priv->modm.proxy) - name = g_dbus_proxy_get_name_owner (priv->modm.proxy); + if (priv->modm.proxy) + name = g_dbus_proxy_get_name_owner(priv->modm.proxy); - if (nm_streq0 (priv->modm.proxy_name_owner, name)) { - g_free (name); - return; - } - g_free (priv->modm.proxy_name_owner); - priv->modm.proxy_name_owner = name; + if (nm_streq0(priv->modm.proxy_name_owner, name)) { + g_free(name); + return; + } + g_free(priv->modm.proxy_name_owner); + priv->modm.proxy_name_owner = name; - _notify (self, PROP_NAME_OWNER); + _notify(self, PROP_NAME_OWNER); } static void -modm_proxy_name_owner_changed_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) +modm_proxy_name_owner_changed_cb(GObject *object, GParamSpec *pspec, gpointer user_data) { - modm_proxy_name_owner_reset (user_data); + modm_proxy_name_owner_reset(user_data); } static void -modm_proxy_new_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +modm_proxy_new_cb(GObject *source_object, GAsyncResult *result, gpointer user_data) { - NMModemManager *self; - NMModemManagerPrivate *priv; - GDBusProxy *proxy; - gs_free_error GError *error = NULL; + NMModemManager * self; + NMModemManagerPrivate *priv; + GDBusProxy * proxy; + gs_free_error GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (result, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + proxy = g_dbus_proxy_new_for_bus_finish(result, &error); + if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = user_data; - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + self = user_data; + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_clear_object (&priv->modm.proxy_cancellable); + g_clear_object(&priv->modm.proxy_cancellable); - if (!proxy) { - _LOGW ("could not obtain D-Bus proxy for ModemManager: %s", error->message); - return; - } + if (!proxy) { + _LOGW("could not obtain D-Bus proxy for ModemManager: %s", error->message); + return; + } - priv->modm.proxy = proxy; - g_signal_connect (priv->modm.proxy, "notify::g-name-owner", - G_CALLBACK (modm_proxy_name_owner_changed_cb), self); + priv->modm.proxy = proxy; + g_signal_connect(priv->modm.proxy, + "notify::g-name-owner", + G_CALLBACK(modm_proxy_name_owner_changed_cb), + self); - modm_proxy_name_owner_reset (self); + modm_proxy_name_owner_reset(self); } void -nm_modem_manager_name_owner_ref (NMModemManager *self) +nm_modem_manager_name_owner_ref(NMModemManager *self) { - NMModemManagerPrivate *priv; + NMModemManagerPrivate *priv; - g_return_if_fail (NM_IS_MODEM_MANAGER (self)); + g_return_if_fail(NM_IS_MODEM_MANAGER(self)); - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - if (priv->modm.proxy_ref_count++ > 0) { - /* only try once to create the proxy. If proxy creation - * for the first "ref" failed, it's unclear what to do. - * The proxy is hosed. */ - return; - } + if (priv->modm.proxy_ref_count++ > 0) { + /* only try once to create the proxy. If proxy creation + * for the first "ref" failed, it's unclear what to do. + * The proxy is hosed. */ + return; + } - nm_assert (!priv->modm.proxy && !priv->modm.proxy_cancellable); + nm_assert(!priv->modm.proxy && !priv->modm.proxy_cancellable); - priv->modm.proxy_cancellable = g_cancellable_new (); + priv->modm.proxy_cancellable = g_cancellable_new(); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - NM_MODEM_MANAGER_MM_DBUS_SERVICE, - NM_MODEM_MANAGER_MM_DBUS_PATH, - NM_MODEM_MANAGER_MM_DBUS_INTERFACE, - priv->modm.proxy_cancellable, - modm_proxy_new_cb, - self); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_MODEM_MANAGER_MM_DBUS_SERVICE, + NM_MODEM_MANAGER_MM_DBUS_PATH, + NM_MODEM_MANAGER_MM_DBUS_INTERFACE, + priv->modm.proxy_cancellable, + modm_proxy_new_cb, + self); } void -nm_modem_manager_name_owner_unref (NMModemManager *self) +nm_modem_manager_name_owner_unref(NMModemManager *self) { - NMModemManagerPrivate *priv; + NMModemManagerPrivate *priv; - g_return_if_fail (NM_IS_MODEM_MANAGER (self)); + g_return_if_fail(NM_IS_MODEM_MANAGER(self)); - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_return_if_fail (priv->modm.proxy_ref_count > 0); + g_return_if_fail(priv->modm.proxy_ref_count > 0); - if (--priv->modm.proxy_ref_count > 0) - return; + if (--priv->modm.proxy_ref_count > 0) + return; - nm_clear_g_cancellable (&priv->modm.proxy_cancellable); - g_clear_object (&priv->modm.proxy); + nm_clear_g_cancellable(&priv->modm.proxy_cancellable); + g_clear_object(&priv->modm.proxy); - modm_proxy_name_owner_reset (self); + modm_proxy_name_owner_reset(self); } const char * -nm_modem_manager_name_owner_get (NMModemManager *self) +nm_modem_manager_name_owner_get(NMModemManager *self) { - g_return_val_if_fail (NM_IS_MODEM_MANAGER (self), NULL); - nm_assert (NM_MODEM_MANAGER_GET_PRIVATE (self)->modm.proxy_ref_count > 0); + g_return_val_if_fail(NM_IS_MODEM_MANAGER(self), NULL); + nm_assert(NM_MODEM_MANAGER_GET_PRIVATE(self)->modm.proxy_ref_count > 0); - return NM_MODEM_MANAGER_GET_PRIVATE (self)->modm.proxy_name_owner; + return NM_MODEM_MANAGER_GET_PRIVATE(self)->modm.proxy_name_owner; } /*****************************************************************************/ @@ -583,328 +564,313 @@ nm_modem_manager_name_owner_get (NMModemManager *self) #if WITH_OFONO static void -ofono_create_modem (NMModemManager *self, const char *path) +ofono_create_modem(NMModemManager *self, const char *path) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - NMModem *modem = NULL; + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + NMModem * modem = NULL; - /* Ensure duplicate modems aren't created. Because we're not using the - * ObjectManager interface there's a race during oFono startup where we - * receive ModemAdded signals before GetModems() returns, so some of the - * modems returned from GetModems() may already have been created. - */ - if (!g_hash_table_lookup (priv->modems, path)) { - modem = nm_modem_ofono_new (path); - if (modem) - handle_new_modem (self, modem); - else - _LOGW ("Failed to create oFono modem for %s", path); - } + /* Ensure duplicate modems aren't created. Because we're not using the + * ObjectManager interface there's a race during oFono startup where we + * receive ModemAdded signals before GetModems() returns, so some of the + * modems returned from GetModems() may already have been created. + */ + if (!g_hash_table_lookup(priv->modems, path)) { + modem = nm_modem_ofono_new(path); + if (modem) + handle_new_modem(self, modem); + else + _LOGW("Failed to create oFono modem for %s", path); + } } static void -ofono_signal_cb (GDBusProxy *proxy, - char *sender_name, - char *signal_name, - GVariant *parameters, - gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - char *object_path; - NMModem *modem; - - if (g_strcmp0 (signal_name, "ModemAdded") == 0) { - g_variant_get (parameters, "(oa{sv})", &object_path, NULL); - _LOGI ("oFono modem appeared: %s", object_path); - - ofono_create_modem (NM_MODEM_MANAGER (user_data), object_path); - g_free (object_path); - } else if (g_strcmp0 (signal_name, "ModemRemoved") == 0) { - g_variant_get (parameters, "(o)", &object_path); - _LOGI ("oFono modem removed: %s", object_path); - - modem = (NMModem *) g_hash_table_lookup (priv->modems, object_path); - if (modem) { - nm_modem_emit_removed (modem); - g_hash_table_remove (priv->modems, object_path); - } else { - _LOGW ("could not remove modem %s, not found in table", - object_path); - } - g_free (object_path); - } +ofono_signal_cb(GDBusProxy *proxy, + char * sender_name, + char * signal_name, + GVariant * parameters, + gpointer user_data) +{ + NMModemManager * self = NM_MODEM_MANAGER(user_data); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + char * object_path; + NMModem * modem; + + if (g_strcmp0(signal_name, "ModemAdded") == 0) { + g_variant_get(parameters, "(oa{sv})", &object_path, NULL); + _LOGI("oFono modem appeared: %s", object_path); + + ofono_create_modem(NM_MODEM_MANAGER(user_data), object_path); + g_free(object_path); + } else if (g_strcmp0(signal_name, "ModemRemoved") == 0) { + g_variant_get(parameters, "(o)", &object_path); + _LOGI("oFono modem removed: %s", object_path); + + modem = (NMModem *) g_hash_table_lookup(priv->modems, object_path); + if (modem) { + nm_modem_emit_removed(modem); + g_hash_table_remove(priv->modems, object_path); + } else { + _LOGW("could not remove modem %s, not found in table", object_path); + } + g_free(object_path); + } } static void -ofono_enumerate_devices_done (GObject *proxy, - GAsyncResult *res, - gpointer user_data) +ofono_enumerate_devices_done(GObject *proxy, GAsyncResult *res, gpointer user_data) { - NMModemManager *self; - NMModemManagerPrivate *priv; - gs_free_error GError *error = NULL; - GVariant *results; - GVariantIter *iter; - const char *path; + NMModemManager * self; + NMModemManagerPrivate *priv; + gs_free_error GError *error = NULL; + GVariant * results; + GVariantIter * iter; + const char * path; - results = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, &error); - if ( !results - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + results = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error); + if (!results && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = NM_MODEM_MANAGER (user_data); - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + self = NM_MODEM_MANAGER(user_data); + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_clear_object (&priv->ofono.cancellable); + g_clear_object(&priv->ofono.cancellable); - if (!results) { - _LOGW ("failed to enumerate oFono devices: %s", - error->message); - return; - } + if (!results) { + _LOGW("failed to enumerate oFono devices: %s", error->message); + return; + } - g_variant_get (results, "(a(oa{sv}))", &iter); - while (g_variant_iter_loop (iter, "(&oa{sv})", &path, NULL)) - ofono_create_modem (self, path); - g_variant_iter_free (iter); - g_variant_unref (results); + g_variant_get(results, "(a(oa{sv}))", &iter); + while (g_variant_iter_loop(iter, "(&oa{sv})", &path, NULL)) + ofono_create_modem(self, path); + g_variant_iter_free(iter); + g_variant_unref(results); } static void -ofono_check_name_owner (NMModemManager *self, gboolean first_invocation) -{ - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - gs_free char *name_owner = NULL; - - name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->ofono.proxy)); - if (name_owner) { - _LOGI ("oFono is %savailable", first_invocation ? "" : "now "); - - nm_clear_g_cancellable (&priv->ofono.cancellable); - priv->ofono.cancellable = g_cancellable_new (); - - g_dbus_proxy_call (priv->ofono.proxy, - "GetModems", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->ofono.cancellable, - ofono_enumerate_devices_done, - self); - } else { - GHashTableIter iter; - NMModem *modem; - - _LOGI ("oFono is %savailable", first_invocation ? "not " : "no longer "); - - /* Remove any oFono modems that might be left around */ - g_hash_table_iter_init (&iter, priv->modems); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &modem)) { - if (NM_IS_MODEM_OFONO (modem)) { - nm_modem_emit_removed (modem); - g_hash_table_iter_remove (&iter); - } - } - } +ofono_check_name_owner(NMModemManager *self, gboolean first_invocation) +{ + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); + gs_free char * name_owner = NULL; + + name_owner = g_dbus_proxy_get_name_owner(G_DBUS_PROXY(priv->ofono.proxy)); + if (name_owner) { + _LOGI("oFono is %savailable", first_invocation ? "" : "now "); + + nm_clear_g_cancellable(&priv->ofono.cancellable); + priv->ofono.cancellable = g_cancellable_new(); + + g_dbus_proxy_call(priv->ofono.proxy, + "GetModems", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->ofono.cancellable, + ofono_enumerate_devices_done, + self); + } else { + GHashTableIter iter; + NMModem * modem; + + _LOGI("oFono is %savailable", first_invocation ? "not " : "no longer "); + + /* Remove any oFono modems that might be left around */ + g_hash_table_iter_init(&iter, priv->modems); + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &modem)) { + if (NM_IS_MODEM_OFONO(modem)) { + nm_modem_emit_removed(modem); + g_hash_table_iter_remove(&iter); + } + } + } } static void -ofono_name_owner_changed (GDBusProxy *ofono_proxy, - GParamSpec *pspec, - NMModemManager *self) +ofono_name_owner_changed(GDBusProxy *ofono_proxy, GParamSpec *pspec, NMModemManager *self) { - ofono_check_name_owner (self, FALSE); + ofono_check_name_owner(self, FALSE); } static void -ofono_proxy_new_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +ofono_proxy_new_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMModemManager *self; - NMModemManagerPrivate *priv; - gs_free_error GError *error = NULL; - GDBusProxy *proxy; + NMModemManager * self; + NMModemManagerPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy * proxy; - proxy = g_dbus_proxy_new_finish (res, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + proxy = g_dbus_proxy_new_finish(res, &error); + if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = NM_MODEM_MANAGER (user_data); - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + self = NM_MODEM_MANAGER(user_data); + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - g_clear_object (&priv->ofono.cancellable); + g_clear_object(&priv->ofono.cancellable); - if (!proxy) { - _LOGW ("error getting oFono bus proxy: %s", error->message); - return; - } + if (!proxy) { + _LOGW("error getting oFono bus proxy: %s", error->message); + return; + } - priv->ofono.proxy = proxy; + priv->ofono.proxy = proxy; - g_signal_connect (priv->ofono.proxy, - "notify::g-name-owner", - G_CALLBACK (ofono_name_owner_changed), - self); + g_signal_connect(priv->ofono.proxy, + "notify::g-name-owner", + G_CALLBACK(ofono_name_owner_changed), + self); - g_signal_connect (priv->ofono.proxy, - "g-signal", - G_CALLBACK (ofono_signal_cb), - self); + g_signal_connect(priv->ofono.proxy, "g-signal", G_CALLBACK(ofono_signal_cb), self); - ofono_check_name_owner (self, TRUE); + ofono_check_name_owner(self, TRUE); } static void -ofono_init_proxy (NMModemManager *self) +ofono_init_proxy(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - nm_assert (priv->dbus_connection); - nm_assert (!priv->ofono.cancellable); + nm_assert(priv->dbus_connection); + nm_assert(!priv->ofono.cancellable); - priv->ofono.cancellable = g_cancellable_new (); + priv->ofono.cancellable = g_cancellable_new(); - g_dbus_proxy_new (priv->dbus_connection, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - OFONO_DBUS_SERVICE, - OFONO_DBUS_PATH, - OFONO_DBUS_INTERFACE, - priv->ofono.cancellable, - ofono_proxy_new_cb, - self); + g_dbus_proxy_new(priv->dbus_connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + OFONO_DBUS_PATH, + OFONO_DBUS_INTERFACE, + priv->ofono.cancellable, + ofono_proxy_new_cb, + self); } #endif /*****************************************************************************/ static void -bus_get_ready (GObject *source, - GAsyncResult *res, - gpointer user_data) +bus_get_ready(GObject *source, GAsyncResult *res, gpointer user_data) { - NMModemManager *self; - NMModemManagerPrivate *priv; - gs_free_error GError *error = NULL; - GDBusConnection *connection; + NMModemManager * self; + NMModemManagerPrivate *priv; + gs_free_error GError *error = NULL; + GDBusConnection * connection; - connection = g_bus_get_finish (res, &error); - if ( !connection - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + connection = g_bus_get_finish(res, &error); + if (!connection && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = NM_MODEM_MANAGER (user_data); - priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + self = NM_MODEM_MANAGER(user_data); + priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - if (!connection) { - _LOGW ("error getting bus connection: %s", error->message); - return; - } + if (!connection) { + _LOGW("error getting bus connection: %s", error->message); + return; + } - priv->dbus_connection = connection; + priv->dbus_connection = connection; - modm_ensure_manager (self); + modm_ensure_manager(self); #if WITH_OFONO - ofono_init_proxy (self); + ofono_init_proxy(self); #endif } /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMModemManager *self = NM_MODEM_MANAGER (object); - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManager * self = NM_MODEM_MANAGER(object); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - switch (prop_id) { - case PROP_NAME_OWNER: - g_value_set_string (value, priv->modm.proxy_name_owner); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + switch (prop_id) { + case PROP_NAME_OWNER: + g_value_set_string(value, priv->modm.proxy_name_owner); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_modem_manager_init (NMModemManager *self) +nm_modem_manager_init(NMModemManager *self) { - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - priv->modems = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); + priv->modems = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref); - priv->main_cancellable = g_cancellable_new (); + priv->main_cancellable = g_cancellable_new(); - g_bus_get (G_BUS_TYPE_SYSTEM, - priv->main_cancellable, - bus_get_ready, - self); + g_bus_get(G_BUS_TYPE_SYSTEM, priv->main_cancellable, bus_get_ready, self); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMModemManager *self = NM_MODEM_MANAGER (object); - NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); + NMModemManager * self = NM_MODEM_MANAGER(object); + NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE(self); - nm_clear_g_cancellable (&priv->main_cancellable); - nm_clear_g_cancellable (&priv->modm.poke_cancellable); + nm_clear_g_cancellable(&priv->main_cancellable); + nm_clear_g_cancellable(&priv->modm.poke_cancellable); - nm_clear_g_source (&priv->modm.relaunch_id); + nm_clear_g_source(&priv->modm.relaunch_id); - nm_clear_g_cancellable (&priv->modm.proxy_cancellable); - g_clear_object (&priv->modm.proxy); - nm_clear_g_free (&priv->modm.proxy_name_owner); + nm_clear_g_cancellable(&priv->modm.proxy_cancellable); + g_clear_object(&priv->modm.proxy); + nm_clear_g_free(&priv->modm.proxy_name_owner); - modm_clear_manager (self); + modm_clear_manager(self); #if WITH_OFONO - if (priv->ofono.proxy) { - g_signal_handlers_disconnect_by_func (priv->ofono.proxy, ofono_name_owner_changed, self); - g_signal_handlers_disconnect_by_func (priv->ofono.proxy, ofono_signal_cb, self); - g_clear_object (&priv->ofono.proxy); - } - nm_clear_g_cancellable (&priv->ofono.cancellable); + if (priv->ofono.proxy) { + g_signal_handlers_disconnect_by_func(priv->ofono.proxy, ofono_name_owner_changed, self); + g_signal_handlers_disconnect_by_func(priv->ofono.proxy, ofono_signal_cb, self); + g_clear_object(&priv->ofono.proxy); + } + nm_clear_g_cancellable(&priv->ofono.cancellable); #endif - g_clear_object (&priv->dbus_connection); + g_clear_object(&priv->dbus_connection); - if (priv->modems) { - g_hash_table_foreach_remove (priv->modems, remove_one_modem, object); - g_hash_table_destroy (priv->modems); - priv->modems = NULL; - } + if (priv->modems) { + g_hash_table_foreach_remove(priv->modems, remove_one_modem, object); + g_hash_table_destroy(priv->modems); + priv->modems = NULL; + } - G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_modem_manager_parent_class)->dispose(object); } static void -nm_modem_manager_class_init (NMModemManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = dispose; - object_class->get_property = get_property; - - obj_properties[PROP_NAME_OWNER] = - g_param_spec_string (NM_MODEM_MANAGER_NAME_OWNER, "", "", - NULL, - G_PARAM_READABLE - | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[MODEM_ADDED] = - g_signal_new (NM_MODEM_MANAGER_MODEM_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, NM_TYPE_MODEM); +nm_modem_manager_class_init(NMModemManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->dispose = dispose; + object_class->get_property = get_property; + + obj_properties[PROP_NAME_OWNER] = + g_param_spec_string(NM_MODEM_MANAGER_NAME_OWNER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[MODEM_ADDED] = g_signal_new(NM_MODEM_MANAGER_MODEM_ADDED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + NM_TYPE_MODEM); } diff --git a/src/devices/wwan/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h index 97a2126a..895d4ced 100644 --- a/src/devices/wwan/nm-modem-manager.h +++ b/src/devices/wwan/nm-modem-manager.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. @@ -10,12 +10,15 @@ #include "nm-modem.h" -#define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type ()) -#define NM_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_MANAGER, NMModemManager)) -#define NM_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) -#define NM_IS_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_MANAGER)) -#define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_MANAGER)) -#define NM_MODEM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) +#define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type()) +#define NM_MODEM_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_MANAGER, NMModemManager)) +#define NM_MODEM_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) +#define NM_IS_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_MANAGER)) +#define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_MANAGER)) +#define NM_MODEM_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) #define NM_MODEM_MANAGER_MODEM_ADDED "modem-added" @@ -25,19 +28,18 @@ #define NM_MODEM_MANAGER_MM_DBUS_PATH "/org/freedesktop/ModemManager1" #define NM_MODEM_MANAGER_MM_DBUS_INTERFACE "org.freedesktop.ModemManager1" -typedef struct _NMModemManager NMModemManager; +typedef struct _NMModemManager NMModemManager; typedef struct _NMModemManagerClass NMModemManagerClass; -GType nm_modem_manager_get_type (void); +GType nm_modem_manager_get_type(void); -NMModemManager *nm_modem_manager_get (void); +NMModemManager *nm_modem_manager_get(void); -void nm_modem_manager_name_owner_ref (NMModemManager *self); -void nm_modem_manager_name_owner_unref (NMModemManager *self); +void nm_modem_manager_name_owner_ref(NMModemManager *self); +void nm_modem_manager_name_owner_unref(NMModemManager *self); -const char *nm_modem_manager_name_owner_get (NMModemManager *self); +const char *nm_modem_manager_name_owner_get(NMModemManager *self); -NMModem **nm_modem_manager_get_modems (NMModemManager *self, - guint *out_len); +NMModem **nm_modem_manager_get_modems(NMModemManager *self, guint *out_len); #endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */ diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c index 96b08e7c..d8d0893b 100644 --- a/src/devices/wwan/nm-modem-ofono.c +++ b/src/devices/wwan/nm-modem-ofono.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - 2016 Canonical Ltd. */ @@ -13,1287 +13,1227 @@ #include "platform/nm-platform.h" #include "nm-ip4-config.h" -#define VARIANT_IS_OF_TYPE_BOOLEAN(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_BOOLEAN) )) -#define VARIANT_IS_OF_TYPE_STRING(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING) )) -#define VARIANT_IS_OF_TYPE_OBJECT_PATH(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_OBJECT_PATH) )) -#define VARIANT_IS_OF_TYPE_STRING_ARRAY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_STRING_ARRAY) )) -#define VARIANT_IS_OF_TYPE_DICTIONARY(v) ((v) != NULL && ( g_variant_is_of_type ((v), G_VARIANT_TYPE_DICTIONARY) )) +#define VARIANT_IS_OF_TYPE_BOOLEAN(v) \ + ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_BOOLEAN))) +#define VARIANT_IS_OF_TYPE_STRING(v) \ + ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_STRING))) +#define VARIANT_IS_OF_TYPE_OBJECT_PATH(v) \ + ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_OBJECT_PATH))) +#define VARIANT_IS_OF_TYPE_STRING_ARRAY(v) \ + ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_STRING_ARRAY))) +#define VARIANT_IS_OF_TYPE_DICTIONARY(v) \ + ((v) != NULL && (g_variant_is_of_type((v), G_VARIANT_TYPE_DICTIONARY))) /*****************************************************************************/ typedef struct { - GHashTable *connect_properties; + GHashTable *connect_properties; - GDBusProxy *modem_proxy; - GDBusProxy *connman_proxy; - GDBusProxy *context_proxy; - GDBusProxy *sim_proxy; + GDBusProxy *modem_proxy; + GDBusProxy *connman_proxy; + GDBusProxy *context_proxy; + GDBusProxy *sim_proxy; - GCancellable *modem_proxy_cancellable; - GCancellable *connman_proxy_cancellable; - GCancellable *context_proxy_cancellable; - GCancellable *sim_proxy_cancellable; + GCancellable *modem_proxy_cancellable; + GCancellable *connman_proxy_cancellable; + GCancellable *context_proxy_cancellable; + GCancellable *sim_proxy_cancellable; - GError *property_error; + GError *property_error; - char *context_path; - char *imsi; + char *context_path; + char *imsi; - gboolean modem_online; - gboolean gprs_attached; + gboolean modem_online; + gboolean gprs_attached; - NMIP4Config *ip4_config; + NMIP4Config *ip4_config; } NMModemOfonoPrivate; struct _NMModemOfono { - NMModem parent; - NMModemOfonoPrivate _priv; + NMModem parent; + NMModemOfonoPrivate _priv; }; struct _NMModemOfonoClass { - NMModemClass parent; + NMModemClass parent; }; -G_DEFINE_TYPE (NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM) +G_DEFINE_TYPE(NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM) -#define NM_MODEM_OFONO_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMModemOfono, NM_IS_MODEM_OFONO) +#define NM_MODEM_OFONO_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMModemOfono, NM_IS_MODEM_OFONO) /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_MB #define _NMLOG_PREFIX_NAME "modem-ofono" -#define _NMLOG(level, ...) \ - G_STMT_START { \ - const NMLogLevel _level = (level); \ - \ - if (nm_logging_enabled (_level, (_NMLOG_DOMAIN))) { \ - NMModemOfono *const __self = (self); \ - char __prefix_name[128]; \ - const char *__uid; \ - \ - _nm_log (_level, (_NMLOG_DOMAIN), 0, NULL, NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - (__self \ - ? ({ \ - ((__uid = nm_modem_get_uid ((NMModem *) __self)) \ - ? nm_sprintf_buf (__prefix_name, "[%s]", __uid) \ - : "(null)"); \ - }) \ - : "") \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, (_NMLOG_DOMAIN))) { \ + NMModemOfono *const __self = (self); \ + char __prefix_name[128]; \ + const char * __uid; \ + \ + _nm_log(_level, \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (__self ? ({ \ + ((__uid = nm_modem_get_uid((NMModem *) __self)) \ + ? nm_sprintf_buf(__prefix_name, "[%s]", __uid) \ + : "(null)"); \ + }) \ + : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ static void -get_capabilities (NMModem *_self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) +get_capabilities(NMModem * _self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) { - /* FIXME: auto-detect capabilities to allow LTE */ - *modem_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; - *current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; + /* FIXME: auto-detect capabilities to allow LTE */ + *modem_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; + *current_caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; } static void -update_modem_state (NMModemOfono *self) +update_modem_state(NMModemOfono *self) { - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - NMModemState state = nm_modem_get_state (NM_MODEM (self)); - NMModemState new_state = NM_MODEM_STATE_DISABLED; - const char *reason = NULL; - - _LOGI ("'Attached': %s 'Online': %s 'IMSI': %s", - priv->gprs_attached ? "true" : "false", - priv->modem_online ? "true" : "false", - priv->imsi); - - if (priv->modem_online == FALSE) { - reason = "modem 'Online=false'"; - } else if (priv->imsi == NULL && state != NM_MODEM_STATE_ENABLING) { - reason = "modem not ready"; - } else if (priv->gprs_attached == FALSE) { - new_state = NM_MODEM_STATE_SEARCHING; - reason = "modem searching"; - } else { - new_state = NM_MODEM_STATE_REGISTERED; - reason = "modem ready"; - } - - if (state != new_state) - nm_modem_set_state (NM_MODEM (self), new_state, reason); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + NMModemState state = nm_modem_get_state(NM_MODEM(self)); + NMModemState new_state = NM_MODEM_STATE_DISABLED; + const char * reason = NULL; + + _LOGI("'Attached': %s 'Online': %s 'IMSI': %s", + priv->gprs_attached ? "true" : "false", + priv->modem_online ? "true" : "false", + priv->imsi); + + if (priv->modem_online == FALSE) { + reason = "modem 'Online=false'"; + } else if (priv->imsi == NULL && state != NM_MODEM_STATE_ENABLING) { + reason = "modem not ready"; + } else if (priv->gprs_attached == FALSE) { + new_state = NM_MODEM_STATE_SEARCHING; + reason = "modem searching"; + } else { + new_state = NM_MODEM_STATE_REGISTERED; + reason = "modem ready"; + } + + if (state != new_state) + nm_modem_set_state(NM_MODEM(self), new_state, reason); } /* Disconnect */ typedef struct { - NMModemOfono *self; - _NMModemDisconnectCallback callback; - gpointer callback_user_data; - GCancellable *cancellable; - gboolean warn; + NMModemOfono * self; + _NMModemDisconnectCallback callback; + gpointer callback_user_data; + GCancellable * cancellable; + gboolean warn; } DisconnectContext; static void -disconnect_context_complete (DisconnectContext *ctx, GError *error) +disconnect_context_complete(DisconnectContext *ctx, GError *error) { - if (ctx->callback) - ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data); - nm_g_object_unref (ctx->cancellable); - g_object_unref (ctx->self); - g_slice_free (DisconnectContext, ctx); + if (ctx->callback) + ctx->callback(NM_MODEM(ctx->self), error, ctx->callback_user_data); + nm_g_object_unref(ctx->cancellable); + g_object_unref(ctx->self); + g_slice_free(DisconnectContext, ctx); } static void -disconnect_context_complete_on_idle (gpointer user_data, - GCancellable *cancellable) +disconnect_context_complete_on_idle(gpointer user_data, GCancellable *cancellable) { - DisconnectContext *ctx = user_data; - gs_free_error GError *error = NULL; - - if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) { - g_set_error_literal (&error, - NM_UTILS_ERROR, - NM_UTILS_ERROR_UNKNOWN, - ("modem is currently not connected")); - } - disconnect_context_complete (ctx, error); + DisconnectContext *ctx = user_data; + gs_free_error GError *error = NULL; + + if (!g_cancellable_set_error_if_cancelled(cancellable, &error)) { + g_set_error_literal(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + ("modem is currently not connected")); + } + disconnect_context_complete(ctx, error); } static void -disconnect_done (GObject *source, - GAsyncResult *result, - gpointer user_data) +disconnect_done(GObject *source, GAsyncResult *result, gpointer user_data) { - DisconnectContext *ctx = user_data; - NMModemOfono *self = ctx->self; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *v = NULL; + DisconnectContext *ctx = user_data; + NMModemOfono * self = ctx->self; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *v = NULL; - v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - disconnect_context_complete (ctx, error); - return; - } + v = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, &error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + disconnect_context_complete(ctx, error); + return; + } - if (error && ctx->warn) - _LOGW ("failed to disconnect modem: %s", error->message); + if (error && ctx->warn) + _LOGW("failed to disconnect modem: %s", error->message); - _LOGD ("modem disconnected"); + _LOGD("modem disconnected"); - update_modem_state (self); - disconnect_context_complete (ctx, error); + update_modem_state(self); + disconnect_context_complete(ctx, error); } static void -disconnect (NMModem *modem, - gboolean warn, - GCancellable *cancellable, - _NMModemDisconnectCallback callback, - gpointer user_data) +disconnect(NMModem * modem, + gboolean warn, + GCancellable * cancellable, + _NMModemDisconnectCallback callback, + gpointer user_data) { - NMModemOfono *self = NM_MODEM_OFONO (modem); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - DisconnectContext *ctx; - NMModemState state = nm_modem_get_state (NM_MODEM (self)); - - _LOGD ("warn: %s modem_state: %s", - warn ? "TRUE" : "FALSE", - nm_modem_state_to_string (state)); - - ctx = g_slice_new0 (DisconnectContext); - ctx->self = g_object_ref (self); - ctx->cancellable = nm_g_object_ref (cancellable); - ctx->warn = warn; - ctx->callback = callback; - ctx->callback_user_data = user_data; - - if ( state != NM_MODEM_STATE_CONNECTED - || g_cancellable_is_cancelled (cancellable)) { - nm_utils_invoke_on_idle (cancellable, - disconnect_context_complete_on_idle, - ctx); - return; - } - - nm_modem_set_state (NM_MODEM (self), - NM_MODEM_STATE_DISCONNECTING, - nm_modem_state_to_string (NM_MODEM_STATE_DISCONNECTING)); - - g_dbus_proxy_call (priv->context_proxy, - "SetProperty", - g_variant_new ("(sv)", - "Active", - g_variant_new ("b", warn)), - G_DBUS_CALL_FLAGS_NONE, - 20000, - ctx->cancellable, - disconnect_done, - ctx); + NMModemOfono * self = NM_MODEM_OFONO(modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + DisconnectContext * ctx; + NMModemState state = nm_modem_get_state(NM_MODEM(self)); + + _LOGD("warn: %s modem_state: %s", warn ? "TRUE" : "FALSE", nm_modem_state_to_string(state)); + + ctx = g_slice_new0(DisconnectContext); + ctx->self = g_object_ref(self); + ctx->cancellable = nm_g_object_ref(cancellable); + ctx->warn = warn; + ctx->callback = callback; + ctx->callback_user_data = user_data; + + if (state != NM_MODEM_STATE_CONNECTED || g_cancellable_is_cancelled(cancellable)) { + nm_utils_invoke_on_idle(cancellable, disconnect_context_complete_on_idle, ctx); + return; + } + + nm_modem_set_state(NM_MODEM(self), + NM_MODEM_STATE_DISCONNECTING, + nm_modem_state_to_string(NM_MODEM_STATE_DISCONNECTING)); + + g_dbus_proxy_call(priv->context_proxy, + "SetProperty", + g_variant_new("(sv)", "Active", g_variant_new("b", warn)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + ctx->cancellable, + disconnect_done, + ctx); } static void -deactivate_cleanup (NMModem *modem, - NMDevice *device, - gboolean stop_ppp_manager) +deactivate_cleanup(NMModem *modem, NMDevice *device, gboolean stop_ppp_manager) { - NMModemOfono *self = NM_MODEM_OFONO (modem); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemOfono * self = NM_MODEM_OFONO(modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); - /* TODO: cancel SimpleConnect() if any */ + /* TODO: cancel SimpleConnect() if any */ - g_clear_object (&priv->ip4_config); + g_clear_object(&priv->ip4_config); - NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (modem, - device, - stop_ppp_manager); + NM_MODEM_CLASS(nm_modem_ofono_parent_class) + ->deactivate_cleanup(modem, device, stop_ppp_manager); } static gboolean -check_connection_compatible_with_modem (NMModem *modem, - NMConnection *connection, - GError **error) +check_connection_compatible_with_modem(NMModem *modem, NMConnection *connection, GError **error) { - NMModemOfono *self = NM_MODEM_OFONO (modem); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - const char *id; - - if (!_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, NULL)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "connection type %s is not supported by ofono modem", - nm_connection_get_connection_type (connection)); - return FALSE; - } - - if (!priv->imsi) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem has no IMSI"); - return FALSE; - } - - id = nm_connection_get_id (connection); - - if (!strstr (id, "/context")) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the connection ID has no context"); - return FALSE; - } - - if (!strstr (id, priv->imsi)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the connection ID does not contain the IMSI"); - return FALSE; - } - - return TRUE; + NMModemOfono * self = NM_MODEM_OFONO(modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + const char * id; + + if (!_nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, NULL)) { + nm_utils_error_set(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "connection type %s is not supported by ofono modem", + nm_connection_get_connection_type(connection)); + return FALSE; + } + + if (!priv->imsi) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "modem has no IMSI"); + return FALSE; + } + + id = nm_connection_get_id(connection); + + if (!strstr(id, "/context")) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the connection ID has no context"); + return FALSE; + } + + if (!strstr(id, priv->imsi)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "the connection ID does not contain the IMSI"); + return FALSE; + } + + return TRUE; } static void -handle_sim_property (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - NMModemOfono *self = NM_MODEM_OFONO (user_data); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if (g_strcmp0 (property, "SubscriberIdentity") == 0 && VARIANT_IS_OF_TYPE_STRING (v)) { - gsize length; - const char *value_str = g_variant_get_string (v, &length); - - _LOGD ("SubscriberIdentify found"); - - /* Check for empty DBus string value */ - if (length && - g_strcmp0 (value_str, "(null)") != 0 && - g_strcmp0 (value_str, priv->imsi) != 0) { - - if (priv->imsi != NULL) { - _LOGW ("SimManager:'SubscriberIdentity' changed: %s", priv->imsi); - g_free(priv->imsi); - } - - priv->imsi = g_strdup (value_str); - update_modem_state (self); - } - } + NMModemOfono * self = NM_MODEM_OFONO(user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if (g_strcmp0(property, "SubscriberIdentity") == 0 && VARIANT_IS_OF_TYPE_STRING(v)) { + gsize length; + const char *value_str = g_variant_get_string(v, &length); + + _LOGD("SubscriberIdentify found"); + + /* Check for empty DBus string value */ + if (length && g_strcmp0(value_str, "(null)") != 0 + && g_strcmp0(value_str, priv->imsi) != 0) { + if (priv->imsi != NULL) { + _LOGW("SimManager:'SubscriberIdentity' changed: %s", priv->imsi); + g_free(priv->imsi); + } + + priv->imsi = g_strdup(value_str); + update_modem_state(self); + } + } } static void -sim_property_changed (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value (v, 0); + GVariant *v_child = g_variant_get_child_value(v, 0); - handle_sim_property (proxy, property, v_child, user_data); - g_variant_unref (v_child); + handle_sim_property(proxy, property, v_child, user_data); + g_variant_unref(v_child); } static void -sim_get_properties_done (GObject *source, - GAsyncResult *result, - gpointer user_data) +sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *v_properties = NULL; - gs_unref_variant GVariant *v_dict = NULL; - GVariant *v; - GVariantIter i; - const char *property; - - v_properties = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), - result, - G_VARIANT_TYPE ("(a{sv})"), - &error); - if ( !v_properties - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - g_clear_object (&priv->sim_proxy_cancellable); - - if (!v_properties) { - g_dbus_error_strip_remote_error (error); - _LOGW ("error getting sim properties: %s", error->message); - return; - } - - _LOGD ("sim v_properties is type: %s", g_variant_get_type_string (v_properties)); - - v_dict = g_variant_get_child_value (v_properties, 0); - if (!v_dict) { - _LOGW ("error getting sim properties: no v_dict"); - return; - } - - _LOGD ("sim v_dict is type: %s", g_variant_get_type_string (v_dict)); - - /* - * TODO: - * 1) optimize by looking up properties ( Online, Interfaces ), instead - * of iterating - * - * 2) reduce code duplication between all of the get_properties_done - * functions in this class. - */ - - g_variant_iter_init (&i, v_dict); - while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { - handle_sim_property (NULL, property, v, self); - g_variant_unref (v); - } + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *v_properties = NULL; + gs_unref_variant GVariant *v_dict = NULL; + GVariant * v; + GVariantIter i; + const char * property; + + v_properties = + _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error); + if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + g_clear_object(&priv->sim_proxy_cancellable); + + if (!v_properties) { + g_dbus_error_strip_remote_error(error); + _LOGW("error getting sim properties: %s", error->message); + return; + } + + _LOGD("sim v_properties is type: %s", g_variant_get_type_string(v_properties)); + + v_dict = g_variant_get_child_value(v_properties, 0); + if (!v_dict) { + _LOGW("error getting sim properties: no v_dict"); + return; + } + + _LOGD("sim v_dict is type: %s", g_variant_get_type_string(v_dict)); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init(&i, v_dict); + while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + handle_sim_property(NULL, property, v, self); + g_variant_unref(v); + } } static void -_sim_proxy_new_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +_sim_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - GDBusProxy *proxy; - - proxy = g_dbus_proxy_new_for_bus_finish (result, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = user_data; - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if (!proxy) { - _LOGW ("failed to create SimManager proxy: %s", error->message); - g_clear_object (&priv->sim_proxy_cancellable); - return; - } - - priv->sim_proxy = proxy; - - /* Watch for custom ofono PropertyChanged signals */ - _nm_dbus_signal_connect (priv->sim_proxy, - "PropertyChanged", - G_VARIANT_TYPE ("(sv)"), - G_CALLBACK (sim_property_changed), - self); - - g_dbus_proxy_call (priv->sim_proxy, - "GetProperties", - NULL, - G_DBUS_CALL_FLAGS_NONE, - 20000, - priv->sim_proxy_cancellable, - sim_get_properties_done, - self); + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy * proxy; + + proxy = g_dbus_proxy_new_for_bus_finish(result, &error); + if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = user_data; + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if (!proxy) { + _LOGW("failed to create SimManager proxy: %s", error->message); + g_clear_object(&priv->sim_proxy_cancellable); + return; + } + + priv->sim_proxy = proxy; + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect(priv->sim_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(sim_property_changed), + self); + + g_dbus_proxy_call(priv->sim_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + priv->sim_proxy_cancellable, + sim_get_properties_done, + self); } static void -handle_sim_iface (NMModemOfono *self, gboolean found) +handle_sim_iface(NMModemOfono *self, gboolean found) { - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - _LOGD ("SimManager interface %sfound", found ? "" : "not "); - - if (!found && (priv->sim_proxy || priv->sim_proxy_cancellable)) { - _LOGI ("SimManager interface disappeared"); - nm_clear_g_cancellable (&priv->sim_proxy_cancellable); - if (priv->sim_proxy) { - g_signal_handlers_disconnect_by_data (priv->sim_proxy, self); - g_clear_object (&priv->sim_proxy); - } - nm_clear_g_free (&priv->imsi); - update_modem_state (self); - } else if (found && (!priv->sim_proxy && !priv->sim_proxy_cancellable)) { - _LOGI ("found new SimManager interface"); - - priv->sim_proxy_cancellable = g_cancellable_new (); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, /* GDBusInterfaceInfo */ - OFONO_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (self)), - OFONO_DBUS_INTERFACE_SIM_MANAGER, - priv->sim_proxy_cancellable, /* GCancellable */ - _sim_proxy_new_cb, - self); - } + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + _LOGD("SimManager interface %sfound", found ? "" : "not "); + + if (!found && (priv->sim_proxy || priv->sim_proxy_cancellable)) { + _LOGI("SimManager interface disappeared"); + nm_clear_g_cancellable(&priv->sim_proxy_cancellable); + if (priv->sim_proxy) { + g_signal_handlers_disconnect_by_data(priv->sim_proxy, self); + g_clear_object(&priv->sim_proxy); + } + nm_clear_g_free(&priv->imsi); + update_modem_state(self); + } else if (found && (!priv->sim_proxy && !priv->sim_proxy_cancellable)) { + _LOGI("found new SimManager interface"); + + priv->sim_proxy_cancellable = g_cancellable_new(); + + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path(NM_MODEM(self)), + OFONO_DBUS_INTERFACE_SIM_MANAGER, + priv->sim_proxy_cancellable, /* GCancellable */ + _sim_proxy_new_cb, + self); + } } static void -handle_connman_property (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - NMModemOfono *self = NM_MODEM_OFONO (user_data); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemOfono * self = NM_MODEM_OFONO(user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); - if (g_strcmp0 (property, "Attached") == 0 && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { - gboolean attached = g_variant_get_boolean (v); - gboolean old_attached = priv->gprs_attached; + if (g_strcmp0(property, "Attached") == 0 && VARIANT_IS_OF_TYPE_BOOLEAN(v)) { + gboolean attached = g_variant_get_boolean(v); + gboolean old_attached = priv->gprs_attached; - _LOGD ("Attached: %s", attached ? "True" : "False"); + _LOGD("Attached: %s", attached ? "True" : "False"); - if (priv->gprs_attached != attached) { - priv->gprs_attached = attached; + if (priv->gprs_attached != attached) { + priv->gprs_attached = attached; - _LOGI ("Attached %s -> %s", - old_attached ? "true" : "false", - attached ? "true" : "false"); + _LOGI("Attached %s -> %s", + old_attached ? "true" : "false", + attached ? "true" : "false"); - update_modem_state (self); - } - } + update_modem_state(self); + } + } } static void -connman_property_changed (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value (v, 0); + GVariant *v_child = g_variant_get_child_value(v, 0); - handle_connman_property (proxy, property, v_child, user_data); - g_variant_unref (v_child); + handle_connman_property(proxy, property, v_child, user_data); + g_variant_unref(v_child); } static void -connman_get_properties_done (GObject *source, - GAsyncResult *result, - gpointer user_data) +connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *v_properties = NULL; - gs_unref_variant GVariant *v_dict = NULL; - GVariant *v; - GVariantIter i; - const char *property; - - v_properties = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), - result, - G_VARIANT_TYPE ("(a{sv})"), - &error); - if ( !v_properties - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - g_clear_object (&priv->connman_proxy_cancellable); - - if (!v_properties) { - g_dbus_error_strip_remote_error (error); - _LOGW ("error getting connman properties: %s", error->message); - return; - } - - v_dict = g_variant_get_child_value (v_properties, 0); - - /* - * TODO: - * 1) optimize by looking up properties ( Online, Interfaces ), instead - * of iterating - * - * 2) reduce code duplication between all of the get_properties_done - * functions in this class. - */ - - g_variant_iter_init (&i, v_dict); - while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { - handle_connman_property (NULL, property, v, self); - g_variant_unref (v); - } + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *v_properties = NULL; + gs_unref_variant GVariant *v_dict = NULL; + GVariant * v; + GVariantIter i; + const char * property; + + v_properties = + _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error); + if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + g_clear_object(&priv->connman_proxy_cancellable); + + if (!v_properties) { + g_dbus_error_strip_remote_error(error); + _LOGW("error getting connman properties: %s", error->message); + return; + } + + v_dict = g_variant_get_child_value(v_properties, 0); + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init(&i, v_dict); + while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + handle_connman_property(NULL, property, v, self); + g_variant_unref(v); + } } static void -_connman_proxy_new_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +_connman_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - GDBusProxy *proxy; - - proxy = g_dbus_proxy_new_for_bus_finish (result, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = user_data; - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if (!proxy) { - _LOGW ("failed to create ConnectionManager proxy: %s", error->message); - g_clear_object (&priv->connman_proxy_cancellable); - return; - } - - priv->connman_proxy = proxy; - - _nm_dbus_signal_connect (priv->connman_proxy, - "PropertyChanged", - G_VARIANT_TYPE ("(sv)"), - G_CALLBACK (connman_property_changed), - self); - - g_dbus_proxy_call (priv->connman_proxy, - "GetProperties", - NULL, - G_DBUS_CALL_FLAGS_NONE, - 20000, - priv->connman_proxy_cancellable, - connman_get_properties_done, - self); + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy * proxy; + + proxy = g_dbus_proxy_new_for_bus_finish(result, &error); + if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = user_data; + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if (!proxy) { + _LOGW("failed to create ConnectionManager proxy: %s", error->message); + g_clear_object(&priv->connman_proxy_cancellable); + return; + } + + priv->connman_proxy = proxy; + + _nm_dbus_signal_connect(priv->connman_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(connman_property_changed), + self); + + g_dbus_proxy_call(priv->connman_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + priv->connman_proxy_cancellable, + connman_get_properties_done, + self); } static void -handle_connman_iface (NMModemOfono *self, gboolean found) +handle_connman_iface(NMModemOfono *self, gboolean found) { - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - _LOGD ("ConnectionManager interface %sfound", found ? "" : "not "); - - if (!found && (priv->connman_proxy || priv->connman_proxy_cancellable)) { - _LOGI ("ConnectionManager interface disappeared"); - nm_clear_g_cancellable (&priv->connman_proxy_cancellable); - if (priv->connman_proxy) { - g_signal_handlers_disconnect_by_data (priv->connman_proxy, self); - g_clear_object (&priv->connman_proxy); - } - - /* The connection manager proxy disappeared, we should - * consider the modem disabled. - */ - priv->gprs_attached = FALSE; - - update_modem_state (self); - } else if (found && (!priv->connman_proxy && !priv->connman_proxy_cancellable)) { - _LOGI ("found new ConnectionManager interface"); - - priv->connman_proxy_cancellable = g_cancellable_new (); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, /* GDBusInterfaceInfo */ - OFONO_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (self)), - OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, - priv->connman_proxy_cancellable, - _connman_proxy_new_cb, - self); - } + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + _LOGD("ConnectionManager interface %sfound", found ? "" : "not "); + + if (!found && (priv->connman_proxy || priv->connman_proxy_cancellable)) { + _LOGI("ConnectionManager interface disappeared"); + nm_clear_g_cancellable(&priv->connman_proxy_cancellable); + if (priv->connman_proxy) { + g_signal_handlers_disconnect_by_data(priv->connman_proxy, self); + g_clear_object(&priv->connman_proxy); + } + + /* The connection manager proxy disappeared, we should + * consider the modem disabled. + */ + priv->gprs_attached = FALSE; + + update_modem_state(self); + } else if (found && (!priv->connman_proxy && !priv->connman_proxy_cancellable)) { + _LOGI("found new ConnectionManager interface"); + + priv->connman_proxy_cancellable = g_cancellable_new(); + + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, /* GDBusInterfaceInfo */ + OFONO_DBUS_SERVICE, + nm_modem_get_path(NM_MODEM(self)), + OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, + priv->connman_proxy_cancellable, + _connman_proxy_new_cb, + self); + } } static void -handle_modem_property (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +handle_modem_property(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - NMModemOfono *self = NM_MODEM_OFONO (user_data); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if ((g_strcmp0 (property, "Online") == 0) && VARIANT_IS_OF_TYPE_BOOLEAN (v)) { - gboolean online = g_variant_get_boolean (v); - - _LOGD ("Online: %s", online ? "True" : "False"); - - if (online != priv->modem_online) { - priv->modem_online = online; - _LOGI ("modem is now %s", online ? "Online" : "Offline"); - update_modem_state (self); - } - - } else if ((g_strcmp0 (property, "Interfaces") == 0) && VARIANT_IS_OF_TYPE_STRING_ARRAY (v)) { - const char **array, **iter; - gboolean found_connman = FALSE; - gboolean found_sim = FALSE; - - _LOGD ("Interfaces found"); - - array = g_variant_get_strv (v, NULL); - if (array) { - for (iter = array; *iter; iter++) { - if (g_strcmp0 (OFONO_DBUS_INTERFACE_SIM_MANAGER, *iter) == 0) - found_sim = TRUE; - else if (g_strcmp0 (OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, *iter) == 0) - found_connman = TRUE; - } - g_free (array); - } - - handle_sim_iface (self, found_sim); - handle_connman_iface (self, found_connman); - } + NMModemOfono * self = NM_MODEM_OFONO(user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if ((g_strcmp0(property, "Online") == 0) && VARIANT_IS_OF_TYPE_BOOLEAN(v)) { + gboolean online = g_variant_get_boolean(v); + + _LOGD("Online: %s", online ? "True" : "False"); + + if (online != priv->modem_online) { + priv->modem_online = online; + _LOGI("modem is now %s", online ? "Online" : "Offline"); + update_modem_state(self); + } + + } else if ((g_strcmp0(property, "Interfaces") == 0) && VARIANT_IS_OF_TYPE_STRING_ARRAY(v)) { + const char **array, **iter; + gboolean found_connman = FALSE; + gboolean found_sim = FALSE; + + _LOGD("Interfaces found"); + + array = g_variant_get_strv(v, NULL); + if (array) { + for (iter = array; *iter; iter++) { + if (g_strcmp0(OFONO_DBUS_INTERFACE_SIM_MANAGER, *iter) == 0) + found_sim = TRUE; + else if (g_strcmp0(OFONO_DBUS_INTERFACE_CONNECTION_MANAGER, *iter) == 0) + found_connman = TRUE; + } + g_free(array); + } + + handle_sim_iface(self, found_sim); + handle_connman_iface(self, found_connman); + } } static void -modem_property_changed (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +modem_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value (v, 0); + GVariant *v_child = g_variant_get_child_value(v, 0); - handle_modem_property (proxy, property, v_child, user_data); - g_variant_unref (v_child); + handle_modem_property(proxy, property, v_child, user_data); + g_variant_unref(v_child); } static void -modem_get_properties_done (GObject *source, - GAsyncResult *result, - gpointer user_data) +modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *v_properties = NULL; - gs_unref_variant GVariant *v_dict = NULL; - GVariant *v; - GVariantIter i; - const char *property; - - v_properties = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), - result, - G_VARIANT_TYPE ("(a{sv})"), - &error); - if ( !v_properties - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - g_clear_object (&priv->modem_proxy_cancellable); - - if (!v_properties) { - g_dbus_error_strip_remote_error (error); - _LOGW ("error getting modem properties: %s", error->message); - return; - } - - v_dict = g_variant_get_child_value (v_properties, 0); - if (!v_dict) { - _LOGW ("error getting modem properties: no v_dict"); - return; - } - - /* - * TODO: - * 1) optimize by looking up properties ( Online, Interfaces ), instead - * of iterating - * - * 2) reduce code duplication between all of the get_properties_done - * functions in this class. - */ - - g_variant_iter_init (&i, v_dict); - while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { - handle_modem_property (NULL, property, v, self); - g_variant_unref (v); - } + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *v_properties = NULL; + gs_unref_variant GVariant *v_dict = NULL; + GVariant * v; + GVariantIter i; + const char * property; + + v_properties = + _nm_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, G_VARIANT_TYPE("(a{sv})"), &error); + if (!v_properties && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + g_clear_object(&priv->modem_proxy_cancellable); + + if (!v_properties) { + g_dbus_error_strip_remote_error(error); + _LOGW("error getting modem properties: %s", error->message); + return; + } + + v_dict = g_variant_get_child_value(v_properties, 0); + if (!v_dict) { + _LOGW("error getting modem properties: no v_dict"); + return; + } + + /* + * TODO: + * 1) optimize by looking up properties ( Online, Interfaces ), instead + * of iterating + * + * 2) reduce code duplication between all of the get_properties_done + * functions in this class. + */ + + g_variant_iter_init(&i, v_dict); + while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + handle_modem_property(NULL, property, v, self); + g_variant_unref(v); + } } static void -stage1_prepare_done (GObject *source, - GAsyncResult *result, - gpointer user_data) +stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - gs_unref_variant GVariant *v = NULL; - - v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - g_clear_object (&priv->context_proxy_cancellable); - - nm_clear_pointer (&priv->connect_properties, g_hash_table_destroy); - - if (error) { - _LOGW ("connection failed: %s", error->message); - - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, - NM_DEVICE_STATE_REASON_MODEM_BUSY); - /* - * FIXME: add code to check for InProgress so that the - * connection doesn't continue to try and activate, - * leading to the connection being disabled, and a 5m - * timeout... - */ - } + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *v = NULL; + + v = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), result, &error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + g_clear_object(&priv->context_proxy_cancellable); + + nm_clear_pointer(&priv->connect_properties, g_hash_table_destroy); + + if (error) { + _LOGW("connection failed: %s", error->message); + + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); + /* + * FIXME: add code to check for InProgress so that the + * connection doesn't continue to try and activate, + * leading to the connection being disabled, and a 5m + * timeout... + */ + } } static void -context_property_changed (GDBusProxy *proxy, - const char *property, - GVariant *v, - gpointer user_data) +context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - NMModemOfono *self = NM_MODEM_OFONO (user_data); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - NMPlatformIP4Address addr; - gboolean ret = FALSE; - gs_unref_variant GVariant *v_dict = NULL; - const char *interface; - const char *s; - const char **array, **iter; - guint32 address_network, gateway_network; - guint32 ip4_route_table, ip4_route_metric; - int ifindex; - GError *error = NULL; - - _LOGD ("PropertyChanged: %s", property); - - /* - * TODO: might be a good idea and re-factor this to mimic bluez-device, - * ie. have this function just check the key, and call a sub-func to - * handle the action. - */ - - if (g_strcmp0 (property, "Settings") != 0) - return; - - v_dict = g_variant_get_child_value (v, 0); - if (!v_dict) { - _LOGW ("error getting IPv4 Settings: no v_dict"); - goto out; - } - - _LOGI ("IPv4 static Settings:"); - - if (!g_variant_lookup (v_dict, "Interface", "&s", &interface)) { - _LOGW ("Settings 'Interface' missing"); - goto out; - } - - _LOGD ("Interface: %s", interface); - if (!nm_modem_set_data_port (NM_MODEM (self), - NM_PLATFORM_GET, - interface, - NM_MODEM_IP_METHOD_STATIC, - NM_MODEM_IP_METHOD_UNKNOWN, - 0, - &error)) { - _LOGW ("failed to connect to modem: %s", error->message); - g_clear_error (&error); - goto out; - } - - ifindex = nm_modem_get_ip_ifindex (NM_MODEM (self)); - nm_assert (ifindex > 0); - - /* TODO: verify handling of ip4_config; check other places it's used... */ - g_clear_object (&priv->ip4_config); - - priv->ip4_config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET), - ifindex); - - if (!g_variant_lookup (v_dict, "Address", "&s", &s)) { - _LOGW ("Settings 'Address' missing"); - goto out; - } - if ( !s - || !nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { - _LOGW ("can't convert 'Address' %s to addr", s ?: ""); - goto out; - } - memset (&addr, 0, sizeof (addr)); - addr.ifindex = ifindex; - addr.address = address_network; - addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN; - - if (!g_variant_lookup (v_dict, "Netmask", "&s", &s)) { - _LOGW ("Settings 'Netmask' missing"); - goto out; - } - if ( !s - || !nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { - _LOGW ("invalid 'Netmask': %s", s ?: ""); - goto out; - } - addr.plen = nm_utils_ip4_netmask_to_prefix (address_network); - - _LOGI ("Address: %s", nm_platform_ip4_address_to_string (&addr, NULL, 0)); - nm_ip4_config_add_address (priv->ip4_config, &addr); - - if ( !g_variant_lookup (v_dict, "Gateway", "&s", &s) - || !s) { - _LOGW ("Settings 'Gateway' missing"); - goto out; - } - if (!nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &gateway_network)) { - _LOGW ("invalid 'Gateway': %s", s); - goto out; - } - nm_modem_get_route_parameters (NM_MODEM (self), - &ip4_route_table, - &ip4_route_metric, - NULL, - NULL); - { - const NMPlatformIP4Route r = { - .rt_source = NM_IP_CONFIG_SOURCE_WWAN, - .gateway = gateway_network, - .table_coerced = nm_platform_route_table_coerce (ip4_route_table), - .metric = ip4_route_metric, - }; - - _LOGI ("Gateway: %s", s); - nm_ip4_config_add_route (priv->ip4_config, &r, NULL); - } - - if (!g_variant_lookup (v_dict, "DomainNameServers", "^a&s", &array)) { - _LOGW ("Settings 'DomainNameServers' missing"); - goto out; - } - if (array) { - for (iter = array; *iter; iter++) { - if ( nm_utils_parse_inaddr_bin (AF_INET, *iter, NULL, &address_network) - && address_network) { - _LOGI ("DNS: %s", *iter); - nm_ip4_config_add_nameserver (priv->ip4_config, address_network); - } else { - _LOGW ("invalid NameServer: %s", *iter); - } - } - - if (iter == array) { - _LOGW ("Settings: 'DomainNameServers': none specified"); - g_free (array); - goto out; - } - g_free (array); - } - - if (g_variant_lookup (v_dict, "MessageProxy", "&s", &s)) { - _LOGI ("MessageProxy: %s", s); - if ( s - && nm_utils_parse_inaddr_bin (AF_INET, s, NULL, &address_network)) { - nm_modem_get_route_parameters (NM_MODEM (self), - &ip4_route_table, - &ip4_route_metric, - NULL, - NULL); - - { - const NMPlatformIP4Route mms_route = { - .network = address_network, - .plen = 32, - .gateway = gateway_network, - .table_coerced = nm_platform_route_table_coerce (ip4_route_table), - .metric = ip4_route_metric, - }; - - nm_ip4_config_add_route (priv->ip4_config, &mms_route, NULL); - } - } else { - _LOGW ("invalid MessageProxy: %s", s); - } - } - - ret = TRUE; + NMModemOfono * self = NM_MODEM_OFONO(user_data); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + NMPlatformIP4Address addr; + gboolean ret = FALSE; + gs_unref_variant GVariant *v_dict = NULL; + const char * interface; + const char * s; + const char ** array, **iter; + guint32 address_network, gateway_network; + guint32 ip4_route_table, ip4_route_metric; + int ifindex; + GError * error = NULL; + + _LOGD("PropertyChanged: %s", property); + + /* + * TODO: might be a good idea and re-factor this to mimic bluez-device, + * ie. have this function just check the key, and call a sub-func to + * handle the action. + */ + + if (g_strcmp0(property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value(v, 0); + if (!v_dict) { + _LOGW("error getting IPv4 Settings: no v_dict"); + goto out; + } + + _LOGI("IPv4 static Settings:"); + + if (!g_variant_lookup(v_dict, "Interface", "&s", &interface)) { + _LOGW("Settings 'Interface' missing"); + goto out; + } + + _LOGD("Interface: %s", interface); + if (!nm_modem_set_data_port(NM_MODEM(self), + NM_PLATFORM_GET, + interface, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_UNKNOWN, + 0, + &error)) { + _LOGW("failed to connect to modem: %s", error->message); + g_clear_error(&error); + goto out; + } + + ifindex = nm_modem_get_ip_ifindex(NM_MODEM(self)); + nm_assert(ifindex > 0); + + /* TODO: verify handling of ip4_config; check other places it's used... */ + g_clear_object(&priv->ip4_config); + + priv->ip4_config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex); + + if (!g_variant_lookup(v_dict, "Address", "&s", &s)) { + _LOGW("Settings 'Address' missing"); + goto out; + } + if (!s || !nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) { + _LOGW("can't convert 'Address' %s to addr", s ?: ""); + goto out; + } + memset(&addr, 0, sizeof(addr)); + addr.ifindex = ifindex; + addr.address = address_network; + addr.addr_source = NM_IP_CONFIG_SOURCE_WWAN; + + if (!g_variant_lookup(v_dict, "Netmask", "&s", &s)) { + _LOGW("Settings 'Netmask' missing"); + goto out; + } + if (!s || !nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) { + _LOGW("invalid 'Netmask': %s", s ?: ""); + goto out; + } + addr.plen = nm_utils_ip4_netmask_to_prefix(address_network); + + _LOGI("Address: %s", nm_platform_ip4_address_to_string(&addr, NULL, 0)); + nm_ip4_config_add_address(priv->ip4_config, &addr); + + if (!g_variant_lookup(v_dict, "Gateway", "&s", &s) || !s) { + _LOGW("Settings 'Gateway' missing"); + goto out; + } + if (!nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &gateway_network)) { + _LOGW("invalid 'Gateway': %s", s); + goto out; + } + nm_modem_get_route_parameters(NM_MODEM(self), &ip4_route_table, &ip4_route_metric, NULL, NULL); + { + const NMPlatformIP4Route r = { + .rt_source = NM_IP_CONFIG_SOURCE_WWAN, + .gateway = gateway_network, + .table_coerced = nm_platform_route_table_coerce(ip4_route_table), + .metric = ip4_route_metric, + }; + + _LOGI("Gateway: %s", s); + nm_ip4_config_add_route(priv->ip4_config, &r, NULL); + } + + if (!g_variant_lookup(v_dict, "DomainNameServers", "^a&s", &array)) { + _LOGW("Settings 'DomainNameServers' missing"); + goto out; + } + if (array) { + for (iter = array; *iter; iter++) { + if (nm_utils_parse_inaddr_bin(AF_INET, *iter, NULL, &address_network) + && address_network) { + _LOGI("DNS: %s", *iter); + nm_ip4_config_add_nameserver(priv->ip4_config, address_network); + } else { + _LOGW("invalid NameServer: %s", *iter); + } + } + + if (iter == array) { + _LOGW("Settings: 'DomainNameServers': none specified"); + g_free(array); + goto out; + } + g_free(array); + } + + if (g_variant_lookup(v_dict, "MessageProxy", "&s", &s)) { + _LOGI("MessageProxy: %s", s); + if (s && nm_utils_parse_inaddr_bin(AF_INET, s, NULL, &address_network)) { + nm_modem_get_route_parameters(NM_MODEM(self), + &ip4_route_table, + &ip4_route_metric, + NULL, + NULL); + + { + const NMPlatformIP4Route mms_route = { + .network = address_network, + .plen = 32, + .gateway = gateway_network, + .table_coerced = nm_platform_route_table_coerce(ip4_route_table), + .metric = ip4_route_metric, + }; + + nm_ip4_config_add_route(priv->ip4_config, &mms_route, NULL); + } + } else { + _LOGW("invalid MessageProxy: %s", s); + } + } + + ret = TRUE; out: - if (nm_modem_get_state (NM_MODEM (self)) != NM_MODEM_STATE_CONNECTED) { - _LOGI ("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE"); - nm_modem_emit_prepare_result (NM_MODEM (self), ret, - ret - ? NM_DEVICE_STATE_REASON_NONE - : NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else { - _LOGW ("MODEM_PPP_FAILED"); - nm_modem_emit_ppp_failed (NM_MODEM (self), NM_DEVICE_STATE_REASON_PPP_FAILED); - } + if (nm_modem_get_state(NM_MODEM(self)) != NM_MODEM_STATE_CONNECTED) { + _LOGI("emitting PREPARE_RESULT: %s", ret ? "TRUE" : "FALSE"); + nm_modem_emit_prepare_result(NM_MODEM(self), + ret, + ret ? NM_DEVICE_STATE_REASON_NONE + : NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + } else { + _LOGW("MODEM_PPP_FAILED"); + nm_modem_emit_ppp_failed(NM_MODEM(self), NM_DEVICE_STATE_REASON_PPP_FAILED); + } } static NMActStageReturn -static_stage3_ip4_config_start (NMModem *modem, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason) +static_stage3_ip4_config_start(NMModem * modem, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason) { - NMModemOfono *self = NM_MODEM_OFONO (modem); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - GError *error = NULL; + NMModemOfono * self = NM_MODEM_OFONO(modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + GError * error = NULL; - if (!priv->ip4_config) { - _LOGD ("IP4 config not ready(?)"); - return NM_ACT_STAGE_RETURN_FAILURE; - } + if (!priv->ip4_config) { + _LOGD("IP4 config not ready(?)"); + return NM_ACT_STAGE_RETURN_FAILURE; + } - _LOGD ("IP4 config is done; setting modem_state -> CONNECTED"); - g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error); + _LOGD("IP4 config is done; setting modem_state -> CONNECTED"); + g_signal_emit_by_name(self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error); - /* Signal listener takes ownership of the IP4Config */ - priv->ip4_config = NULL; + /* Signal listener takes ownership of the IP4Config */ + priv->ip4_config = NULL; - nm_modem_set_state (NM_MODEM (self), - NM_MODEM_STATE_CONNECTED, - nm_modem_state_to_string (NM_MODEM_STATE_CONNECTED)); - return NM_ACT_STAGE_RETURN_POSTPONE; + nm_modem_set_state(NM_MODEM(self), + NM_MODEM_STATE_CONNECTED, + nm_modem_state_to_string(NM_MODEM_STATE_CONNECTED)); + return NM_ACT_STAGE_RETURN_POSTPONE; } static void -context_proxy_new_cb (GObject *source, GAsyncResult *result, gpointer user_data) +context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - GDBusProxy *proxy; - - proxy = g_dbus_proxy_new_for_bus_finish (result, &error); - if ( !proxy - || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if (!proxy) { - _LOGE ("failed to create ofono ConnectionContext DBus proxy: %s", error->message); - g_clear_object (&priv->context_proxy_cancellable); - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, - NM_DEVICE_STATE_REASON_MODEM_BUSY); - return; - } - - priv->context_proxy = proxy; - - if (!priv->gprs_attached) { - g_clear_object (&priv->context_proxy_cancellable); - nm_modem_emit_prepare_result (NM_MODEM (self), FALSE, - NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return; - } - - /* We have an old copy of the settings from a previous activation, - * clear it so that we can gate getting the IP config from oFono - * on whether or not we have already received them - */ - g_clear_object (&priv->ip4_config); - - _nm_dbus_signal_connect (priv->context_proxy, - "PropertyChanged", - G_VARIANT_TYPE ("(sv)"), - G_CALLBACK (context_property_changed), - self); - - g_dbus_proxy_call (priv->context_proxy, - "SetProperty", - g_variant_new ("(sv)", - "Active", - g_variant_new ("b", TRUE)), - G_DBUS_CALL_FLAGS_NONE, - 20000, - priv->context_proxy_cancellable, - stage1_prepare_done, - self); + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy * proxy; + + proxy = g_dbus_proxy_new_for_bus_finish(result, &error); + if (!proxy || g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if (!proxy) { + _LOGE("failed to create ofono ConnectionContext DBus proxy: %s", error->message); + g_clear_object(&priv->context_proxy_cancellable); + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); + return; + } + + priv->context_proxy = proxy; + + if (!priv->gprs_attached) { + g_clear_object(&priv->context_proxy_cancellable); + nm_modem_emit_prepare_result(NM_MODEM(self), + FALSE, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return; + } + + /* We have an old copy of the settings from a previous activation, + * clear it so that we can gate getting the IP config from oFono + * on whether or not we have already received them + */ + g_clear_object(&priv->ip4_config); + + _nm_dbus_signal_connect(priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(context_property_changed), + self); + + g_dbus_proxy_call(priv->context_proxy, + "SetProperty", + g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + priv->context_proxy_cancellable, + stage1_prepare_done, + self); } static void -do_context_activate (NMModemOfono *self) +do_context_activate(NMModemOfono *self) { - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); - g_return_if_fail (NM_IS_MODEM_OFONO (self)); + g_return_if_fail(NM_IS_MODEM_OFONO(self)); - nm_clear_g_cancellable (&priv->context_proxy_cancellable); - g_clear_object (&priv->context_proxy); + nm_clear_g_cancellable(&priv->context_proxy_cancellable); + g_clear_object(&priv->context_proxy); - priv->context_proxy_cancellable = g_cancellable_new (); + priv->context_proxy_cancellable = g_cancellable_new(); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - OFONO_DBUS_SERVICE, - priv->context_path, - OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT, - priv->context_proxy_cancellable, - context_proxy_new_cb, - self); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + priv->context_path, + OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT, + priv->context_proxy_cancellable, + context_proxy_new_cb, + self); } static GHashTable * -create_connect_properties (NMConnection *connection) +create_connect_properties(NMConnection *connection) { - NMSettingGsm *setting; - GHashTable *properties; - const char *str; + NMSettingGsm *setting; + GHashTable * properties; + const char * str; - setting = nm_connection_get_setting_gsm (connection); - properties = g_hash_table_new (nm_str_hash, g_str_equal); + setting = nm_connection_get_setting_gsm(connection); + properties = g_hash_table_new(nm_str_hash, g_str_equal); - str = nm_setting_gsm_get_apn (setting); - if (str) - g_hash_table_insert (properties, "AccessPointName", g_strdup (str)); + str = nm_setting_gsm_get_apn(setting); + if (str) + g_hash_table_insert(properties, "AccessPointName", g_strdup(str)); - str = nm_setting_gsm_get_username (setting); - if (str) - g_hash_table_insert (properties, "Username", g_strdup (str)); + str = nm_setting_gsm_get_username(setting); + if (str) + g_hash_table_insert(properties, "Username", g_strdup(str)); - str = nm_setting_gsm_get_password (setting); - if (str) - g_hash_table_insert (properties, "Password", g_strdup (str)); + str = nm_setting_gsm_get_password(setting); + if (str) + g_hash_table_insert(properties, "Password", g_strdup(str)); - return properties; + return properties; } static NMActStageReturn -modem_act_stage1_prepare (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *out_failure_reason) +modem_act_stage1_prepare(NMModem * modem, + NMConnection * connection, + NMDeviceStateReason *out_failure_reason) { - NMModemOfono *self = NM_MODEM_OFONO (modem); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - const char *context_id; - char **id = NULL; + NMModemOfono * self = NM_MODEM_OFONO(modem); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + const char * context_id; + char ** id = NULL; - context_id = nm_connection_get_id (connection); - id = g_strsplit (context_id, "/", 0); - g_return_val_if_fail (id[2], NM_ACT_STAGE_RETURN_FAILURE); + context_id = nm_connection_get_id(connection); + id = g_strsplit(context_id, "/", 0); + g_return_val_if_fail(id[2], NM_ACT_STAGE_RETURN_FAILURE); - _LOGD ("trying %s %s", id[1], id[2]); + _LOGD("trying %s %s", id[1], id[2]); - g_free (priv->context_path); - priv->context_path = g_strdup_printf ("%s/%s", - nm_modem_get_path (modem), - id[2]); - g_strfreev (id); + g_free(priv->context_path); + priv->context_path = g_strdup_printf("%s/%s", nm_modem_get_path(modem), id[2]); + g_strfreev(id); - if (!priv->context_path) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_GSM_APN_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } + if (!priv->context_path) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_GSM_APN_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } - if (priv->connect_properties) - g_hash_table_destroy (priv->connect_properties); + if (priv->connect_properties) + g_hash_table_destroy(priv->connect_properties); - priv->connect_properties = create_connect_properties (connection); + priv->connect_properties = create_connect_properties(connection); - _LOGI ("activating context %s", priv->context_path); + _LOGI("activating context %s", priv->context_path); - if (nm_modem_get_state (modem) == NM_MODEM_STATE_REGISTERED) { - do_context_activate (self); - } else { - _LOGW ("could not activate context: modem is not registered."); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return NM_ACT_STAGE_RETURN_FAILURE; - } + if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) { + do_context_activate(self); + } else { + _LOGW("could not activate context: modem is not registered."); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); + return NM_ACT_STAGE_RETURN_FAILURE; + } - return NM_ACT_STAGE_RETURN_POSTPONE; + return NM_ACT_STAGE_RETURN_POSTPONE; } static void -modem_proxy_new_cb (GObject *source, GAsyncResult *result, gpointer user_data) +modem_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { - NMModemOfono *self; - NMModemOfonoPrivate *priv; - gs_free_error GError *error = NULL; - GDBusProxy *proxy; - - proxy = g_dbus_proxy_new_for_bus_finish (result, &error); - if ( !proxy - && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; - - self = NM_MODEM_OFONO (user_data); - priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - if (!proxy) { - _LOGE ("failed to create ofono modem DBus proxy: %s", error->message); - g_clear_object (&priv->modem_proxy_cancellable); - return; - } - - priv->modem_proxy = proxy; - - _nm_dbus_signal_connect (priv->modem_proxy, - "PropertyChanged", - G_VARIANT_TYPE ("(sv)"), - G_CALLBACK (modem_property_changed), - self); - - g_dbus_proxy_call (priv->modem_proxy, - "GetProperties", - NULL, - G_DBUS_CALL_FLAGS_NONE, - 20000, - priv->modem_proxy_cancellable, - modem_get_properties_done, - self); + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + GDBusProxy * proxy; + + proxy = g_dbus_proxy_new_for_bus_finish(result, &error); + if (!proxy && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + if (!proxy) { + _LOGE("failed to create ofono modem DBus proxy: %s", error->message); + g_clear_object(&priv->modem_proxy_cancellable); + return; + } + + priv->modem_proxy = proxy; + + _nm_dbus_signal_connect(priv->modem_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(modem_property_changed), + self); + + g_dbus_proxy_call(priv->modem_proxy, + "GetProperties", + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + priv->modem_proxy_cancellable, + modem_get_properties_done, + self); } /*****************************************************************************/ static void -nm_modem_ofono_init (NMModemOfono *self) -{ -} +nm_modem_ofono_init(NMModemOfono *self) +{} static void -constructed (GObject *object) +constructed(GObject *object) { - NMModemOfono *self = NM_MODEM_OFONO (object); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); - - priv->modem_proxy_cancellable = g_cancellable_new (); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - OFONO_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (self)), - OFONO_DBUS_INTERFACE_MODEM, - priv->modem_proxy_cancellable, - modem_proxy_new_cb, - self); - - G_OBJECT_CLASS (nm_modem_ofono_parent_class)->constructed (object); + NMModemOfono * self = NM_MODEM_OFONO(object); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + priv->modem_proxy_cancellable = g_cancellable_new(); + + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + OFONO_DBUS_SERVICE, + nm_modem_get_path(NM_MODEM(self)), + OFONO_DBUS_INTERFACE_MODEM, + priv->modem_proxy_cancellable, + modem_proxy_new_cb, + self); + + G_OBJECT_CLASS(nm_modem_ofono_parent_class)->constructed(object); } NMModem * -nm_modem_ofono_new (const char *path) +nm_modem_ofono_new(const char *path) { - gs_free char *basename = NULL; - - g_return_val_if_fail (path != NULL, NULL); - - nm_log_info (LOGD_MB, "ofono: creating new Ofono modem path %s", path); - - /* Use short modem name (not its object path) as the NM device name (which - * comes from NM_MODEM_UID)and the device ID. - */ - basename = g_path_get_basename (path); - - return (NMModem *) g_object_new (NM_TYPE_MODEM_OFONO, - NM_MODEM_PATH, path, - NM_MODEM_UID, basename, - NM_MODEM_DEVICE_ID, basename, - NM_MODEM_CONTROL_PORT, "ofono", /* mandatory */ - NM_MODEM_DRIVER, "ofono", - NM_MODEM_STATE, (int) NM_MODEM_STATE_INITIALIZING, - NULL); + gs_free char *basename = NULL; + + g_return_val_if_fail(path != NULL, NULL); + + nm_log_info(LOGD_MB, "ofono: creating new Ofono modem path %s", path); + + /* Use short modem name (not its object path) as the NM device name (which + * comes from NM_MODEM_UID)and the device ID. + */ + basename = g_path_get_basename(path); + + return (NMModem *) g_object_new(NM_TYPE_MODEM_OFONO, + NM_MODEM_PATH, + path, + NM_MODEM_UID, + basename, + NM_MODEM_DEVICE_ID, + basename, + NM_MODEM_CONTROL_PORT, + "ofono", /* mandatory */ + NM_MODEM_DRIVER, + "ofono", + NM_MODEM_STATE, + (int) NM_MODEM_STATE_INITIALIZING, + NULL); } static void -dispose (GObject *object) +dispose(GObject *object) { - NMModemOfono *self = NM_MODEM_OFONO (object); - NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMModemOfono * self = NM_MODEM_OFONO(object); + NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); - nm_clear_g_cancellable (&priv->modem_proxy_cancellable); - nm_clear_g_cancellable (&priv->connman_proxy_cancellable); - nm_clear_g_cancellable (&priv->context_proxy_cancellable); - nm_clear_g_cancellable (&priv->sim_proxy_cancellable); + nm_clear_g_cancellable(&priv->modem_proxy_cancellable); + nm_clear_g_cancellable(&priv->connman_proxy_cancellable); + nm_clear_g_cancellable(&priv->context_proxy_cancellable); + nm_clear_g_cancellable(&priv->sim_proxy_cancellable); - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } + if (priv->connect_properties) { + g_hash_table_destroy(priv->connect_properties); + priv->connect_properties = NULL; + } - g_clear_object (&priv->ip4_config); + g_clear_object(&priv->ip4_config); - if (priv->modem_proxy) { - g_signal_handlers_disconnect_by_data (priv->modem_proxy, self); - g_clear_object (&priv->modem_proxy); - } + if (priv->modem_proxy) { + g_signal_handlers_disconnect_by_data(priv->modem_proxy, self); + g_clear_object(&priv->modem_proxy); + } - if (priv->connman_proxy) { - g_signal_handlers_disconnect_by_data (priv->connman_proxy, self); - g_clear_object (&priv->connman_proxy); - } + if (priv->connman_proxy) { + g_signal_handlers_disconnect_by_data(priv->connman_proxy, self); + g_clear_object(&priv->connman_proxy); + } - if (priv->context_proxy) { - g_signal_handlers_disconnect_by_data (priv->context_proxy, self); - g_clear_object (&priv->context_proxy); - } + if (priv->context_proxy) { + g_signal_handlers_disconnect_by_data(priv->context_proxy, self); + g_clear_object(&priv->context_proxy); + } - if (priv->sim_proxy) { - g_signal_handlers_disconnect_by_data (priv->sim_proxy, self); - g_clear_object (&priv->sim_proxy); - } + if (priv->sim_proxy) { + g_signal_handlers_disconnect_by_data(priv->sim_proxy, self); + g_clear_object(&priv->sim_proxy); + } - g_free (priv->imsi); - priv->imsi = NULL; + g_free(priv->imsi); + priv->imsi = NULL; - G_OBJECT_CLASS (nm_modem_ofono_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_modem_ofono_parent_class)->dispose(object); } static void -nm_modem_ofono_class_init (NMModemOfonoClass *klass) +nm_modem_ofono_class_init(NMModemOfonoClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMModemClass *modem_class = NM_MODEM_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMModemClass *modem_class = NM_MODEM_CLASS(klass); - object_class->constructed = constructed; - object_class->dispose = dispose; + object_class->constructed = constructed; + object_class->dispose = dispose; - modem_class->get_capabilities = get_capabilities; - modem_class->disconnect = disconnect; - modem_class->deactivate_cleanup = deactivate_cleanup; - modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; + modem_class->get_capabilities = get_capabilities; + modem_class->disconnect = disconnect; + modem_class->deactivate_cleanup = deactivate_cleanup; + modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; - modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare; - modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; + modem_class->modem_act_stage1_prepare = modem_act_stage1_prepare; + modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; } diff --git a/src/devices/wwan/nm-modem-ofono.h b/src/devices/wwan/nm-modem-ofono.h index 4ff2fbdd..10b4a385 100644 --- a/src/devices/wwan/nm-modem-ofono.h +++ b/src/devices/wwan/nm-modem-ofono.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2013 - Canonical Ltd. */ @@ -8,12 +8,14 @@ #include "nm-modem.h" -#define NM_TYPE_MODEM_OFONO (nm_modem_ofono_get_type ()) -#define NM_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OFONO, NMModemOfono)) -#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OFONO)) -#define NM_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) -#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OFONO)) -#define NM_MODEM_OFONO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) +#define NM_TYPE_MODEM_OFONO (nm_modem_ofono_get_type()) +#define NM_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM_OFONO, NMModemOfono)) +#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) +#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM_OFONO)) +#define NM_MODEM_OFONO_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass)) #define OFONO_DBUS_SERVICE "org.ofono" #define OFONO_DBUS_PATH "/" @@ -23,11 +25,11 @@ #define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" #define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" -typedef struct _NMModemOfono NMModemOfono; +typedef struct _NMModemOfono NMModemOfono; typedef struct _NMModemOfonoClass NMModemOfonoClass; -GType nm_modem_ofono_get_type (void); +GType nm_modem_ofono_get_type(void); -NMModem *nm_modem_ofono_new (const char *path); +NMModem *nm_modem_ofono_new(const char *path); #endif /* NM_MODEM_OFONO_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index bedc3844..9e16420e 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2014 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. @@ -26,327 +26,326 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMModem, - PROP_CONTROL_PORT, - PROP_IP_IFINDEX, - PROP_PATH, - PROP_UID, - PROP_DRIVER, - PROP_STATE, - PROP_DEVICE_ID, - PROP_SIM_ID, - PROP_IP_TYPES, - PROP_SIM_OPERATOR_ID, - PROP_OPERATOR_CODE, - PROP_APN, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMModem, + PROP_CONTROL_PORT, + PROP_IP_IFINDEX, + PROP_PATH, + PROP_UID, + PROP_DRIVER, + PROP_STATE, + PROP_DEVICE_ID, + PROP_SIM_ID, + PROP_IP_TYPES, + PROP_SIM_OPERATOR_ID, + PROP_OPERATOR_CODE, + PROP_APN, ); enum { - PPP_STATS, - PPP_FAILED, - PREPARE_RESULT, - IP4_CONFIG_RESULT, - IP6_CONFIG_RESULT, - AUTH_REQUESTED, - AUTH_RESULT, - REMOVED, - STATE_CHANGED, - LAST_SIGNAL, + PPP_STATS, + PPP_FAILED, + PREPARE_RESULT, + IP4_CONFIG_RESULT, + IP6_CONFIG_RESULT, + AUTH_REQUESTED, + AUTH_RESULT, + REMOVED, + STATE_CHANGED, + LAST_SIGNAL, }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = {0}; typedef struct _NMModemPrivate { - char *uid; - char *path; - char *driver; - char *control_port; - char *data_port; - - /* TODO: ip_iface is solely used for nm_modem_owns_port(). - * We should rework the code that it's not necessary */ - char *ip_iface; - - int ip_ifindex; - NMModemIPMethod ip4_method; - NMModemIPMethod ip6_method; - NMUtilsIPv6IfaceId iid; - NMModemState state; - NMModemState prev_state; /* revert to this state if enable/disable fails */ - char *device_id; - char *sim_id; - NMModemIPType ip_types; - char *sim_operator_id; - char *operator_code; - char *apn; - - NMPPPManager *ppp_manager; - - NMActRequest *act_request; - guint32 secrets_tries; - NMActRequestGetSecretsCallId *secrets_id; - - guint mm_ip_timeout; - - guint32 ip4_route_table; - guint32 ip4_route_metric; - guint32 ip6_route_table; - guint32 ip6_route_metric; - - /* PPP stats */ - guint32 in_bytes; - guint32 out_bytes; - - bool claimed:1; + char *uid; + char *path; + char *driver; + char *control_port; + char *data_port; + + /* TODO: ip_iface is solely used for nm_modem_owns_port(). + * We should rework the code that it's not necessary */ + char *ip_iface; + + int ip_ifindex; + NMModemIPMethod ip4_method; + NMModemIPMethod ip6_method; + NMUtilsIPv6IfaceId iid; + NMModemState state; + NMModemState prev_state; /* revert to this state if enable/disable fails */ + char * device_id; + char * sim_id; + NMModemIPType ip_types; + char * sim_operator_id; + char * operator_code; + char * apn; + + NMPPPManager *ppp_manager; + + NMActRequest * act_request; + guint32 secrets_tries; + NMActRequestGetSecretsCallId *secrets_id; + + guint mm_ip_timeout; + + guint32 ip4_route_table; + guint32 ip4_route_metric; + guint32 ip6_route_table; + guint32 ip6_route_metric; + + /* PPP stats */ + guint32 in_bytes; + guint32 out_bytes; + + bool claimed : 1; } NMModemPrivate; -G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMModem, nm_modem, G_TYPE_OBJECT) -#define NM_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMModem, NM_IS_MODEM) +#define NM_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMModem, NM_IS_MODEM) /*****************************************************************************/ -#define _NMLOG_PREFIX_BUFLEN 64 -#define _NMLOG_PREFIX_NAME "modem" -#define _NMLOG_DOMAIN LOGD_MB +#define _NMLOG_PREFIX_BUFLEN 64 +#define _NMLOG_PREFIX_NAME "modem" +#define _NMLOG_DOMAIN LOGD_MB static const char * -_nmlog_prefix (char *prefix, NMModem *self) +_nmlog_prefix(char *prefix, NMModem *self) { - const char *uuid; - int c; + const char *uuid; + int c; - if (!self) - return ""; + if (!self) + return ""; - uuid = nm_modem_get_uid (self); + uuid = nm_modem_get_uid(self); - if (uuid) { - char pp[_NMLOG_PREFIX_BUFLEN - 5]; + if (uuid) { + char pp[_NMLOG_PREFIX_BUFLEN - 5]; - c = g_snprintf (prefix, _NMLOG_PREFIX_BUFLEN, "[%s]", - nm_strquote (pp, sizeof (pp), uuid)); - } else - c = g_snprintf (prefix, _NMLOG_PREFIX_BUFLEN, "[%p]", self); - nm_assert (c < _NMLOG_PREFIX_BUFLEN); + c = g_snprintf(prefix, _NMLOG_PREFIX_BUFLEN, "[%s]", nm_strquote(pp, sizeof(pp), uuid)); + } else + c = g_snprintf(prefix, _NMLOG_PREFIX_BUFLEN, "[%p]", self); + nm_assert(c < _NMLOG_PREFIX_BUFLEN); - return prefix; + return prefix; } -#define _NMLOG(level, ...) \ - G_STMT_START { \ - char _prefix[_NMLOG_PREFIX_BUFLEN]; \ - \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - _nmlog_prefix (_prefix, (self)) \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + char _prefix[_NMLOG_PREFIX_BUFLEN]; \ + \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + _nmlog_prefix(_prefix, (self)) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ -static void _set_ip_ifindex (NMModem *self, int ifindex, const char *ifname); +static void _set_ip_ifindex(NMModem *self, int ifindex, const char *ifname); /*****************************************************************************/ /* State/enabled/connected */ static const char *state_table[] = { - [NM_MODEM_STATE_UNKNOWN] = "unknown", - [NM_MODEM_STATE_FAILED] = "failed", - [NM_MODEM_STATE_INITIALIZING] = "initializing", - [NM_MODEM_STATE_LOCKED] = "locked", - [NM_MODEM_STATE_DISABLED] = "disabled", - [NM_MODEM_STATE_DISABLING] = "disabling", - [NM_MODEM_STATE_ENABLING] = "enabling", - [NM_MODEM_STATE_ENABLED] = "enabled", - [NM_MODEM_STATE_SEARCHING] = "searching", - [NM_MODEM_STATE_REGISTERED] = "registered", - [NM_MODEM_STATE_DISCONNECTING] = "disconnecting", - [NM_MODEM_STATE_CONNECTING] = "connecting", - [NM_MODEM_STATE_CONNECTED] = "connected", + [NM_MODEM_STATE_UNKNOWN] = "unknown", + [NM_MODEM_STATE_FAILED] = "failed", + [NM_MODEM_STATE_INITIALIZING] = "initializing", + [NM_MODEM_STATE_LOCKED] = "locked", + [NM_MODEM_STATE_DISABLED] = "disabled", + [NM_MODEM_STATE_DISABLING] = "disabling", + [NM_MODEM_STATE_ENABLING] = "enabling", + [NM_MODEM_STATE_ENABLED] = "enabled", + [NM_MODEM_STATE_SEARCHING] = "searching", + [NM_MODEM_STATE_REGISTERED] = "registered", + [NM_MODEM_STATE_DISCONNECTING] = "disconnecting", + [NM_MODEM_STATE_CONNECTING] = "connecting", + [NM_MODEM_STATE_CONNECTED] = "connected", }; const char * -nm_modem_state_to_string (NMModemState state) +nm_modem_state_to_string(NMModemState state) { - if ((gsize) state < G_N_ELEMENTS (state_table)) - return state_table[state]; - return NULL; + if ((gsize) state < G_N_ELEMENTS(state_table)) + return state_table[state]; + return NULL; } /*****************************************************************************/ gboolean -nm_modem_is_claimed (NMModem *self) +nm_modem_is_claimed(NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + g_return_val_if_fail(NM_IS_MODEM(self), FALSE); - return NM_MODEM_GET_PRIVATE (self)->claimed; + return NM_MODEM_GET_PRIVATE(self)->claimed; } NMModem * -nm_modem_claim (NMModem *self) +nm_modem_claim(NMModem *self) { - NMModemPrivate *priv; + NMModemPrivate *priv; - g_return_val_if_fail (NM_IS_MODEM (self), NULL); + g_return_val_if_fail(NM_IS_MODEM(self), NULL); - priv = NM_MODEM_GET_PRIVATE (self); + priv = NM_MODEM_GET_PRIVATE(self); - g_return_val_if_fail (!priv->claimed, NULL); + g_return_val_if_fail(!priv->claimed, NULL); - priv->claimed = TRUE; - return g_object_ref (self); + priv->claimed = TRUE; + return g_object_ref(self); } void -nm_modem_unclaim (NMModem *self) +nm_modem_unclaim(NMModem *self) { - NMModemPrivate *priv; + NMModemPrivate *priv; - g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail(NM_IS_MODEM(self)); - priv = NM_MODEM_GET_PRIVATE (self); + priv = NM_MODEM_GET_PRIVATE(self); - g_return_if_fail (priv->claimed); + g_return_if_fail(priv->claimed); - /* we don't actually unclaim the instance. This instance should not be re-used - * by another owner, that is because we only claim modems as we receive them. - * There is no mechanism that somebody else would later re-use them again. - * - * // priv->claimed = FALSE; */ + /* we don't actually unclaim the instance. This instance should not be re-used + * by another owner, that is because we only claim modems as we receive them. + * There is no mechanism that somebody else would later re-use them again. + * + * // priv->claimed = FALSE; */ - g_object_unref (self); + g_object_unref(self); } /*****************************************************************************/ NMModemState -nm_modem_get_state (NMModem *self) +nm_modem_get_state(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->state; + return NM_MODEM_GET_PRIVATE(self)->state; } void -nm_modem_set_state (NMModem *self, - NMModemState new_state, - const char *reason) +nm_modem_set_state(NMModem *self, NMModemState new_state, const char *reason) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMModemState old_state = priv->state; + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + NMModemState old_state = priv->state; - priv->prev_state = NM_MODEM_STATE_UNKNOWN; + priv->prev_state = NM_MODEM_STATE_UNKNOWN; - if (new_state != old_state) { - _LOGI ("modem state changed, '%s' --> '%s' (reason: %s)", - nm_modem_state_to_string (old_state), - nm_modem_state_to_string (new_state), - reason ?: "none"); + if (new_state != old_state) { + _LOGI("modem state changed, '%s' --> '%s' (reason: %s)", + nm_modem_state_to_string(old_state), + nm_modem_state_to_string(new_state), + reason ?: "none"); - priv->state = new_state; - _notify (self, PROP_STATE); - g_signal_emit (self, signals[STATE_CHANGED], 0, (int) new_state, (int) old_state); - } + priv->state = new_state; + _notify(self, PROP_STATE); + g_signal_emit(self, signals[STATE_CHANGED], 0, (int) new_state, (int) old_state); + } } void -nm_modem_set_prev_state (NMModem *self, const char *reason) +nm_modem_set_prev_state(NMModem *self, const char *reason) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - /* Reset modem to previous state if the state hasn't already changed */ - if (priv->prev_state != NM_MODEM_STATE_UNKNOWN) - nm_modem_set_state (self, priv->prev_state, reason); + /* Reset modem to previous state if the state hasn't already changed */ + if (priv->prev_state != NM_MODEM_STATE_UNKNOWN) + nm_modem_set_state(self, priv->prev_state, reason); } void -nm_modem_set_mm_enabled (NMModem *self, - gboolean enabled) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMModemState prev_state = priv->state; - - if (enabled && priv->state >= NM_MODEM_STATE_ENABLING) { - _LOGD ("cannot enable modem: already enabled"); - return; - } - if (!enabled && priv->state <= NM_MODEM_STATE_DISABLING) { - _LOGD ("cannot disable modem: already disabled"); - return; - } - - if (priv->state <= NM_MODEM_STATE_INITIALIZING) { - _LOGD ("cannot enable/disable modem: initializing or failed"); - return; - } else if (priv->state == NM_MODEM_STATE_LOCKED) { - /* Don't try to enable if the modem is locked since that will fail */ - _LOGW ("cannot enable/disable modem: locked"); - - /* Try to unlock the modem if it's being enabled */ - if (enabled) - g_signal_emit (self, signals[AUTH_REQUESTED], 0); - return; - } - - /* Not all modem classes support set_mm_enabled */ - if (NM_MODEM_GET_CLASS (self)->set_mm_enabled) - NM_MODEM_GET_CLASS (self)->set_mm_enabled (self, enabled); - - /* Pre-empt the state change signal */ - nm_modem_set_state (self, - enabled ? NM_MODEM_STATE_ENABLING : NM_MODEM_STATE_DISABLING, - "user preference"); - priv->prev_state = prev_state; +nm_modem_set_mm_enabled(NMModem *self, gboolean enabled) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + NMModemState prev_state = priv->state; + + if (enabled && priv->state >= NM_MODEM_STATE_ENABLING) { + _LOGD("cannot enable modem: already enabled"); + return; + } + if (!enabled && priv->state <= NM_MODEM_STATE_DISABLING) { + _LOGD("cannot disable modem: already disabled"); + return; + } + + if (priv->state <= NM_MODEM_STATE_INITIALIZING) { + _LOGD("cannot enable/disable modem: initializing or failed"); + return; + } else if (priv->state == NM_MODEM_STATE_LOCKED) { + /* Don't try to enable if the modem is locked since that will fail */ + _LOGW("cannot enable/disable modem: locked"); + + /* Try to unlock the modem if it's being enabled */ + if (enabled) + g_signal_emit(self, signals[AUTH_REQUESTED], 0); + return; + } + + /* Not all modem classes support set_mm_enabled */ + if (NM_MODEM_GET_CLASS(self)->set_mm_enabled) + NM_MODEM_GET_CLASS(self)->set_mm_enabled(self, enabled); + + /* Pre-empt the state change signal */ + nm_modem_set_state(self, + enabled ? NM_MODEM_STATE_ENABLING : NM_MODEM_STATE_DISABLING, + "user preference"); + priv->prev_state = prev_state; } void -nm_modem_emit_removed (NMModem *self) +nm_modem_emit_removed(NMModem *self) { - g_signal_emit (self, signals[REMOVED], 0); + g_signal_emit(self, signals[REMOVED], 0); } void -nm_modem_emit_prepare_result (NMModem *self, gboolean success, NMDeviceStateReason reason) +nm_modem_emit_prepare_result(NMModem *self, gboolean success, NMDeviceStateReason reason) { - nm_assert (NM_IS_MODEM (self)); + nm_assert(NM_IS_MODEM(self)); - g_signal_emit (self, signals[PREPARE_RESULT], 0, success, (guint) reason); + g_signal_emit(self, signals[PREPARE_RESULT], 0, success, (guint) reason); } void -nm_modem_emit_ppp_failed (NMModem *self, NMDeviceStateReason reason) +nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason) { - nm_assert (NM_IS_MODEM (self)); + nm_assert(NM_IS_MODEM(self)); - g_signal_emit (self, signals[PPP_FAILED], 0, (guint) reason); + g_signal_emit(self, signals[PPP_FAILED], 0, (guint) reason); } NMModemIPType -nm_modem_get_supported_ip_types (NMModem *self) +nm_modem_get_supported_ip_types(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->ip_types; + return NM_MODEM_GET_PRIVATE(self)->ip_types; } const char * -nm_modem_ip_type_to_string (NMModemIPType ip_type) +nm_modem_ip_type_to_string(NMModemIPType ip_type) { - switch (ip_type) { - case NM_MODEM_IP_TYPE_IPV4: - return "ipv4"; - case NM_MODEM_IP_TYPE_IPV6: - return "ipv6"; - case NM_MODEM_IP_TYPE_IPV4V6: - return "ipv4v6"; - default: - g_return_val_if_reached ("unknown"); - } + switch (ip_type) { + case NM_MODEM_IP_TYPE_IPV4: + return "ipv4"; + case NM_MODEM_IP_TYPE_IPV6: + return "ipv6"; + case NM_MODEM_IP_TYPE_IPV4V6: + return "ipv4v6"; + default: + g_return_val_if_reached("unknown"); + } } static GArray * -build_single_ip_type_array (NMModemIPType type) +build_single_ip_type_array(NMModemIPType type) { - return g_array_append_val (g_array_sized_new (FALSE, FALSE, sizeof (NMModemIPType), 1), type); + return g_array_append_val(g_array_sized_new(FALSE, FALSE, sizeof(NMModemIPType), 1), type); } /** @@ -361,1637 +360,1678 @@ build_single_ip_type_array (NMModemIPType type) * should be tried. */ GArray * -nm_modem_get_connection_ip_type (NMModem *self, - NMConnection *connection, - GError **error) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSettingIPConfig *s_ip4, *s_ip6; - const char *method; - gboolean ip4 = TRUE, ip6 = TRUE; - gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4) { - method = nm_setting_ip_config_get_method (s_ip4); - if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) - ip4 = FALSE; - ip4_may_fail = nm_setting_ip_config_get_may_fail (s_ip4); - } - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6) { - method = nm_setting_ip_config_get_method (s_ip6); - if (NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) - ip6 = FALSE; - ip6_may_fail = nm_setting_ip_config_get_may_fail (s_ip6); - } - - if (ip4 && !ip6) { - if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Connection requested IPv4 but IPv4 is " - "unsupported by the modem."); - return NULL; - } - return build_single_ip_type_array (NM_MODEM_IP_TYPE_IPV4); - } - - if (ip6 && !ip4) { - if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Connection requested IPv6 but IPv6 is " - "unsupported by the modem."); - return NULL; - } - return build_single_ip_type_array (NM_MODEM_IP_TYPE_IPV6); - } - - if (ip4 && ip6) { - NMModemIPType type; - GArray *out; - - out = g_array_sized_new (FALSE, FALSE, sizeof (NMModemIPType), 3); - - /* Modem supports dual-stack? */ - if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) { - type = NM_MODEM_IP_TYPE_IPV4V6; - g_array_append_val (out, type); - } - - /* If IPv6 may-fail=false, we should NOT try IPv4 as fallback */ - if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV4) && ip6_may_fail) { - type = NM_MODEM_IP_TYPE_IPV4; - g_array_append_val (out, type); - } - - /* If IPv4 may-fail=false, we should NOT try IPv6 as fallback */ - if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV6) && ip4_may_fail) { - type = NM_MODEM_IP_TYPE_IPV6; - g_array_append_val (out, type); - } - - if (out->len > 0) - return out; - - /* Error... */ - g_array_unref (out); - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Connection requested both IPv4 and IPv6 " - "but dual-stack addressing is unsupported " - "by the modem."); - return NULL; - } - - g_set_error_literal (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - "Connection specified no IP configuration!"); - return NULL; +nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error) +{ + NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self); + NMSettingIPConfig *s_ip4, *s_ip6; + const char * method; + gboolean ip4 = TRUE, ip6 = TRUE; + gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + if (s_ip4) { + method = nm_setting_ip_config_get_method(s_ip4); + if (g_strcmp0(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + ip4 = FALSE; + ip4_may_fail = nm_setting_ip_config_get_may_fail(s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (s_ip6) { + method = nm_setting_ip_config_get_method(s_ip6); + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) + ip6 = FALSE; + ip6_may_fail = nm_setting_ip_config_get_may_fail(s_ip6); + } + + if (ip4 && !ip6) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv4 but IPv4 is " + "unsupported by the modem."); + return NULL; + } + return build_single_ip_type_array(NM_MODEM_IP_TYPE_IPV4); + } + + if (ip6 && !ip4) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv6 but IPv6 is " + "unsupported by the modem."); + return NULL; + } + return build_single_ip_type_array(NM_MODEM_IP_TYPE_IPV6); + } + + if (ip4 && ip6) { + NMModemIPType type; + GArray * out; + + out = g_array_sized_new(FALSE, FALSE, sizeof(NMModemIPType), 3); + + /* Modem supports dual-stack? */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) { + type = NM_MODEM_IP_TYPE_IPV4V6; + g_array_append_val(out, type); + } + + /* If IPv6 may-fail=false, we should NOT try IPv4 as fallback */ + if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV4) && ip6_may_fail) { + type = NM_MODEM_IP_TYPE_IPV4; + g_array_append_val(out, type); + } + + /* If IPv4 may-fail=false, we should NOT try IPv6 as fallback */ + if ((priv->ip_types & NM_MODEM_IP_TYPE_IPV6) && ip4_may_fail) { + type = NM_MODEM_IP_TYPE_IPV6; + g_array_append_val(out, type); + } + + if (out->len > 0) + return out; + + /* Error... */ + g_array_unref(out); + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested both IPv4 and IPv6 " + "but dual-stack addressing is unsupported " + "by the modem."); + return NULL; + } + + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection specified no IP configuration!"); + return NULL; } const char * -nm_modem_get_device_id (NMModem *self) +nm_modem_get_device_id(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->device_id; + return NM_MODEM_GET_PRIVATE(self)->device_id; } const char * -nm_modem_get_sim_id (NMModem *self) +nm_modem_get_sim_id(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->sim_id; + return NM_MODEM_GET_PRIVATE(self)->sim_id; } const char * -nm_modem_get_sim_operator_id (NMModem *self) +nm_modem_get_sim_operator_id(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->sim_operator_id; + return NM_MODEM_GET_PRIVATE(self)->sim_operator_id; } const char * -nm_modem_get_operator_code (NMModem *self) +nm_modem_get_operator_code(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->operator_code; + return NM_MODEM_GET_PRIVATE(self)->operator_code; } const char * -nm_modem_get_apn (NMModem *self) +nm_modem_get_apn(NMModem *self) { - return NM_MODEM_GET_PRIVATE (self)->apn; + return NM_MODEM_GET_PRIVATE(self)->apn; } /*****************************************************************************/ /* IP method PPP */ static void -ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) +ppp_state_changed(NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) { - switch (status) { - case NM_PPP_STATUS_DISCONNECT: - nm_modem_emit_ppp_failed (user_data, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); - break; - case NM_PPP_STATUS_DEAD: - nm_modem_emit_ppp_failed (user_data, NM_DEVICE_STATE_REASON_PPP_FAILED); - break; - default: - break; - } + switch (status) { + case NM_PPP_STATUS_DISCONNECT: + nm_modem_emit_ppp_failed(user_data, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); + break; + case NM_PPP_STATUS_DEAD: + nm_modem_emit_ppp_failed(user_data, NM_DEVICE_STATE_REASON_PPP_FAILED); + break; + default: + break; + } } static void -ppp_ifindex_set (NMPPPManager *ppp_manager, - int ifindex, - const char *iface, - gpointer user_data) +ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpointer user_data) { - NMModem *self = NM_MODEM (user_data); + NMModem *self = NM_MODEM(user_data); - nm_assert (ifindex >= 0); - nm_assert (NM_MODEM_GET_PRIVATE (self)->ppp_manager == ppp_manager); + nm_assert(ifindex >= 0); + nm_assert(NM_MODEM_GET_PRIVATE(self)->ppp_manager == ppp_manager); - if (ifindex <= 0 && iface) { - /* this might happen, if the ifname was already deleted - * and we failed to resolve ifindex. - * - * Forget about the name. */ - iface = NULL; - } - _set_ip_ifindex (self, ifindex, iface); + if (ifindex <= 0 && iface) { + /* this might happen, if the ifname was already deleted + * and we failed to resolve ifindex. + * + * Forget about the name. */ + iface = NULL; + } + _set_ip_ifindex(self, ifindex, iface); } static void -ppp_ip4_config (NMPPPManager *ppp_manager, - NMIP4Config *config, - gpointer user_data) -{ - NMModem *self = NM_MODEM (user_data); - guint32 i, num; - guint32 bad_dns1 = htonl (0x0A0B0C0D); - guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ - guint32 bad_dns2 = htonl (0x0A0B0C0E); - guint32 good_dns2 = htonl (0x04020202); /* GTE nameserver */ - gboolean dns_workaround = FALSE; - - /* Work around a PPP bug (#1732) which causes many mobile broadband - * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. - * Apparently fixed in ppp-2.4.5 but we've had some reports that this is - * not the case. - * - * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6 - * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e - */ - - num = nm_ip4_config_get_num_nameservers (config); - if (num == 2) { - gboolean found1 = FALSE, found2 = FALSE; - - for (i = 0; i < num; i++) { - guint32 ns = nm_ip4_config_get_nameserver (config, i); - - if (ns == bad_dns1) - found1 = TRUE; - else if (ns == bad_dns2) - found2 = TRUE; - } - - /* Be somewhat conservative about substitutions; the "bad" nameservers - * could actually be valid in some cases, so only substitute if ppp - * returns *only* the two bad nameservers. - */ - dns_workaround = (found1 && found2); - } - - if (!num || dns_workaround) { - _LOGW ("compensating for invalid PPP-provided nameservers"); - nm_ip4_config_reset_nameservers (config); - nm_ip4_config_add_nameserver (config, good_dns1); - nm_ip4_config_add_nameserver (config, good_dns2); - } - - g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, config, NULL); +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) +{ + NMModem *self = NM_MODEM(user_data); + guint32 i, num; + guint32 bad_dns1 = htonl(0x0A0B0C0D); + guint32 good_dns1 = htonl(0x04020201); /* GTE nameserver */ + guint32 bad_dns2 = htonl(0x0A0B0C0E); + guint32 good_dns2 = htonl(0x04020202); /* GTE nameserver */ + gboolean dns_workaround = FALSE; + + /* Work around a PPP bug (#1732) which causes many mobile broadband + * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. + * Apparently fixed in ppp-2.4.5 but we've had some reports that this is + * not the case. + * + * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6 + * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e + */ + + num = nm_ip4_config_get_num_nameservers(config); + if (num == 2) { + gboolean found1 = FALSE, found2 = FALSE; + + for (i = 0; i < num; i++) { + guint32 ns = nm_ip4_config_get_nameserver(config, i); + + if (ns == bad_dns1) + found1 = TRUE; + else if (ns == bad_dns2) + found2 = TRUE; + } + + /* Be somewhat conservative about substitutions; the "bad" nameservers + * could actually be valid in some cases, so only substitute if ppp + * returns *only* the two bad nameservers. + */ + dns_workaround = (found1 && found2); + } + + if (!num || dns_workaround) { + _LOGW("compensating for invalid PPP-provided nameservers"); + nm_ip4_config_reset_nameservers(config); + nm_ip4_config_add_nameserver(config, good_dns1); + nm_ip4_config_add_nameserver(config, good_dns2); + } + + g_signal_emit(self, signals[IP4_CONFIG_RESULT], 0, config, NULL); } static void -ppp_ip6_config (NMPPPManager *ppp_manager, - const NMUtilsIPv6IfaceId *iid, - NMIP6Config *config, - gpointer user_data) +ppp_ip6_config(NMPPPManager * ppp_manager, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config * config, + gpointer user_data) { - NMModem *self = NM_MODEM (user_data); + NMModem *self = NM_MODEM(user_data); - NM_MODEM_GET_PRIVATE (self)->iid = *iid; + NM_MODEM_GET_PRIVATE(self)->iid = *iid; - nm_modem_emit_ip6_config_result (self, config, NULL); + nm_modem_emit_ip6_config_result(self, config, NULL); } static void -ppp_stats (NMPPPManager *ppp_manager, - guint i_in_bytes, - guint i_out_bytes, - gpointer user_data) +ppp_stats(NMPPPManager *ppp_manager, guint i_in_bytes, guint i_out_bytes, gpointer user_data) { - NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - guint32 in_bytes = i_in_bytes; - guint32 out_bytes = i_out_bytes; + NMModem * self = NM_MODEM(user_data); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + guint32 in_bytes = i_in_bytes; + guint32 out_bytes = i_out_bytes; - if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { - priv->in_bytes = in_bytes; - priv->out_bytes = out_bytes; - g_signal_emit (self, signals[PPP_STATS], 0, (guint) in_bytes, (guint) out_bytes); - } + if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { + priv->in_bytes = in_bytes; + priv->out_bytes = out_bytes; + g_signal_emit(self, signals[PPP_STATS], 0, (guint) in_bytes, (guint) out_bytes); + } } static gboolean -port_speed_is_zero (const char *port) +port_speed_is_zero(const char *port) { - struct termios options; - nm_auto_close int fd = -1; - gs_free char *path = NULL; + struct termios options; + nm_auto_close int fd = -1; + gs_free char * path = NULL; - nm_assert (port); + nm_assert(port); - if (port[0] != '/') { - if ( !port[0] - || strchr (port, '/') - || NM_IN_STRSET (port, ".", "..")) - return FALSE; - path = g_build_path ("/sys/class/tty", port, NULL); - port = path; - } + if (port[0] != '/') { + if (!port[0] || strchr(port, '/') || NM_IN_STRSET(port, ".", "..")) + return FALSE; + path = g_build_path("/sys/class/tty", port, NULL); + port = path; + } - fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC); - if (fd < 0) - return FALSE; + fd = open(port, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC); + if (fd < 0) + return FALSE; - memset (&options, 0, sizeof (struct termios)); - if (tcgetattr (fd, &options) != 0) - return FALSE; + memset(&options, 0, sizeof(struct termios)); + if (tcgetattr(fd, &options) != 0) + return FALSE; - return cfgetospeed (&options) == B0; + return cfgetospeed(&options) == B0; } static NMActStageReturn -ppp_stage3_ip_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - const char *ppp_name = NULL; - GError *error = NULL; - guint ip_timeout = 30; - guint baud_override = 0; - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); - - /* If we're already running PPP don't restart it; for example, if both - * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the - * same pppd for both v4 and v6. - */ - if (priv->ppp_manager) - return NM_ACT_STAGE_RETURN_POSTPONE; - - if (NM_MODEM_GET_CLASS (self)->get_user_pass) { - NMConnection *connection = nm_act_request_get_applied_connection (req); - - g_assert (connection); - if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &ppp_name, NULL)) - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (!priv->data_port) { - _LOGE ("error starting PPP (no data port)"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, - * use the default one (30s) */ - if (priv->mm_ip_timeout > 0) { - _LOGI ("using modem-specified IP timeout: %u seconds", - priv->mm_ip_timeout); - ip_timeout = priv->mm_ip_timeout; - } - - /* Some tty drivers and modems ignore port speed, but pppd requires the - * port speed to be > 0 or it exits. If the port speed is 0 pass an - * explicit speed to pppd to prevent the exit. - * https://bugzilla.redhat.com/show_bug.cgi?id=1281731 - */ - if (port_speed_is_zero (priv->data_port)) - baud_override = 57600; - - priv->ppp_manager = nm_ppp_manager_create (priv->data_port, &error); - - if (priv->ppp_manager) { - nm_ppp_manager_set_route_parameters (priv->ppp_manager, - priv->ip4_route_table, - priv->ip4_route_metric, - priv->ip6_route_table, - priv->ip6_route_metric); - } - - if ( !priv->ppp_manager - || !nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, - ip_timeout, baud_override, &error)) { - _LOGE ("error starting PPP: %s", error->message); - g_error_free (error); - g_clear_object (&priv->ppp_manager); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, - G_CALLBACK (ppp_state_changed), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, - G_CALLBACK (ppp_ifindex_set), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, - G_CALLBACK (ppp_ip4_config), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP6_CONFIG, - G_CALLBACK (ppp_ip6_config), - self); - g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATS, - G_CALLBACK (ppp_stats), - self); - - return NM_ACT_STAGE_RETURN_POSTPONE; +ppp_stage3_ip_config_start(NMModem * self, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + const char * ppp_name = NULL; + GError * error = NULL; + guint ip_timeout = 30; + guint baud_override = 0; + + g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail(NM_IS_ACT_REQUEST(req), NM_ACT_STAGE_RETURN_FAILURE); + + /* If we're already running PPP don't restart it; for example, if both + * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the + * same pppd for both v4 and v6. + */ + if (priv->ppp_manager) + return NM_ACT_STAGE_RETURN_POSTPONE; + + if (NM_MODEM_GET_CLASS(self)->get_user_pass) { + NMConnection *connection = nm_act_request_get_applied_connection(req); + + g_assert(connection); + if (!NM_MODEM_GET_CLASS(self)->get_user_pass(self, connection, &ppp_name, NULL)) + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (!priv->data_port) { + _LOGE("error starting PPP (no data port)"); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, + * use the default one (30s) */ + if (priv->mm_ip_timeout > 0) { + _LOGI("using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); + ip_timeout = priv->mm_ip_timeout; + } + + /* Some tty drivers and modems ignore port speed, but pppd requires the + * port speed to be > 0 or it exits. If the port speed is 0 pass an + * explicit speed to pppd to prevent the exit. + * https://bugzilla.redhat.com/show_bug.cgi?id=1281731 + */ + if (port_speed_is_zero(priv->data_port)) + baud_override = 57600; + + priv->ppp_manager = nm_ppp_manager_create(priv->data_port, &error); + + if (priv->ppp_manager) { + nm_ppp_manager_set_route_parameters(priv->ppp_manager, + priv->ip4_route_table, + priv->ip4_route_metric, + priv->ip6_route_table, + priv->ip6_route_metric); + } + + if (!priv->ppp_manager + || !nm_ppp_manager_start(priv->ppp_manager, + req, + ppp_name, + ip_timeout, + baud_override, + &error)) { + _LOGE("error starting PPP: %s", error->message); + g_error_free(error); + g_clear_object(&priv->ppp_manager); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_PPP_START_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_STATE_CHANGED, + G_CALLBACK(ppp_state_changed), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IFINDEX_SET, + G_CALLBACK(ppp_ifindex_set), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IP4_CONFIG, + G_CALLBACK(ppp_ip4_config), + self); + g_signal_connect(priv->ppp_manager, + NM_PPP_MANAGER_SIGNAL_IP6_CONFIG, + G_CALLBACK(ppp_ip6_config), + self); + g_signal_connect(priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_STATS, G_CALLBACK(ppp_stats), self); + + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ NMActStageReturn -nm_modem_stage3_ip4_config_start (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, - NMDeviceStateReason *out_failure_reason) -{ - NMModemPrivate *priv; - NMActRequest *req; - NMConnection *connection; - const char *method; - NMActStageReturn ret; - - _LOGD ("ip4_config_start"); - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_DEVICE (device), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_DEVICE_CLASS (device_class), NM_ACT_STAGE_RETURN_FAILURE); - - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - connection = nm_act_request_get_applied_connection (req); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - nm_modem_set_route_parameters_from_device (self, device); - - method = nm_utils_get_ip_config_method (connection, AF_INET); - - /* Only Disabled and Auto methods make sense for WWAN */ - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) - return NM_ACT_STAGE_RETURN_SUCCESS; - - if (!nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - _LOGE ("unhandled WWAN IPv4 method '%s'; will fail", method); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip4_method) { - case NM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip_config_start (self, req, out_failure_reason); - break; - case NM_MODEM_IP_METHOD_STATIC: - _LOGD ("MODEM_IP_METHOD_STATIC"); - ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, out_failure_reason); - break; - case NM_MODEM_IP_METHOD_AUTO: - _LOGD ("MODEM_IP_METHOD_AUTO"); - ret = device_class->act_stage3_ip_config_start (device, AF_INET, NULL, out_failure_reason); - break; - default: - _LOGI ("IPv4 configuration disabled"); - ret = NM_ACT_STAGE_RETURN_IP_FAIL; - break; - } - - return ret; +nm_modem_stage3_ip4_config_start(NMModem * self, + NMDevice * device, + NMDeviceClass * device_class, + NMDeviceStateReason *out_failure_reason) +{ + NMModemPrivate * priv; + NMActRequest * req; + NMConnection * connection; + const char * method; + NMActStageReturn ret; + + _LOGD("ip4_config_start"); + + g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail(NM_IS_DEVICE(device), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail(NM_IS_DEVICE_CLASS(device_class), NM_ACT_STAGE_RETURN_FAILURE); + + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection(req); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + nm_modem_set_route_parameters_from_device(self, device); + + method = nm_utils_get_ip_config_method(connection, AF_INET); + + /* Only Disabled and Auto methods make sense for WWAN */ + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + return NM_ACT_STAGE_RETURN_SUCCESS; + + if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + _LOGE("unhandled WWAN IPv4 method '%s'; will fail", method); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE(self); + switch (priv->ip4_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start(self, req, out_failure_reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + _LOGD("MODEM_IP_METHOD_STATIC"); + ret = + NM_MODEM_GET_CLASS(self)->static_stage3_ip4_config_start(self, req, out_failure_reason); + break; + case NM_MODEM_IP_METHOD_AUTO: + _LOGD("MODEM_IP_METHOD_AUTO"); + ret = device_class->act_stage3_ip_config_start(device, AF_INET, NULL, out_failure_reason); + break; + default: + _LOGI("IPv4 configuration disabled"); + ret = NM_ACT_STAGE_RETURN_IP_FAIL; + break; + } + + return ret; } void -nm_modem_ip4_pre_commit (NMModem *modem, - NMDevice *device, - NMIP4Config *config) +nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (modem); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(modem); - /* If the modem has an ethernet-type data interface (ie, not PPP and thus - * not point-to-point) and IP config has a /32 prefix, then we assume that - * ARP will be pointless and we turn it off. - */ - if ( priv->ip4_method == NM_MODEM_IP_METHOD_STATIC - || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { - const NMPlatformIP4Address *address = nm_ip4_config_get_first_address (config); + /* If the modem has an ethernet-type data interface (ie, not PPP and thus + * not point-to-point) and IP config has a /32 prefix, then we assume that + * ARP will be pointless and we turn it off. + */ + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { + const NMPlatformIP4Address *address = nm_ip4_config_get_first_address(config); - g_assert (address); - if (address->plen == 32) - nm_platform_link_set_noarp (nm_device_get_platform (device), nm_device_get_ip_ifindex (device)); - } + g_assert(address); + if (address->plen == 32) + nm_platform_link_set_noarp(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device)); + } } /*****************************************************************************/ void -nm_modem_emit_ip6_config_result (NMModem *self, - NMIP6Config *config, - GError *error) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMDedupMultiIter ipconf_iter; - const NMPlatformIP6Address *addr; - gboolean do_slaac = TRUE; - - if (error) { - g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); - return; - } - - if (config) { - /* If the IPv6 configuration only included a Link-Local address, then - * we have to run SLAAC to get the full IPv6 configuration. - */ - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, config, &addr) { - if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { - if (!priv->iid.id) - priv->iid.id = ((guint64 *)(&addr->address.s6_addr))[1]; - } else - do_slaac = FALSE; - } - } - g_assert (config || do_slaac); - - g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); +nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error) +{ + NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self); + NMDedupMultiIter ipconf_iter; + const NMPlatformIP6Address *addr; + gboolean do_slaac = TRUE; + + if (error) { + g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); + return; + } + + if (config) { + /* If the IPv6 configuration only included a Link-Local address, then + * we have to run SLAAC to get the full IPv6 configuration. + */ + nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, config, &addr) { + if (IN6_IS_ADDR_LINKLOCAL(&addr->address)) { + if (!priv->iid.id) + priv->iid.id = ((guint64 *) (&addr->address.s6_addr))[1]; + } else + do_slaac = FALSE; + } + } + g_assert(config || do_slaac); + + g_signal_emit(self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); } static NMActStageReturn -stage3_ip6_config_request (NMModem *self, NMDeviceStateReason *out_failure_reason) +stage3_ip6_config_request(NMModem *self, NMDeviceStateReason *out_failure_reason) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return NM_ACT_STAGE_RETURN_FAILURE; + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return NM_ACT_STAGE_RETURN_FAILURE; } NMActStageReturn -nm_modem_stage3_ip6_config_start (NMModem *self, - NMDevice *device, - NMDeviceStateReason *out_failure_reason) -{ - NMModemPrivate *priv; - NMActRequest *req; - NMActStageReturn ret; - NMConnection *connection; - const char *method; - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - - req = nm_device_get_act_request (device); - g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - - connection = nm_act_request_get_applied_connection (req); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - nm_modem_set_route_parameters_from_device (self, device); - - method = nm_utils_get_ip_config_method (connection, AF_INET6); - - /* Only Ignore, Disabled and Auto methods make sense for WWAN */ - if (NM_IN_STRSET (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) - return NM_ACT_STAGE_RETURN_IP_DONE; - - if (!nm_streq (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - _LOGW ("unhandled WWAN IPv6 method '%s'; will fail", - method); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip6_method) { - case NM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip_config_start (self, req, out_failure_reason); - break; - case NM_MODEM_IP_METHOD_STATIC: - case NM_MODEM_IP_METHOD_AUTO: - /* Both static and DHCP/Auto retrieve a base IP config from the modem - * which in the static case is the full config, and the DHCP/Auto case - * is just the IPv6LL address to use for SLAAC. - */ - ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, out_failure_reason); - break; - default: - _LOGI ("IPv6 configuration disabled"); - ret = NM_ACT_STAGE_RETURN_IP_FAIL; - break; - } - - return ret; +nm_modem_stage3_ip6_config_start(NMModem * self, + NMDevice * device, + NMDeviceStateReason *out_failure_reason) +{ + NMModemPrivate * priv; + NMActRequest * req; + NMActStageReturn ret; + NMConnection * connection; + const char * method; + + g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE); + + req = nm_device_get_act_request(device); + g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection(req); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + nm_modem_set_route_parameters_from_device(self, device); + + method = nm_utils_get_ip_config_method(connection, AF_INET6); + + /* Only Ignore, Disabled and Auto methods make sense for WWAN */ + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) + return NM_ACT_STAGE_RETURN_IP_DONE; + + if (!nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + _LOGW("unhandled WWAN IPv6 method '%s'; will fail", method); + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE(self); + switch (priv->ip6_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start(self, req, out_failure_reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_AUTO: + /* Both static and DHCP/Auto retrieve a base IP config from the modem + * which in the static case is the full config, and the DHCP/Auto case + * is just the IPv6LL address to use for SLAAC. + */ + ret = NM_MODEM_GET_CLASS(self)->stage3_ip6_config_request(self, out_failure_reason); + break; + default: + _LOGI("IPv6 configuration disabled"); + ret = NM_ACT_STAGE_RETURN_IP_FAIL; + break; + } + + return ret; } guint32 -nm_modem_get_configured_mtu (NMDevice *self, - NMDeviceMtuSource *out_source, - gboolean *out_force) -{ - NMConnection *connection; - NMSetting *setting; - gint64 mtu_default; - guint mtu = 0; - const char *property_name; - - nm_assert (NM_IS_DEVICE (self)); - nm_assert (out_source); - - connection = nm_device_get_applied_connection (self); - if (!connection) - g_return_val_if_reached (0); - - setting = (NMSetting *) nm_connection_get_setting_gsm (connection); - if (!setting) - setting = (NMSetting *) nm_connection_get_setting_cdma (connection); - - if (setting) { - g_object_get (setting, "mtu", &mtu, NULL); - if (mtu) { - *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; - return mtu; - } - - property_name = NM_IS_SETTING_GSM (setting) ? "gsm.mtu" : "cdma.mtu"; - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, property_name, G_MAXUINT32); - if (mtu_default >= 0) { - *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; - return (guint32) mtu_default; - } - } - - *out_source = NM_DEVICE_MTU_SOURCE_NONE; - return 0; +nm_modem_get_configured_mtu(NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force) +{ + NMConnection *connection; + NMSetting * setting; + gint64 mtu_default; + guint mtu = 0; + const char * property_name; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(out_source); + + connection = nm_device_get_applied_connection(self); + if (!connection) + g_return_val_if_reached(0); + + setting = (NMSetting *) nm_connection_get_setting_gsm(connection); + if (!setting) + setting = (NMSetting *) nm_connection_get_setting_cdma(connection); + + if (setting) { + g_object_get(setting, "mtu", &mtu, NULL); + if (mtu) { + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; + return mtu; + } + + property_name = NM_IS_SETTING_GSM(setting) ? "gsm.mtu" : "cdma.mtu"; + mtu_default = + nm_device_get_configured_mtu_from_connection_default(self, property_name, G_MAXUINT32); + if (mtu_default >= 0) { + *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; + return (guint32) mtu_default; + } + } + + *out_source = NM_DEVICE_MTU_SOURCE_NONE; + return 0; } /*****************************************************************************/ static void -cancel_get_secrets (NMModem *self) +cancel_get_secrets(NMModem *self) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - if (priv->secrets_id) - nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + if (priv->secrets_id) + nm_act_request_cancel_secrets(priv->act_request, priv->secrets_id); } static void -modem_secrets_cb (NMActRequest *req, - NMActRequestGetSecretsCallId *call_id, - NMSettingsConnection *connection, - GError *error, - gpointer user_data) +modem_secrets_cb(NMActRequest * req, + NMActRequestGetSecretsCallId *call_id, + NMSettingsConnection * connection, + GError * error, + gpointer user_data) { - NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModem * self = NM_MODEM(user_data); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - g_return_if_fail (call_id == priv->secrets_id); + g_return_if_fail(call_id == priv->secrets_id); - priv->secrets_id = NULL; + priv->secrets_id = NULL; - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || - g_error_matches (error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS)) - return; + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED) + || g_error_matches(error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS)) + return; - if (error) - _LOGW ("modem-secrets: %s", error->message); + if (error) + _LOGW("modem-secrets: %s", error->message); - g_signal_emit (self, signals[AUTH_RESULT], 0, error); + g_signal_emit(self, signals[AUTH_RESULT], 0, error); } void -nm_modem_get_secrets (NMModem *self, - const char *setting_name, - gboolean request_new, - const char *hint) +nm_modem_get_secrets(NMModem * self, + const char *setting_name, + gboolean request_new, + const char *hint) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self); + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - cancel_get_secrets (self); + cancel_get_secrets(self); - if (request_new) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - priv->secrets_id = nm_act_request_get_secrets (priv->act_request, - FALSE, - setting_name, - flags, - NM_MAKE_STRV (hint), - modem_secrets_cb, - self); - g_return_if_fail (priv->secrets_id); - g_signal_emit (self, signals[AUTH_REQUESTED], 0); + if (request_new) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + priv->secrets_id = nm_act_request_get_secrets(priv->act_request, + FALSE, + setting_name, + flags, + NM_MAKE_STRV(hint), + modem_secrets_cb, + self); + g_return_if_fail(priv->secrets_id); + g_signal_emit(self, signals[AUTH_REQUESTED], 0); } /*****************************************************************************/ static NMActStageReturn -modem_act_stage1_prepare (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *out_failure_reason) +modem_act_stage1_prepare(NMModem * modem, + NMConnection * connection, + NMDeviceStateReason *out_failure_reason) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_UNKNOWN); - return NM_ACT_STAGE_RETURN_FAILURE; + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_UNKNOWN); + return NM_ACT_STAGE_RETURN_FAILURE; } NMActStageReturn -nm_modem_act_stage1_prepare (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *hints = NULL; - const char *setting_name = NULL; - NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - NMConnection *connection; - - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); - - if (priv->act_request) - g_object_unref (priv->act_request); - priv->act_request = g_object_ref (req); - - connection = nm_act_request_get_applied_connection (req); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - setting_name = nm_connection_need_secrets (connection, &hints); - if (!setting_name) { - nm_assert (!hints); - return NM_MODEM_GET_CLASS (self)->modem_act_stage1_prepare (self, connection, out_failure_reason); - } - - /* Secrets required... */ - if (priv->secrets_tries++) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - if (hints) - g_ptr_array_add (hints, NULL); - - priv->secrets_id = nm_act_request_get_secrets (req, - FALSE, - setting_name, - flags, - hints ? (const char *const*) hints->pdata : NULL, - modem_secrets_cb, - self); - g_return_val_if_fail (priv->secrets_id, NM_ACT_STAGE_RETURN_FAILURE); - g_signal_emit (self, signals[AUTH_REQUESTED], 0); - return NM_ACT_STAGE_RETURN_POSTPONE; +nm_modem_act_stage1_prepare(NMModem * self, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason) +{ + NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self); + gs_unref_ptrarray GPtrArray *hints = NULL; + const char * setting_name = NULL; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMConnection * connection; + + g_return_val_if_fail(NM_IS_ACT_REQUEST(req), NM_ACT_STAGE_RETURN_FAILURE); + + if (priv->act_request) + g_object_unref(priv->act_request); + priv->act_request = g_object_ref(req); + + connection = nm_act_request_get_applied_connection(req); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + + setting_name = nm_connection_need_secrets(connection, &hints); + if (!setting_name) { + nm_assert(!hints); + return NM_MODEM_GET_CLASS(self)->modem_act_stage1_prepare(self, + connection, + out_failure_reason); + } + + /* Secrets required... */ + if (priv->secrets_tries++) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + + if (hints) + g_ptr_array_add(hints, NULL); + + priv->secrets_id = nm_act_request_get_secrets(req, + FALSE, + setting_name, + flags, + hints ? (const char *const *) hints->pdata : NULL, + modem_secrets_cb, + self); + g_return_val_if_fail(priv->secrets_id, NM_ACT_STAGE_RETURN_FAILURE); + g_signal_emit(self, signals[AUTH_REQUESTED], 0); + return NM_ACT_STAGE_RETURN_POSTPONE; } /*****************************************************************************/ void -nm_modem_act_stage2_config (NMModem *self) +nm_modem_act_stage2_config(NMModem *self) { - NMModemPrivate *priv; + NMModemPrivate *priv; - g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail(NM_IS_MODEM(self)); - priv = NM_MODEM_GET_PRIVATE (self); - /* Clear secrets tries counter since secrets were successfully used - * already if we get here. - */ - priv->secrets_tries = 0; + priv = NM_MODEM_GET_PRIVATE(self); + /* Clear secrets tries counter since secrets were successfully used + * already if we get here. + */ + priv->secrets_tries = 0; } /*****************************************************************************/ gboolean -nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection, GError **error) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - - if (nm_streq0 (nm_connection_get_connection_type (connection), - NM_SETTING_GSM_SETTING_NAME)) { - NMSettingGsm *s_gsm; - const char *str; - - s_gsm = _nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, error); - if (!s_gsm) - return FALSE; - - str = nm_setting_gsm_get_device_id (s_gsm); - if (str) { - if (!priv->device_id) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "GSM profile has device-id, device does not"); - return FALSE; - } - if (!nm_streq (str, priv->device_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing device-id than GSM profile"); - return FALSE; - } - } - - /* SIM properties may not be available before the SIM is unlocked, so - * to ensure that autoconnect works, the connection's SIM properties - * are only compared if present on the device. - */ - - if ( priv->sim_id - && (str = nm_setting_gsm_get_sim_id (s_gsm))) { - if (!nm_streq (str, priv->sim_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing sim-id than GSM profile"); - return FALSE; - } - } - - if ( priv->sim_operator_id - && (str = nm_setting_gsm_get_sim_operator_id (s_gsm))) { - if (!nm_streq (str, priv->sim_operator_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing sim-operator-id than GSM profile"); - return FALSE; - } - } - } - - return NM_MODEM_GET_CLASS (self)->check_connection_compatible_with_modem (self, connection, error); +nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GError **error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + + if (nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_GSM_SETTING_NAME)) { + NMSettingGsm *s_gsm; + const char * str; + + s_gsm = _nm_connection_check_main_setting(connection, NM_SETTING_GSM_SETTING_NAME, error); + if (!s_gsm) + return FALSE; + + str = nm_setting_gsm_get_device_id(s_gsm); + if (str) { + if (!priv->device_id) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "GSM profile has device-id, device does not"); + return FALSE; + } + if (!nm_streq(str, priv->device_id)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has differing device-id than GSM profile"); + return FALSE; + } + } + + /* SIM properties may not be available before the SIM is unlocked, so + * to ensure that autoconnect works, the connection's SIM properties + * are only compared if present on the device. + */ + + if (priv->sim_id && (str = nm_setting_gsm_get_sim_id(s_gsm))) { + if (!nm_streq(str, priv->sim_id)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has differing sim-id than GSM profile"); + return FALSE; + } + } + + if (priv->sim_operator_id && (str = nm_setting_gsm_get_sim_operator_id(s_gsm))) { + if (!nm_streq(str, priv->sim_operator_id)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has differing sim-operator-id than GSM profile"); + return FALSE; + } + } + } + + return NM_MODEM_GET_CLASS(self)->check_connection_compatible_with_modem(self, + connection, + error); } /*****************************************************************************/ gboolean -nm_modem_complete_connection (NMModem *self, - const char *iface, - NMConnection *connection, - NMConnection *const*existing_connections, - GError **error) +nm_modem_complete_connection(NMModem * self, + const char * iface, + NMConnection * connection, + NMConnection *const *existing_connections, + GError ** error) { - NMModemClass *klass; + NMModemClass *klass; - klass = NM_MODEM_GET_CLASS (self); - if (!klass->complete_connection) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "Modem class %s had no complete_connection method", - G_OBJECT_TYPE_NAME (self)); - return FALSE; - } + klass = NM_MODEM_GET_CLASS(self); + if (!klass->complete_connection) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "Modem class %s had no complete_connection method", + G_OBJECT_TYPE_NAME(self)); + return FALSE; + } - return klass->complete_connection (self, iface, connection, existing_connections, error); + return klass->complete_connection(self, iface, connection, existing_connections, error); } /*****************************************************************************/ static void -deactivate_cleanup (NMModem *self, - NMDevice *device, - gboolean stop_ppp_manager) +deactivate_cleanup(NMModem *self, NMDevice *device, gboolean stop_ppp_manager) { - NMModemPrivate *priv; - int ifindex; + NMModemPrivate *priv; + int ifindex; - g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail(NM_IS_MODEM(self)); - priv = NM_MODEM_GET_PRIVATE (self); + priv = NM_MODEM_GET_PRIVATE(self); - priv->secrets_tries = 0; + priv->secrets_tries = 0; - if (priv->act_request) { - cancel_get_secrets (self); - g_object_unref (priv->act_request); - priv->act_request = NULL; - } + if (priv->act_request) { + cancel_get_secrets(self); + g_object_unref(priv->act_request); + priv->act_request = NULL; + } - priv->in_bytes = priv->out_bytes = 0; + priv->in_bytes = priv->out_bytes = 0; - if (priv->ppp_manager) { - g_signal_handlers_disconnect_by_data (priv->ppp_manager, self); - if (stop_ppp_manager) - nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL); - g_clear_object (&priv->ppp_manager); - } + if (priv->ppp_manager) { + g_signal_handlers_disconnect_by_data(priv->ppp_manager, self); + if (stop_ppp_manager) + nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); + g_clear_object(&priv->ppp_manager); + } - if (device) { - g_return_if_fail (NM_IS_DEVICE (device)); + if (device) { + g_return_if_fail(NM_IS_DEVICE(device)); - if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || - priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || - priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || - priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { - ifindex = nm_device_get_ip_ifindex (device); - if (ifindex > 0) { - NMPlatform *platform = nm_device_get_platform (device); + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO + || priv->ip6_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { + ifindex = nm_device_get_ip_ifindex(device); + if (ifindex > 0) { + NMPlatform *platform = nm_device_get_platform(device); - nm_platform_ip_route_flush (platform, AF_UNSPEC, ifindex); - nm_platform_ip_address_flush (platform, AF_UNSPEC, ifindex); - nm_platform_link_set_down (platform, ifindex); - } - } - } + nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); + nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); + nm_platform_link_set_down(platform, ifindex); + } + } + } - nm_clear_g_free (&priv->data_port); - priv->mm_ip_timeout = 0; - priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; - priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; - _set_ip_ifindex (self, -1, NULL); + nm_clear_g_free(&priv->data_port); + priv->mm_ip_timeout = 0; + priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; + _set_ip_ifindex(self, -1, NULL); } /*****************************************************************************/ typedef struct { - NMModem *self; - NMDevice *device; - GCancellable *cancellable; - NMModemDeactivateCallback callback; - gpointer callback_user_data; + NMModem * self; + NMDevice * device; + GCancellable * cancellable; + NMModemDeactivateCallback callback; + gpointer callback_user_data; } DeactivateContext; static void -deactivate_context_complete (DeactivateContext *ctx, GError *error) +deactivate_context_complete(DeactivateContext *ctx, GError *error) { - NMModem *self = ctx->self; + NMModem *self = ctx->self; - _LOGD ("modem deactivation finished %s%s%s", - NM_PRINT_FMT_QUOTED (error, "with failure: ", error->message, "", "successfully")); + _LOGD("modem deactivation finished %s%s%s", + NM_PRINT_FMT_QUOTED(error, "with failure: ", error->message, "", "successfully")); - if (ctx->callback) - ctx->callback (ctx->self, error, ctx->callback_user_data); - nm_g_object_unref (ctx->cancellable); - g_object_unref (ctx->device); - g_object_unref (ctx->self); - g_slice_free (DeactivateContext, ctx); + if (ctx->callback) + ctx->callback(ctx->self, error, ctx->callback_user_data); + nm_g_object_unref(ctx->cancellable); + g_object_unref(ctx->device); + g_object_unref(ctx->self); + g_slice_free(DeactivateContext, ctx); } static void -_deactivate_call_disconnect_cb (NMModem *self, - GError *error, - gpointer user_data) +_deactivate_call_disconnect_cb(NMModem *self, GError *error, gpointer user_data) { - deactivate_context_complete (user_data, error); + deactivate_context_complete(user_data, error); } static void -_deactivate_call_disconnect (DeactivateContext *ctx) +_deactivate_call_disconnect(DeactivateContext *ctx) { - NM_MODEM_GET_CLASS (ctx->self)->disconnect (ctx->self, - FALSE, - ctx->cancellable, - _deactivate_call_disconnect_cb, - ctx); + NM_MODEM_GET_CLASS(ctx->self)->disconnect(ctx->self, + FALSE, + ctx->cancellable, + _deactivate_call_disconnect_cb, + ctx); } static void -_deactivate_ppp_manager_stop_cb (NMPPPManager *ppp_manager, - NMPPPManagerStopHandle *handle, - gboolean was_cancelled, - gpointer user_data) +_deactivate_ppp_manager_stop_cb(NMPPPManager * ppp_manager, + NMPPPManagerStopHandle *handle, + gboolean was_cancelled, + gpointer user_data) { - DeactivateContext *ctx = user_data; + DeactivateContext *ctx = user_data; - g_object_unref (ppp_manager); + g_object_unref(ppp_manager); - if (was_cancelled) { - gs_free_error GError *error = NULL; + if (was_cancelled) { + gs_free_error GError *error = NULL; - if (!g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) - nm_assert_not_reached (); - deactivate_context_complete (ctx, error); - return; - } + if (!g_cancellable_set_error_if_cancelled(ctx->cancellable, &error)) + nm_assert_not_reached(); + deactivate_context_complete(ctx, error); + return; + } - nm_assert (!g_cancellable_is_cancelled (ctx->cancellable)); - _deactivate_call_disconnect (ctx); + nm_assert(!g_cancellable_is_cancelled(ctx->cancellable)); + _deactivate_call_disconnect(ctx); } void -nm_modem_deactivate_async (NMModem *self, - NMDevice *device, - GCancellable *cancellable, - NMModemDeactivateCallback callback, - gpointer user_data) +nm_modem_deactivate_async(NMModem * self, + NMDevice * device, + GCancellable * cancellable, + NMModemDeactivateCallback callback, + gpointer user_data) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - DeactivateContext *ctx; - NMPPPManager *ppp_manager; + NMModemPrivate * priv = NM_MODEM_GET_PRIVATE(self); + DeactivateContext *ctx; + NMPPPManager * ppp_manager; - g_return_if_fail (NM_IS_MODEM (self)); - g_return_if_fail (NM_IS_DEVICE (device)); - g_return_if_fail (G_IS_CANCELLABLE (cancellable)); + g_return_if_fail(NM_IS_MODEM(self)); + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(G_IS_CANCELLABLE(cancellable)); - ctx = g_slice_new (DeactivateContext); - ctx->self = g_object_ref (self); - ctx->device = g_object_ref (device); - ctx->cancellable = g_object_ref (cancellable); - ctx->callback = callback; - ctx->callback_user_data = user_data; + ctx = g_slice_new(DeactivateContext); + ctx->self = g_object_ref(self); + ctx->device = g_object_ref(device); + ctx->cancellable = g_object_ref(cancellable); + ctx->callback = callback; + ctx->callback_user_data = user_data; - ppp_manager = nm_g_object_ref (priv->ppp_manager); + ppp_manager = nm_g_object_ref(priv->ppp_manager); - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, ctx->device, FALSE); + NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, ctx->device, FALSE); - if (ppp_manager) { - /* If we have a PPP manager, stop it. - * - * Pass on the reference in @ppp_manager. */ - nm_ppp_manager_stop (ppp_manager, - ctx->cancellable, - _deactivate_ppp_manager_stop_cb, - ctx); - return; - } + if (ppp_manager) { + /* If we have a PPP manager, stop it. + * + * Pass on the reference in @ppp_manager. */ + nm_ppp_manager_stop(ppp_manager, ctx->cancellable, _deactivate_ppp_manager_stop_cb, ctx); + return; + } - _deactivate_call_disconnect (ctx); + _deactivate_call_disconnect(ctx); } /*****************************************************************************/ void -nm_modem_deactivate (NMModem *self, NMDevice *device) +nm_modem_deactivate(NMModem *self, NMDevice *device) { - /* First cleanup */ - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device, TRUE); - /* Then disconnect without waiting */ - NM_MODEM_GET_CLASS (self)->disconnect (self, FALSE, NULL, NULL, NULL); + /* First cleanup */ + NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, device, TRUE); + /* Then disconnect without waiting */ + NM_MODEM_GET_CLASS(self)->disconnect(self, FALSE, NULL, NULL, NULL); } /*****************************************************************************/ void -nm_modem_device_state_changed (NMModem *self, - NMDeviceState new_state, - NMDeviceState old_state) -{ - gboolean was_connected = FALSE, warn = TRUE; - NMModemPrivate *priv; - - g_return_if_fail (NM_IS_MODEM (self)); - - if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_DEACTIVATING) - was_connected = TRUE; - - priv = NM_MODEM_GET_PRIVATE (self); - - /* Make sure we don't leave the serial device open */ - switch (new_state) { - case NM_DEVICE_STATE_UNMANAGED: - case NM_DEVICE_STATE_UNAVAILABLE: - case NM_DEVICE_STATE_FAILED: - case NM_DEVICE_STATE_DISCONNECTED: - if (priv->act_request) { - cancel_get_secrets (self); - g_object_unref (priv->act_request); - priv->act_request = NULL; - } - - if (was_connected) { - /* Don't bother warning on FAILED since the modem is already gone */ - if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED) - warn = FALSE; - /* First cleanup */ - NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL, TRUE); - NM_MODEM_GET_CLASS (self)->disconnect (self, warn, NULL, NULL, NULL); - } - break; - default: - break; - } +nm_modem_device_state_changed(NMModem *self, NMDeviceState new_state, NMDeviceState old_state) +{ + gboolean was_connected = FALSE, warn = TRUE; + NMModemPrivate *priv; + + g_return_if_fail(NM_IS_MODEM(self)); + + if (old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_DEACTIVATING) + was_connected = TRUE; + + priv = NM_MODEM_GET_PRIVATE(self); + + /* Make sure we don't leave the serial device open */ + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_FAILED: + case NM_DEVICE_STATE_DISCONNECTED: + if (priv->act_request) { + cancel_get_secrets(self); + g_object_unref(priv->act_request); + priv->act_request = NULL; + } + + if (was_connected) { + /* Don't bother warning on FAILED since the modem is already gone */ + if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED) + warn = FALSE; + /* First cleanup */ + NM_MODEM_GET_CLASS(self)->deactivate_cleanup(self, NULL, TRUE); + NM_MODEM_GET_CLASS(self)->disconnect(self, warn, NULL, NULL, NULL); + } + break; + default: + break; + } } /*****************************************************************************/ const char * -nm_modem_get_uid (NMModem *self) +nm_modem_get_uid(NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), NULL); + g_return_val_if_fail(NM_IS_MODEM(self), NULL); - return NM_MODEM_GET_PRIVATE (self)->uid; + return NM_MODEM_GET_PRIVATE(self)->uid; } const char * -nm_modem_get_path (NMModem *self) +nm_modem_get_path(NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), NULL); + g_return_val_if_fail(NM_IS_MODEM(self), NULL); - return NM_MODEM_GET_PRIVATE (self)->path; + return NM_MODEM_GET_PRIVATE(self)->path; } const char * -nm_modem_get_driver (NMModem *self) +nm_modem_get_driver(NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), NULL); + g_return_val_if_fail(NM_IS_MODEM(self), NULL); - return NM_MODEM_GET_PRIVATE (self)->driver; + return NM_MODEM_GET_PRIVATE(self)->driver; } const char * -nm_modem_get_control_port (NMModem *self) +nm_modem_get_control_port(NMModem *self) { - g_return_val_if_fail (NM_IS_MODEM (self), NULL); + g_return_val_if_fail(NM_IS_MODEM(self), NULL); - return NM_MODEM_GET_PRIVATE (self)->control_port; + return NM_MODEM_GET_PRIVATE(self)->control_port; } int -nm_modem_get_ip_ifindex (NMModem *self) +nm_modem_get_ip_ifindex(NMModem *self) { - NMModemPrivate *priv; + NMModemPrivate *priv; - g_return_val_if_fail (NM_IS_MODEM (self), 0); + g_return_val_if_fail(NM_IS_MODEM(self), 0); - priv = NM_MODEM_GET_PRIVATE (self); + priv = NM_MODEM_GET_PRIVATE(self); - /* internally we track an unset ip_ifindex as -1. - * For the caller of nm_modem_get_ip_ifindex(), this - * shall be zero too. */ - return priv->ip_ifindex != -1 ? priv->ip_ifindex : 0; + /* internally we track an unset ip_ifindex as -1. + * For the caller of nm_modem_get_ip_ifindex(), this + * shall be zero too. */ + return priv->ip_ifindex != -1 ? priv->ip_ifindex : 0; } static void -_set_ip_ifindex (NMModem *self, int ifindex, const char *ifname) +_set_ip_ifindex(NMModem *self, int ifindex, const char *ifname) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - nm_assert (ifindex >= -1); - nm_assert ((ifindex > 0) == !!ifname); + nm_assert(ifindex >= -1); + nm_assert((ifindex > 0) == !!ifname); - if (!nm_streq0 (priv->ip_iface, ifname)) { - g_free (priv->ip_iface); - priv->ip_iface = g_strdup (ifname); - } + if (!nm_streq0(priv->ip_iface, ifname)) { + g_free(priv->ip_iface); + priv->ip_iface = g_strdup(ifname); + } - if (priv->ip_ifindex != ifindex) { - priv->ip_ifindex = ifindex; - _notify (self, PROP_IP_IFINDEX); - } + if (priv->ip_ifindex != ifindex) { + priv->ip_ifindex = ifindex; + _notify(self, PROP_IP_IFINDEX); + } } gboolean -nm_modem_set_data_port (NMModem *self, - NMPlatform *platform, - const char *data_port, - NMModemIPMethod ip4_method, - NMModemIPMethod ip6_method, - guint timeout, - GError **error) -{ - NMModemPrivate *priv; - gboolean is_ppp; - int ifindex = -1; - - g_return_val_if_fail (NM_IS_MODEM (self), FALSE); - g_return_val_if_fail (NM_IS_PLATFORM (platform), FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - - priv = NM_MODEM_GET_PRIVATE (self); - - if ( priv->ppp_manager - || priv->data_port - || priv->ip_ifindex != -1) { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "cannot set data port in activated state"); - /* this really shouldn't happen. Assert. */ - g_return_val_if_reached (FALSE); - } - - if (!data_port) { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "missing data port"); - return FALSE; - } - - is_ppp = (ip4_method == NM_MODEM_IP_METHOD_PPP) - || (ip6_method == NM_MODEM_IP_METHOD_PPP); - if (is_ppp) { - if ( !NM_IN_SET (ip4_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP) - || !NM_IN_SET (ip6_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP)) { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "conflicting ip methods"); - return FALSE; - } - } else if ( !NM_IN_SET (ip4_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_STATIC, NM_MODEM_IP_METHOD_AUTO) - || !NM_IN_SET (ip6_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_STATIC, NM_MODEM_IP_METHOD_AUTO) - || ( ip4_method == NM_MODEM_IP_METHOD_UNKNOWN - && ip6_method == NM_MODEM_IP_METHOD_UNKNOWN)) { - g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "invalid ip methods"); - return FALSE; - } - - if (!is_ppp) { - ifindex = nm_platform_if_nametoindex (platform, data_port); - if (ifindex <= 0) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "cannot find network interface %s", data_port); - return FALSE; - } - if (!nm_platform_process_events_ensure_link (platform, ifindex, data_port)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "cannot find network interface %s in platform cache", data_port); - return FALSE; - } - } - - priv->mm_ip_timeout = timeout; - priv->ip4_method = ip4_method; - priv->ip6_method = ip6_method; - if (is_ppp) { - priv->data_port = g_strdup (data_port); - _set_ip_ifindex (self, -1, NULL); - } else { - priv->data_port = NULL; - _set_ip_ifindex (self, ifindex, data_port); - } - return TRUE; +nm_modem_set_data_port(NMModem * self, + NMPlatform * platform, + const char * data_port, + NMModemIPMethod ip4_method, + NMModemIPMethod ip6_method, + guint timeout, + GError ** error) +{ + NMModemPrivate *priv; + gboolean is_ppp; + int ifindex = -1; + + g_return_val_if_fail(NM_IS_MODEM(self), FALSE); + g_return_val_if_fail(NM_IS_PLATFORM(platform), FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + + priv = NM_MODEM_GET_PRIVATE(self); + + if (priv->ppp_manager || priv->data_port || priv->ip_ifindex != -1) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "cannot set data port in activated state"); + /* this really shouldn't happen. Assert. */ + g_return_val_if_reached(FALSE); + } + + if (!data_port) { + g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "missing data port"); + return FALSE; + } + + is_ppp = (ip4_method == NM_MODEM_IP_METHOD_PPP) || (ip6_method == NM_MODEM_IP_METHOD_PPP); + if (is_ppp) { + if (!NM_IN_SET(ip4_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP) + || !NM_IN_SET(ip6_method, NM_MODEM_IP_METHOD_UNKNOWN, NM_MODEM_IP_METHOD_PPP)) { + g_set_error_literal(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "conflicting ip methods"); + return FALSE; + } + } else if (!NM_IN_SET(ip4_method, + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO) + || !NM_IN_SET(ip6_method, + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO) + || (ip4_method == NM_MODEM_IP_METHOD_UNKNOWN + && ip6_method == NM_MODEM_IP_METHOD_UNKNOWN)) { + g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "invalid ip methods"); + return FALSE; + } + + if (!is_ppp) { + ifindex = nm_platform_if_nametoindex(platform, data_port); + if (ifindex <= 0) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "cannot find network interface %s", + data_port); + return FALSE; + } + if (!nm_platform_process_events_ensure_link(platform, ifindex, data_port)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "cannot find network interface %s in platform cache", + data_port); + return FALSE; + } + } + + priv->mm_ip_timeout = timeout; + priv->ip4_method = ip4_method; + priv->ip6_method = ip6_method; + if (is_ppp) { + priv->data_port = g_strdup(data_port); + _set_ip_ifindex(self, -1, NULL); + } else { + priv->data_port = NULL; + _set_ip_ifindex(self, ifindex, data_port); + } + return TRUE; } gboolean -nm_modem_owns_port (NMModem *self, const char *iface) +nm_modem_owns_port(NMModem *self, const char *iface) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail(iface != NULL, FALSE); - if (NM_MODEM_GET_CLASS (self)->owns_port) - return NM_MODEM_GET_CLASS (self)->owns_port (self, iface); + if (NM_MODEM_GET_CLASS(self)->owns_port) + return NM_MODEM_GET_CLASS(self)->owns_port(self, iface); - return NM_IN_STRSET (iface, - priv->ip_iface, - priv->data_port, - priv->control_port); + return NM_IN_STRSET(iface, priv->ip_iface, priv->data_port, priv->control_port); } gboolean -nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid) +nm_modem_get_iid(NMModem *self, NMUtilsIPv6IfaceId *out_iid) { - g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + g_return_val_if_fail(NM_IS_MODEM(self), FALSE); - *out_iid = NM_MODEM_GET_PRIVATE (self)->iid; - return TRUE; + *out_iid = NM_MODEM_GET_PRIVATE(self)->iid; + return TRUE; } /*****************************************************************************/ void -nm_modem_get_route_parameters (NMModem *self, - guint32 *out_ip4_route_table, - guint32 *out_ip4_route_metric, - guint32 *out_ip6_route_table, - guint32 *out_ip6_route_metric) +nm_modem_get_route_parameters(NMModem *self, + guint32 *out_ip4_route_table, + guint32 *out_ip4_route_metric, + guint32 *out_ip6_route_table, + guint32 *out_ip6_route_metric) { - NMModemPrivate *priv; + NMModemPrivate *priv; - g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail(NM_IS_MODEM(self)); - priv = NM_MODEM_GET_PRIVATE (self); - NM_SET_OUT (out_ip4_route_table, priv->ip4_route_table); - NM_SET_OUT (out_ip4_route_metric, priv->ip4_route_metric); - NM_SET_OUT (out_ip6_route_table, priv->ip6_route_table); - NM_SET_OUT (out_ip6_route_metric, priv->ip6_route_metric); + priv = NM_MODEM_GET_PRIVATE(self); + NM_SET_OUT(out_ip4_route_table, priv->ip4_route_table); + NM_SET_OUT(out_ip4_route_metric, priv->ip4_route_metric); + NM_SET_OUT(out_ip6_route_table, priv->ip6_route_table); + NM_SET_OUT(out_ip6_route_metric, priv->ip6_route_metric); } void -nm_modem_set_route_parameters (NMModem *self, - guint32 ip4_route_table, - guint32 ip4_route_metric, - guint32 ip6_route_table, - guint32 ip6_route_metric) -{ - NMModemPrivate *priv; - - g_return_if_fail (NM_IS_MODEM (self)); - - priv = NM_MODEM_GET_PRIVATE (self); - if ( priv->ip4_route_table != ip4_route_table - || priv->ip4_route_metric != ip4_route_metric - || priv->ip6_route_table != ip6_route_table - || priv->ip6_route_metric != ip6_route_metric) { - priv->ip4_route_table = ip4_route_table; - priv->ip4_route_metric = ip4_route_metric; - priv->ip6_route_table = ip6_route_table; - priv->ip6_route_metric = ip6_route_metric; - - _LOGT ("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u", - priv->ip4_route_table, - priv->ip4_route_metric, - priv->ip6_route_table, - priv->ip6_route_metric); - } - - if (priv->ppp_manager) { - nm_ppp_manager_set_route_parameters (priv->ppp_manager, - priv->ip4_route_table, - priv->ip4_route_metric, - priv->ip6_route_table, - priv->ip6_route_metric); - } +nm_modem_set_route_parameters(NMModem *self, + guint32 ip4_route_table, + guint32 ip4_route_metric, + guint32 ip6_route_table, + guint32 ip6_route_metric) +{ + NMModemPrivate *priv; + + g_return_if_fail(NM_IS_MODEM(self)); + + priv = NM_MODEM_GET_PRIVATE(self); + if (priv->ip4_route_table != ip4_route_table || priv->ip4_route_metric != ip4_route_metric + || priv->ip6_route_table != ip6_route_table || priv->ip6_route_metric != ip6_route_metric) { + priv->ip4_route_table = ip4_route_table; + priv->ip4_route_metric = ip4_route_metric; + priv->ip6_route_table = ip6_route_table; + priv->ip6_route_metric = ip6_route_metric; + + _LOGT("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u", + priv->ip4_route_table, + priv->ip4_route_metric, + priv->ip6_route_table, + priv->ip6_route_metric); + } + + if (priv->ppp_manager) { + nm_ppp_manager_set_route_parameters(priv->ppp_manager, + priv->ip4_route_table, + priv->ip4_route_metric, + priv->ip6_route_table, + priv->ip6_route_metric); + } } void -nm_modem_set_route_parameters_from_device (NMModem *self, - NMDevice *device) +nm_modem_set_route_parameters_from_device(NMModem *self, NMDevice *device) { - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail(NM_IS_DEVICE(device)); - nm_modem_set_route_parameters (self, - nm_device_get_route_table (device, AF_INET), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_table (device, AF_INET6), - nm_device_get_route_metric (device, AF_INET6)); + nm_modem_set_route_parameters(self, + nm_device_get_route_table(device, AF_INET), + nm_device_get_route_metric(device, AF_INET), + nm_device_get_route_table(device, AF_INET6), + nm_device_get_route_metric(device, AF_INET6)); } /*****************************************************************************/ void -nm_modem_get_capabilities (NMModem *self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) +nm_modem_get_capabilities(NMModem * self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps) { - g_return_if_fail (NM_IS_MODEM (self)); + g_return_if_fail(NM_IS_MODEM(self)); - NM_MODEM_GET_CLASS (self)->get_capabilities (self, modem_caps, current_caps); + NM_MODEM_GET_CLASS(self)->get_capabilities(self, modem_caps, current_caps); } /*****************************************************************************/ void -_nm_modem_set_operator_code (NMModem *self, const char *operator_code) +_nm_modem_set_operator_code(NMModem *self, const char *operator_code) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - if (g_strcmp0 (priv->operator_code, operator_code) != 0) { - g_free (priv->operator_code); - priv->operator_code = g_strdup (operator_code); - _notify (self, PROP_OPERATOR_CODE); - } + if (g_strcmp0(priv->operator_code, operator_code) != 0) { + g_free(priv->operator_code); + priv->operator_code = g_strdup(operator_code); + _notify(self, PROP_OPERATOR_CODE); + } } void -_nm_modem_set_apn (NMModem *self, const char *apn) +_nm_modem_set_apn(NMModem *self, const char *apn) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); - if (g_strcmp0 (priv->apn, apn) != 0) { - g_free (priv->apn); - priv->apn = g_strdup (apn); - _notify (self, PROP_APN); - } + if (g_strcmp0(priv->apn, apn) != 0) { + g_free(priv->apn); + priv->apn = g_strdup(apn); + _notify(self, PROP_APN); + } } static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMModem *self = NM_MODEM (object); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_PATH: - g_value_set_string (value, priv->path); - break; - case PROP_DRIVER: - g_value_set_string (value, priv->driver); - break; - case PROP_CONTROL_PORT: - g_value_set_string (value, priv->control_port); - break; - case PROP_IP_IFINDEX: - g_value_set_int (value, nm_modem_get_ip_ifindex (self)); - break; - case PROP_UID: - g_value_set_string (value, priv->uid); - break; - case PROP_STATE: - g_value_set_int (value, priv->state); - break; - case PROP_DEVICE_ID: - g_value_set_string (value, priv->device_id); - break; - case PROP_SIM_ID: - g_value_set_string (value, priv->sim_id); - break; - case PROP_IP_TYPES: - g_value_set_uint (value, priv->ip_types); - break; - case PROP_SIM_OPERATOR_ID: - g_value_set_string (value, priv->sim_operator_id); - break; - case PROP_OPERATOR_CODE: - g_value_set_string (value, priv->operator_code); - break; - case PROP_APN: - g_value_set_string (value, priv->apn); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMModem * self = NM_MODEM(object); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string(value, priv->path); + break; + case PROP_DRIVER: + g_value_set_string(value, priv->driver); + break; + case PROP_CONTROL_PORT: + g_value_set_string(value, priv->control_port); + break; + case PROP_IP_IFINDEX: + g_value_set_int(value, nm_modem_get_ip_ifindex(self)); + break; + case PROP_UID: + g_value_set_string(value, priv->uid); + break; + case PROP_STATE: + g_value_set_int(value, priv->state); + break; + case PROP_DEVICE_ID: + g_value_set_string(value, priv->device_id); + break; + case PROP_SIM_ID: + g_value_set_string(value, priv->sim_id); + break; + case PROP_IP_TYPES: + g_value_set_uint(value, priv->ip_types); + break; + case PROP_SIM_OPERATOR_ID: + g_value_set_string(value, priv->sim_operator_id); + break; + case PROP_OPERATOR_CODE: + g_value_set_string(value, priv->operator_code); + break; + case PROP_APN: + g_value_set_string(value, priv->apn); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); - const char *s; - - switch (prop_id) { - case PROP_PATH: - /* construct-only */ - priv->path = g_value_dup_string (value); - g_return_if_fail (priv->path); - break; - case PROP_DRIVER: - /* construct-only */ - priv->driver = g_value_dup_string (value); - break; - case PROP_CONTROL_PORT: - /* construct-only */ - priv->control_port = g_value_dup_string (value); - break; - case PROP_UID: - /* construct-only */ - priv->uid = g_value_dup_string (value); - break; - case PROP_STATE: - /* construct-only */ - priv->state = g_value_get_int (value); - break; - case PROP_DEVICE_ID: - /* construct-only */ - priv->device_id = g_value_dup_string (value); - break; - case PROP_SIM_ID: - g_free (priv->sim_id); - priv->sim_id = g_value_dup_string (value); - break; - case PROP_IP_TYPES: - priv->ip_types = g_value_get_uint (value); - break; - case PROP_SIM_OPERATOR_ID: - nm_clear_g_free (&priv->sim_operator_id); - s = g_value_get_string (value); - if (s && s[0]) - priv->sim_operator_id = g_strdup (s); - break; - case PROP_OPERATOR_CODE: - /* construct-only */ - priv->operator_code = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object); + const char * s; + + switch (prop_id) { + case PROP_PATH: + /* construct-only */ + priv->path = g_value_dup_string(value); + g_return_if_fail(priv->path); + break; + case PROP_DRIVER: + /* construct-only */ + priv->driver = g_value_dup_string(value); + break; + case PROP_CONTROL_PORT: + /* construct-only */ + priv->control_port = g_value_dup_string(value); + break; + case PROP_UID: + /* construct-only */ + priv->uid = g_value_dup_string(value); + break; + case PROP_STATE: + /* construct-only */ + priv->state = g_value_get_int(value); + break; + case PROP_DEVICE_ID: + /* construct-only */ + priv->device_id = g_value_dup_string(value); + break; + case PROP_SIM_ID: + g_free(priv->sim_id); + priv->sim_id = g_value_dup_string(value); + break; + case PROP_IP_TYPES: + priv->ip_types = g_value_get_uint(value); + break; + case PROP_SIM_OPERATOR_ID: + nm_clear_g_free(&priv->sim_operator_id); + s = g_value_get_string(value); + if (s && s[0]) + priv->sim_operator_id = g_strdup(s); + break; + case PROP_OPERATOR_CODE: + /* construct-only */ + priv->operator_code = g_value_dup_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_modem_init (NMModem *self) +nm_modem_init(NMModem *self) { - NMModemPrivate *priv; + NMModemPrivate *priv; - self->_priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_MODEM, NMModemPrivate); - priv = self->_priv; + self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_MODEM, NMModemPrivate); + priv = self->_priv; - priv->ip_ifindex = -1; - priv->ip4_route_table = RT_TABLE_MAIN; - priv->ip4_route_metric = 700; - priv->ip6_route_table = RT_TABLE_MAIN; - priv->ip6_route_metric = 700; + priv->ip_ifindex = -1; + priv->ip4_route_table = RT_TABLE_MAIN; + priv->ip4_route_metric = 700; + priv->ip6_route_table = RT_TABLE_MAIN; + priv->ip6_route_metric = 700; } static void -constructed (GObject *object) +constructed(GObject *object) { - NMModemPrivate *priv; + NMModemPrivate *priv; - G_OBJECT_CLASS (nm_modem_parent_class)->constructed (object); + G_OBJECT_CLASS(nm_modem_parent_class)->constructed(object); - priv = NM_MODEM_GET_PRIVATE (NM_MODEM (object)); + priv = NM_MODEM_GET_PRIVATE(NM_MODEM(object)); - g_return_if_fail (priv->control_port); + g_return_if_fail(priv->control_port); } /*****************************************************************************/ static void -dispose (GObject *object) +dispose(GObject *object) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object); - g_clear_object (&priv->act_request); + g_clear_object(&priv->act_request); - G_OBJECT_CLASS (nm_modem_parent_class)->dispose (object); + G_OBJECT_CLASS(nm_modem_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE(object); - g_free (priv->uid); - g_free (priv->path); - g_free (priv->driver); - g_free (priv->control_port); - g_free (priv->data_port); - g_free (priv->ip_iface); - g_free (priv->device_id); - g_free (priv->sim_id); - g_free (priv->sim_operator_id); - g_free (priv->operator_code); - g_free (priv->apn); + g_free(priv->uid); + g_free(priv->path); + g_free(priv->driver); + g_free(priv->control_port); + g_free(priv->data_port); + g_free(priv->ip_iface); + g_free(priv->device_id); + g_free(priv->sim_id); + g_free(priv->sim_operator_id); + g_free(priv->operator_code); + g_free(priv->apn); - G_OBJECT_CLASS (nm_modem_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_modem_parent_class)->finalize(object); } static void -nm_modem_class_init (NMModemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMModemPrivate)); - - object_class->constructed = constructed; - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - klass->modem_act_stage1_prepare = modem_act_stage1_prepare; - klass->stage3_ip6_config_request = stage3_ip6_config_request; - klass->deactivate_cleanup = deactivate_cleanup; - - obj_properties[PROP_UID] = - g_param_spec_string (NM_MODEM_UID, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_PATH] = - g_param_spec_string (NM_MODEM_PATH, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_DRIVER] = - g_param_spec_string (NM_MODEM_DRIVER, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_CONTROL_PORT] = - g_param_spec_string (NM_MODEM_CONTROL_PORT, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_IP_IFINDEX] = - g_param_spec_int (NM_MODEM_IP_IFINDEX, "", "", - 0, G_MAXINT, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_STATE] = - g_param_spec_int (NM_MODEM_STATE, "", "", - NM_MODEM_STATE_UNKNOWN, _NM_MODEM_STATE_LAST, NM_MODEM_STATE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_DEVICE_ID] = - g_param_spec_string (NM_MODEM_DEVICE_ID, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SIM_ID] = - g_param_spec_string (NM_MODEM_SIM_ID, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_IP_TYPES] = - g_param_spec_uint (NM_MODEM_IP_TYPES, - "IP Types", - "Supported IP types", - 0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_SIM_OPERATOR_ID] = - g_param_spec_string (NM_MODEM_SIM_OPERATOR_ID, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_OPERATOR_CODE] = - g_param_spec_string (NM_MODEM_OPERATOR_CODE, "", "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_APN] = - g_param_spec_string (NM_MODEM_APN, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[PPP_STATS] = - g_signal_new (NM_MODEM_PPP_STATS, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_UINT /*guint32 in_bytes*/, - G_TYPE_UINT /*guint32 out_bytes*/); - - signals[PPP_FAILED] = - g_signal_new (NM_MODEM_PPP_FAILED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_UINT); - - signals[IP4_CONFIG_RESULT] = - g_signal_new (NM_MODEM_IP4_CONFIG_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); - - /** - * NMModem::ip6-config-result: - * @modem: the #NMModem on which the signal is emitted - * @config: the #NMIP6Config to apply to the modem's data port - * @do_slaac: %TRUE if IPv6 SLAAC should be started - * @error: a #GError if any error occurred during IP configuration - * - * This signal is emitted when IPv6 configuration has completed or failed. - * If @error is set the configuration failed. If @config is set, then - * the details should be applied to the data port before any further - * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC - * should be started after applying @config to the data port. - */ - signals[IP6_CONFIG_RESULT] = - g_signal_new (NM_MODEM_IP6_CONFIG_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_POINTER); - - signals[PREPARE_RESULT] = - g_signal_new (NM_MODEM_PREPARE_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT); - - signals[AUTH_REQUESTED] = - g_signal_new (NM_MODEM_AUTH_REQUESTED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - signals[AUTH_RESULT] = - g_signal_new (NM_MODEM_AUTH_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - signals[REMOVED] = - g_signal_new (NM_MODEM_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - - signals[STATE_CHANGED] = - g_signal_new (NM_MODEM_STATE_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); +nm_modem_class_init(NMModemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(object_class, sizeof(NMModemPrivate)); + + object_class->constructed = constructed; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + klass->modem_act_stage1_prepare = modem_act_stage1_prepare; + klass->stage3_ip6_config_request = stage3_ip6_config_request; + klass->deactivate_cleanup = deactivate_cleanup; + + obj_properties[PROP_UID] = + g_param_spec_string(NM_MODEM_UID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_PATH] = + g_param_spec_string(NM_MODEM_PATH, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_DRIVER] = + g_param_spec_string(NM_MODEM_DRIVER, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_CONTROL_PORT] = + g_param_spec_string(NM_MODEM_CONTROL_PORT, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_IP_IFINDEX] = g_param_spec_int(NM_MODEM_IP_IFINDEX, + "", + "", + 0, + G_MAXINT, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_STATE] = + g_param_spec_int(NM_MODEM_STATE, + "", + "", + NM_MODEM_STATE_UNKNOWN, + _NM_MODEM_STATE_LAST, + NM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_DEVICE_ID] = + g_param_spec_string(NM_MODEM_DEVICE_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SIM_ID] = + g_param_spec_string(NM_MODEM_SIM_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_IP_TYPES] = + g_param_spec_uint(NM_MODEM_IP_TYPES, + "IP Types", + "Supported IP types", + 0, + G_MAXUINT32, + NM_MODEM_IP_TYPE_IPV4, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SIM_OPERATOR_ID] = + g_param_spec_string(NM_MODEM_SIM_OPERATOR_ID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_OPERATOR_CODE] = + g_param_spec_string(NM_MODEM_OPERATOR_CODE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_APN] = + g_param_spec_string(NM_MODEM_APN, "", "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + signals[PPP_STATS] = g_signal_new(NM_MODEM_PPP_STATS, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_UINT /*guint32 in_bytes*/, + G_TYPE_UINT /*guint32 out_bytes*/); + + signals[PPP_FAILED] = g_signal_new(NM_MODEM_PPP_FAILED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + signals[IP4_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP4_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_OBJECT, + G_TYPE_POINTER); + + /** + * NMModem::ip6-config-result: + * @modem: the #NMModem on which the signal is emitted + * @config: the #NMIP6Config to apply to the modem's data port + * @do_slaac: %TRUE if IPv6 SLAAC should be started + * @error: a #GError if any error occurred during IP configuration + * + * This signal is emitted when IPv6 configuration has completed or failed. + * If @error is set the configuration failed. If @config is set, then + * the details should be applied to the data port before any further + * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC + * should be started after applying @config to the data port. + */ + signals[IP6_CONFIG_RESULT] = g_signal_new(NM_MODEM_IP6_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 3, + G_TYPE_OBJECT, + G_TYPE_BOOLEAN, + G_TYPE_POINTER); + + signals[PREPARE_RESULT] = g_signal_new(NM_MODEM_PREPARE_RESULT, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_BOOLEAN, + G_TYPE_UINT); + + signals[AUTH_REQUESTED] = g_signal_new(NM_MODEM_AUTH_REQUESTED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[AUTH_RESULT] = g_signal_new(NM_MODEM_AUTH_RESULT, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_POINTER); + + signals[REMOVED] = g_signal_new(NM_MODEM_REMOVED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[STATE_CHANGED] = g_signal_new(NM_MODEM_STATE_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_INT, + G_TYPE_INT); } diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index f2de990b..4b275cf7 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2009 - 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. @@ -10,12 +10,12 @@ #include "ppp/nm-ppp-manager.h" #include "devices/nm-device.h" -#define NM_TYPE_MODEM (nm_modem_get_type ()) -#define NM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM, NMModem)) -#define NM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM, NMModemClass)) -#define NM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM)) -#define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM)) -#define NM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM, NMModemClass)) +#define NM_TYPE_MODEM (nm_modem_get_type()) +#define NM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MODEM, NMModem)) +#define NM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_MODEM, NMModemClass)) +#define NM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_MODEM)) +#define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_MODEM)) +#define NM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_MODEM, NMModemClass)) /* Properties */ #define NM_MODEM_UID "uid" @@ -26,7 +26,7 @@ #define NM_MODEM_STATE "state" #define NM_MODEM_DEVICE_ID "device-id" #define NM_MODEM_SIM_ID "sim-id" -#define NM_MODEM_IP_TYPES "ip-types" /* Supported IP types */ +#define NM_MODEM_IP_TYPES "ip-types" /* Supported IP types */ #define NM_MODEM_SIM_OPERATOR_ID "sim-operator-id" #define NM_MODEM_OPERATOR_CODE "operator-code" #define NM_MODEM_APN "apn" @@ -43,10 +43,10 @@ #define NM_MODEM_STATE_CHANGED "state-changed" typedef enum { - NM_MODEM_IP_METHOD_UNKNOWN = 0, - NM_MODEM_IP_METHOD_PPP, - NM_MODEM_IP_METHOD_STATIC, - NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */ + NM_MODEM_IP_METHOD_UNKNOWN = 0, + NM_MODEM_IP_METHOD_PPP, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */ } NMModemIPMethod; /** @@ -62,222 +62,208 @@ typedef enum { * but not simultaneously on the same bearer. */ typedef enum { - NM_MODEM_IP_TYPE_UNKNOWN = 0x0, - NM_MODEM_IP_TYPE_IPV4 = 0x1, - NM_MODEM_IP_TYPE_IPV6 = 0x2, - NM_MODEM_IP_TYPE_IPV4V6 = 0x4 + NM_MODEM_IP_TYPE_UNKNOWN = 0x0, + NM_MODEM_IP_TYPE_IPV4 = 0x1, + NM_MODEM_IP_TYPE_IPV6 = 0x2, + NM_MODEM_IP_TYPE_IPV4V6 = 0x4 } NMModemIPType; -typedef enum { /*< underscore_name=nm_modem_state >*/ - NM_MODEM_STATE_UNKNOWN = 0, - NM_MODEM_STATE_FAILED = 1, - NM_MODEM_STATE_INITIALIZING = 2, - NM_MODEM_STATE_LOCKED = 3, - NM_MODEM_STATE_DISABLED = 4, - NM_MODEM_STATE_DISABLING = 5, - NM_MODEM_STATE_ENABLING = 6, - NM_MODEM_STATE_ENABLED = 7, - NM_MODEM_STATE_SEARCHING = 8, - NM_MODEM_STATE_REGISTERED = 9, - NM_MODEM_STATE_DISCONNECTING = 10, - NM_MODEM_STATE_CONNECTING = 11, - NM_MODEM_STATE_CONNECTED = 12, - - _NM_MODEM_STATE_LAST0, - _NM_MODEM_STATE_LAST = _NM_MODEM_STATE_LAST0 -1, +typedef enum { /*< underscore_name=nm_modem_state >*/ + NM_MODEM_STATE_UNKNOWN = 0, + NM_MODEM_STATE_FAILED = 1, + NM_MODEM_STATE_INITIALIZING = 2, + NM_MODEM_STATE_LOCKED = 3, + NM_MODEM_STATE_DISABLED = 4, + NM_MODEM_STATE_DISABLING = 5, + NM_MODEM_STATE_ENABLING = 6, + NM_MODEM_STATE_ENABLED = 7, + NM_MODEM_STATE_SEARCHING = 8, + NM_MODEM_STATE_REGISTERED = 9, + NM_MODEM_STATE_DISCONNECTING = 10, + NM_MODEM_STATE_CONNECTING = 11, + NM_MODEM_STATE_CONNECTED = 12, + + _NM_MODEM_STATE_LAST0, + _NM_MODEM_STATE_LAST = _NM_MODEM_STATE_LAST0 - 1, } NMModemState; struct _NMModemPrivate; struct _NMModem { - GObject parent; - struct _NMModemPrivate *_priv; + GObject parent; + struct _NMModemPrivate *_priv; }; typedef struct _NMModem NMModem; -typedef void (*_NMModemDisconnectCallback) (NMModem *modem, - GError *error, - gpointer user_data); +typedef void (*_NMModemDisconnectCallback)(NMModem *modem, GError *error, gpointer user_data); typedef struct { - GObjectClass parent; - - void (*get_capabilities) (NMModem *self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps); - - gboolean (*get_user_pass) (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass); - - gboolean (*check_connection_compatible_with_modem) (NMModem *modem, - NMConnection *connection, - GError **error); - - gboolean (*complete_connection) (NMModem *modem, - const char *iface, - NMConnection *connection, - NMConnection *const*existing_connections, - GError **error); - - NMActStageReturn (*modem_act_stage1_prepare) (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *out_failure_reason); - - NMActStageReturn (*static_stage3_ip4_config_start) (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason); - - /* Request the IP6 config; when the config returns the modem - * subclass should emit the ip6_config_result signal. - */ - NMActStageReturn (*stage3_ip6_config_request) (NMModem *self, - NMDeviceStateReason *out_failure_reason); - - void (*set_mm_enabled) (NMModem *self, gboolean enabled); - - void (*disconnect) (NMModem *self, - gboolean warn, - GCancellable *cancellable, - _NMModemDisconnectCallback callback, - gpointer user_data); - - void (*deactivate_cleanup) (NMModem *self, - NMDevice *device, - gboolean stop_ppp_manager); - - gboolean (*owns_port) (NMModem *self, const char *iface); + GObjectClass parent; + + void (*get_capabilities)(NMModem * self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps); + + gboolean (*get_user_pass)(NMModem * modem, + NMConnection *connection, + const char ** user, + const char ** pass); + + gboolean (*check_connection_compatible_with_modem)(NMModem * modem, + NMConnection *connection, + GError ** error); + + gboolean (*complete_connection)(NMModem * modem, + const char * iface, + NMConnection * connection, + NMConnection *const *existing_connections, + GError ** error); + + NMActStageReturn (*modem_act_stage1_prepare)(NMModem * modem, + NMConnection * connection, + NMDeviceStateReason *out_failure_reason); + + NMActStageReturn (*static_stage3_ip4_config_start)(NMModem * self, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason); + + /* Request the IP6 config; when the config returns the modem + * subclass should emit the ip6_config_result signal. + */ + NMActStageReturn (*stage3_ip6_config_request)(NMModem * self, + NMDeviceStateReason *out_failure_reason); + + void (*set_mm_enabled)(NMModem *self, gboolean enabled); + + void (*disconnect)(NMModem * self, + gboolean warn, + GCancellable * cancellable, + _NMModemDisconnectCallback callback, + gpointer user_data); + + void (*deactivate_cleanup)(NMModem *self, NMDevice *device, gboolean stop_ppp_manager); + + gboolean (*owns_port)(NMModem *self, const char *iface); } NMModemClass; -GType nm_modem_get_type (void); - -gboolean nm_modem_is_claimed (NMModem *modem); -NMModem *nm_modem_claim (NMModem *modem); -void nm_modem_unclaim (NMModem *modem); - -const char *nm_modem_get_path (NMModem *modem); -const char *nm_modem_get_uid (NMModem *modem); -const char *nm_modem_get_control_port (NMModem *modem); -int nm_modem_get_ip_ifindex (NMModem *modem); -const char *nm_modem_get_driver (NMModem *modem); -const char *nm_modem_get_device_id (NMModem *modem); -const char *nm_modem_get_sim_id (NMModem *modem); -const char *nm_modem_get_sim_operator_id (NMModem *modem); -gboolean nm_modem_get_iid (NMModem *modem, NMUtilsIPv6IfaceId *out_iid); -const char *nm_modem_get_operator_code (NMModem *modem); -const char *nm_modem_get_apn (NMModem *modem); - -gboolean nm_modem_set_data_port (NMModem *self, - NMPlatform *platform, - const char *data_port, - NMModemIPMethod ip4_method, - NMModemIPMethod ip6_method, - guint timeout, - GError **error); - -gboolean nm_modem_owns_port (NMModem *modem, const char *iface); - -void nm_modem_get_capabilities (NMModem *self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps); - -gboolean nm_modem_check_connection_compatible (NMModem *self, - NMConnection *connection, - GError **error); - -gboolean nm_modem_complete_connection (NMModem *self, - const char *iface, - NMConnection *connection, - NMConnection *const*existing_connections, - GError **error); - -void nm_modem_get_route_parameters (NMModem *self, - guint32 *out_ip4_route_table, - guint32 *out_ip4_route_metric, - guint32 *out_ip6_route_table, - guint32 *out_ip6_route_metric); - -void nm_modem_set_route_parameters (NMModem *self, - guint32 ip4_route_table, - guint32 ip4_route_metric, - guint32 ip6_route_table, - guint32 ip6_route_metric); - -void nm_modem_set_route_parameters_from_device (NMModem *modem, - NMDevice *device); - -NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem, - NMActRequest *req, - NMDeviceStateReason *out_failure_reason); - -void nm_modem_act_stage2_config (NMModem *modem); - -NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem, - NMDevice *device, - NMDeviceClass *device_class, - NMDeviceStateReason *out_failure_reason); - -NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, - NMDevice *device, - NMDeviceStateReason *out_failure_reason); - -void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config); - -void nm_modem_get_secrets (NMModem *modem, - const char *setting_name, - gboolean request_new, - const char *hint); - -void nm_modem_deactivate (NMModem *modem, NMDevice *device); - -typedef void (*NMModemDeactivateCallback) (NMModem *self, - GError *error, - gpointer user_data); - -void nm_modem_deactivate_async (NMModem *self, - NMDevice *device, - GCancellable *cancellable, - NMModemDeactivateCallback callback, - gpointer user_data); - -void nm_modem_device_state_changed (NMModem *modem, - NMDeviceState new_state, - NMDeviceState old_state); - -void nm_modem_set_mm_enabled (NMModem *self, gboolean enabled); - -NMModemState nm_modem_get_state (NMModem *self); -void nm_modem_set_state (NMModem *self, - NMModemState new_state, - const char *reason); -void nm_modem_set_prev_state (NMModem *self, const char *reason); -const char * nm_modem_state_to_string (NMModemState state); - -NMModemIPType nm_modem_get_supported_ip_types (NMModem *self); +GType nm_modem_get_type(void); + +gboolean nm_modem_is_claimed(NMModem *modem); +NMModem *nm_modem_claim(NMModem *modem); +void nm_modem_unclaim(NMModem *modem); + +const char *nm_modem_get_path(NMModem *modem); +const char *nm_modem_get_uid(NMModem *modem); +const char *nm_modem_get_control_port(NMModem *modem); +int nm_modem_get_ip_ifindex(NMModem *modem); +const char *nm_modem_get_driver(NMModem *modem); +const char *nm_modem_get_device_id(NMModem *modem); +const char *nm_modem_get_sim_id(NMModem *modem); +const char *nm_modem_get_sim_operator_id(NMModem *modem); +gboolean nm_modem_get_iid(NMModem *modem, NMUtilsIPv6IfaceId *out_iid); +const char *nm_modem_get_operator_code(NMModem *modem); +const char *nm_modem_get_apn(NMModem *modem); + +gboolean nm_modem_set_data_port(NMModem * self, + NMPlatform * platform, + const char * data_port, + NMModemIPMethod ip4_method, + NMModemIPMethod ip6_method, + guint timeout, + GError ** error); + +gboolean nm_modem_owns_port(NMModem *modem, const char *iface); + +void nm_modem_get_capabilities(NMModem * self, + NMDeviceModemCapabilities *modem_caps, + NMDeviceModemCapabilities *current_caps); + +gboolean +nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GError **error); + +gboolean nm_modem_complete_connection(NMModem * self, + const char * iface, + NMConnection * connection, + NMConnection *const *existing_connections, + GError ** error); + +void nm_modem_get_route_parameters(NMModem *self, + guint32 *out_ip4_route_table, + guint32 *out_ip4_route_metric, + guint32 *out_ip6_route_table, + guint32 *out_ip6_route_metric); + +void nm_modem_set_route_parameters(NMModem *self, + guint32 ip4_route_table, + guint32 ip4_route_metric, + guint32 ip6_route_table, + guint32 ip6_route_metric); + +void nm_modem_set_route_parameters_from_device(NMModem *modem, NMDevice *device); + +NMActStageReturn nm_modem_act_stage1_prepare(NMModem * modem, + NMActRequest * req, + NMDeviceStateReason *out_failure_reason); + +void nm_modem_act_stage2_config(NMModem *modem); + +NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem * modem, + NMDevice * device, + NMDeviceClass * device_class, + NMDeviceStateReason *out_failure_reason); + +NMActStageReturn nm_modem_stage3_ip6_config_start(NMModem * modem, + NMDevice * device, + NMDeviceStateReason *out_failure_reason); + +void nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config); + +void nm_modem_get_secrets(NMModem * modem, + const char *setting_name, + gboolean request_new, + const char *hint); + +void nm_modem_deactivate(NMModem *modem, NMDevice *device); + +typedef void (*NMModemDeactivateCallback)(NMModem *self, GError *error, gpointer user_data); + +void nm_modem_deactivate_async(NMModem * self, + NMDevice * device, + GCancellable * cancellable, + NMModemDeactivateCallback callback, + gpointer user_data); + +void +nm_modem_device_state_changed(NMModem *modem, NMDeviceState new_state, NMDeviceState old_state); + +void nm_modem_set_mm_enabled(NMModem *self, gboolean enabled); + +NMModemState nm_modem_get_state(NMModem *self); +void nm_modem_set_state(NMModem *self, NMModemState new_state, const char *reason); +void nm_modem_set_prev_state(NMModem *self, const char *reason); +const char * nm_modem_state_to_string(NMModemState state); + +NMModemIPType nm_modem_get_supported_ip_types(NMModem *self); /* For the modem-manager only */ -void nm_modem_emit_removed (NMModem *self); +void nm_modem_emit_removed(NMModem *self); -void nm_modem_emit_prepare_result (NMModem *self, gboolean success, NMDeviceStateReason reason); +void nm_modem_emit_prepare_result(NMModem *self, gboolean success, NMDeviceStateReason reason); -void nm_modem_emit_ppp_failed (NMModem *self, NMDeviceStateReason reason); +void nm_modem_emit_ppp_failed(NMModem *self, NMDeviceStateReason reason); -GArray *nm_modem_get_connection_ip_type (NMModem *self, - NMConnection *connection, - GError **error); +GArray *nm_modem_get_connection_ip_type(NMModem *self, NMConnection *connection, GError **error); /* For subclasses */ -void nm_modem_emit_ip6_config_result (NMModem *self, - NMIP6Config *config, - GError *error); +void nm_modem_emit_ip6_config_result(NMModem *self, NMIP6Config *config, GError *error); -const char *nm_modem_ip_type_to_string (NMModemIPType ip_type); +const char *nm_modem_ip_type_to_string(NMModemIPType ip_type); -guint32 nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force); +guint32 +nm_modem_get_configured_mtu(NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force); -void _nm_modem_set_operator_code (NMModem *self, const char *operator_code); -void _nm_modem_set_apn (NMModem *self, const char *apn); +void _nm_modem_set_operator_code(NMModem *self, const char *operator_code); +void _nm_modem_set_apn(NMModem *self, const char *apn); #endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-service-providers.c b/src/devices/wwan/nm-service-providers.c index 5694c99e..f7c6b5b8 100644 --- a/src/devices/wwan/nm-service-providers.c +++ b/src/devices/wwan/nm-service-providers.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2009 Novell, Inc. * Author: Tambet Ingo (tambet@gmail.com). @@ -11,449 +11,445 @@ #include "nm-service-providers.h" typedef enum { - PARSER_TOPLEVEL = 0, - PARSER_COUNTRY, - PARSER_PROVIDER, - PARSER_METHOD_GSM, - PARSER_METHOD_GSM_APN, - PARSER_METHOD_CDMA, - PARSER_DONE, - PARSER_ERROR + PARSER_TOPLEVEL = 0, + PARSER_COUNTRY, + PARSER_PROVIDER, + PARSER_METHOD_GSM, + PARSER_METHOD_GSM_APN, + PARSER_METHOD_CDMA, + PARSER_DONE, + PARSER_ERROR } ParseContextState; typedef struct { - char *mccmnc; - NMServiceProvidersGsmApnCallback callback; - gpointer user_data; - GCancellable *cancellable; - GMarkupParseContext *ctx; - char buffer[4096]; - - char *text_buffer; - ParseContextState state; - - gboolean mccmnc_matched; - gboolean found_internet_apn; - char *apn; - char *username; - char *password; - char *gateway; - char *auth_method; - GSList *dns; + char * mccmnc; + NMServiceProvidersGsmApnCallback callback; + gpointer user_data; + GCancellable * cancellable; + GMarkupParseContext * ctx; + char buffer[4096]; + + char * text_buffer; + ParseContextState state; + + gboolean mccmnc_matched; + gboolean found_internet_apn; + char * apn; + char * username; + char * password; + char * gateway; + char * auth_method; + GSList * dns; } ParseContext; /*****************************************************************************/ static void -parser_toplevel_start (ParseContext *parse_context, - const char *name, - const char **attribute_names, - const char **attribute_values) +parser_toplevel_start(ParseContext *parse_context, + const char * name, + const char ** attribute_names, + const char ** attribute_values) { - int i; - - if (strcmp (name, "serviceproviders") == 0) { - for (i = 0; attribute_names && attribute_names[i]; i++) { - if (strcmp (attribute_names[i], "format") == 0) { - if (strcmp (attribute_values[i], "2.0")) { - g_warning ("%s: mobile broadband provider database format '%s'" - " not supported.", __func__, attribute_values[i]); - parse_context->state = PARSER_ERROR; - break; - } - } - } - } else if (strcmp (name, "country") == 0) { - parse_context->state = PARSER_COUNTRY; - } + int i; + + if (strcmp(name, "serviceproviders") == 0) { + for (i = 0; attribute_names && attribute_names[i]; i++) { + if (strcmp(attribute_names[i], "format") == 0) { + if (strcmp(attribute_values[i], "2.0")) { + g_warning("%s: mobile broadband provider database format '%s'" + " not supported.", + __func__, + attribute_values[i]); + parse_context->state = PARSER_ERROR; + break; + } + } + } + } else if (strcmp(name, "country") == 0) { + parse_context->state = PARSER_COUNTRY; + } } static void -parser_country_start (ParseContext *parse_context, - const char *name, - const char **attribute_names, - const char **attribute_values) +parser_country_start(ParseContext *parse_context, + const char * name, + const char ** attribute_names, + const char ** attribute_values) { - if (strcmp (name, "provider") == 0) - parse_context->state = PARSER_PROVIDER; + if (strcmp(name, "provider") == 0) + parse_context->state = PARSER_PROVIDER; } static void -parser_provider_start (ParseContext *parse_context, - const char *name, - const char **attribute_names, - const char **attribute_values) +parser_provider_start(ParseContext *parse_context, + const char * name, + const char ** attribute_names, + const char ** attribute_values) { - parse_context->mccmnc_matched = FALSE; - if (strcmp (name, "gsm") == 0) - parse_context->state = PARSER_METHOD_GSM; - else if (strcmp (name, "cdma") == 0) - parse_context->state = PARSER_METHOD_CDMA; + parse_context->mccmnc_matched = FALSE; + if (strcmp(name, "gsm") == 0) + parse_context->state = PARSER_METHOD_GSM; + else if (strcmp(name, "cdma") == 0) + parse_context->state = PARSER_METHOD_CDMA; } static void -parser_gsm_start (ParseContext *parse_context, - const char *name, - const char **attribute_names, - const char **attribute_values) +parser_gsm_start(ParseContext *parse_context, + const char * name, + const char ** attribute_names, + const char ** attribute_values) { - int i; - - if (strcmp (name, "network-id") == 0) { - const char *mcc = NULL, *mnc = NULL; - - for (i = 0; attribute_names && attribute_names[i]; i++) { - if (strcmp (attribute_names[i], "mcc") == 0) - mcc = attribute_values[i]; - else if (strcmp (attribute_names[i], "mnc") == 0) - mnc = attribute_values[i]; - if (mcc && strlen (mcc) && mnc && strlen (mnc)) { - char *mccmnc = g_strdup_printf ("%s%s", mcc, mnc); - - if (strcmp (mccmnc, parse_context->mccmnc) == 0) - parse_context->mccmnc_matched = TRUE; - g_free (mccmnc); - break; - } - } - } else if (strcmp (name, "apn") == 0) { - parse_context->found_internet_apn = FALSE; - nm_clear_g_free (&parse_context->apn); - nm_clear_g_free (&parse_context->username); - nm_clear_g_free (&parse_context->password); - nm_clear_g_free (&parse_context->gateway); - nm_clear_g_free (&parse_context->auth_method); - g_slist_free_full (parse_context->dns, g_free); - parse_context->dns = NULL; - - for (i = 0; attribute_names && attribute_names[i]; i++) { - if (strcmp (attribute_names[i], "value") == 0) { - parse_context->state = PARSER_METHOD_GSM_APN; - parse_context->apn = g_strstrip (g_strdup (attribute_values[i])); - break; - } - } - } + int i; + + if (strcmp(name, "network-id") == 0) { + const char *mcc = NULL, *mnc = NULL; + + for (i = 0; attribute_names && attribute_names[i]; i++) { + if (strcmp(attribute_names[i], "mcc") == 0) + mcc = attribute_values[i]; + else if (strcmp(attribute_names[i], "mnc") == 0) + mnc = attribute_values[i]; + if (mcc && strlen(mcc) && mnc && strlen(mnc)) { + char *mccmnc = g_strdup_printf("%s%s", mcc, mnc); + + if (strcmp(mccmnc, parse_context->mccmnc) == 0) + parse_context->mccmnc_matched = TRUE; + g_free(mccmnc); + break; + } + } + } else if (strcmp(name, "apn") == 0) { + parse_context->found_internet_apn = FALSE; + nm_clear_g_free(&parse_context->apn); + nm_clear_g_free(&parse_context->username); + nm_clear_g_free(&parse_context->password); + nm_clear_g_free(&parse_context->gateway); + nm_clear_g_free(&parse_context->auth_method); + g_slist_free_full(parse_context->dns, g_free); + parse_context->dns = NULL; + + for (i = 0; attribute_names && attribute_names[i]; i++) { + if (strcmp(attribute_names[i], "value") == 0) { + parse_context->state = PARSER_METHOD_GSM_APN; + parse_context->apn = g_strstrip(g_strdup(attribute_values[i])); + break; + } + } + } } static void -parser_gsm_apn_start (ParseContext *parse_context, - const char *name, - const char **attribute_names, - const char **attribute_values) +parser_gsm_apn_start(ParseContext *parse_context, + const char * name, + const char ** attribute_names, + const char ** attribute_values) { - int i; - - if (strcmp (name, "usage") == 0) { - for (i = 0; attribute_names && attribute_names[i]; i++) { - if ( (strcmp (attribute_names[i], "type") == 0) - && (strcmp (attribute_values[i], "internet") == 0)) { - parse_context->found_internet_apn = TRUE; - break; - } - } - } else if (strcmp (name, "authentication") == 0) { - for (i = 0; attribute_names && attribute_names[i]; i++) { - if (strcmp (attribute_names[i], "method") == 0) { - nm_clear_g_free (&parse_context->auth_method); - parse_context->auth_method = g_strstrip (g_strdup (attribute_values[i])); - break; - } - } - } + int i; + + if (strcmp(name, "usage") == 0) { + for (i = 0; attribute_names && attribute_names[i]; i++) { + if ((strcmp(attribute_names[i], "type") == 0) + && (strcmp(attribute_values[i], "internet") == 0)) { + parse_context->found_internet_apn = TRUE; + break; + } + } + } else if (strcmp(name, "authentication") == 0) { + for (i = 0; attribute_names && attribute_names[i]; i++) { + if (strcmp(attribute_names[i], "method") == 0) { + nm_clear_g_free(&parse_context->auth_method); + parse_context->auth_method = g_strstrip(g_strdup(attribute_values[i])); + break; + } + } + } } static void -parser_start_element (GMarkupParseContext *context, - const char *element_name, - const char **attribute_names, - const char **attribute_values, - gpointer user_data, - GError **error) +parser_start_element(GMarkupParseContext *context, + const char * element_name, + const char ** attribute_names, + const char ** attribute_values, + gpointer user_data, + GError ** error) { - ParseContext *parse_context = user_data; - - nm_clear_g_free (&parse_context->text_buffer); - - switch (parse_context->state) { - case PARSER_TOPLEVEL: - parser_toplevel_start (parse_context, element_name, attribute_names, attribute_values); - break; - case PARSER_COUNTRY: - parser_country_start (parse_context, element_name, attribute_names, attribute_values); - break; - case PARSER_PROVIDER: - parser_provider_start (parse_context, element_name, attribute_names, attribute_values); - break; - case PARSER_METHOD_GSM: - parser_gsm_start (parse_context, element_name, attribute_names, attribute_values); - break; - case PARSER_METHOD_GSM_APN: - parser_gsm_apn_start (parse_context, element_name, attribute_names, attribute_values); - break; - case PARSER_METHOD_CDMA: - break; - case PARSER_ERROR: - break; - case PARSER_DONE: - break; - } + ParseContext *parse_context = user_data; + + nm_clear_g_free(&parse_context->text_buffer); + + switch (parse_context->state) { + case PARSER_TOPLEVEL: + parser_toplevel_start(parse_context, element_name, attribute_names, attribute_values); + break; + case PARSER_COUNTRY: + parser_country_start(parse_context, element_name, attribute_names, attribute_values); + break; + case PARSER_PROVIDER: + parser_provider_start(parse_context, element_name, attribute_names, attribute_values); + break; + case PARSER_METHOD_GSM: + parser_gsm_start(parse_context, element_name, attribute_names, attribute_values); + break; + case PARSER_METHOD_GSM_APN: + parser_gsm_apn_start(parse_context, element_name, attribute_names, attribute_values); + break; + case PARSER_METHOD_CDMA: + break; + case PARSER_ERROR: + break; + case PARSER_DONE: + break; + } } static void -parser_country_end (ParseContext *parse_context, - const char *name) +parser_country_end(ParseContext *parse_context, const char *name) { - if (strcmp (name, "country") == 0) { - nm_clear_g_free (&parse_context->text_buffer); - parse_context->state = PARSER_TOPLEVEL; - } + if (strcmp(name, "country") == 0) { + nm_clear_g_free(&parse_context->text_buffer); + parse_context->state = PARSER_TOPLEVEL; + } } static void -parser_provider_end (ParseContext *parse_context, - const char *name) +parser_provider_end(ParseContext *parse_context, const char *name) { - if (strcmp (name, "provider") == 0) { - nm_clear_g_free (&parse_context->text_buffer); - parse_context->state = PARSER_COUNTRY; - } + if (strcmp(name, "provider") == 0) { + nm_clear_g_free(&parse_context->text_buffer); + parse_context->state = PARSER_COUNTRY; + } } static void -parser_gsm_end (ParseContext *parse_context, - const char *name) +parser_gsm_end(ParseContext *parse_context, const char *name) { - if (strcmp (name, "gsm") == 0) { - nm_clear_g_free (&parse_context->text_buffer); - parse_context->state = PARSER_PROVIDER; - } + if (strcmp(name, "gsm") == 0) { + nm_clear_g_free(&parse_context->text_buffer); + parse_context->state = PARSER_PROVIDER; + } } static void -parser_gsm_apn_end (ParseContext *parse_context, - const char *name) +parser_gsm_apn_end(ParseContext *parse_context, const char *name) { - if (strcmp (name, "username") == 0) { - nm_clear_g_free (&parse_context->username); - parse_context->username = g_steal_pointer (&parse_context->text_buffer); - } else if (strcmp (name, "password") == 0) { - nm_clear_g_free (&parse_context->password); - parse_context->password = g_steal_pointer (&parse_context->text_buffer); - } else if (strcmp (name, "dns") == 0) { - parse_context->dns = g_slist_prepend (parse_context->dns, - g_steal_pointer (&parse_context->text_buffer)); - } else if (strcmp (name, "gateway") == 0) { - nm_clear_g_free (&parse_context->gateway); - parse_context->gateway = g_steal_pointer (&parse_context->text_buffer); - } else if (strcmp (name, "apn") == 0) { - nm_clear_g_free (&parse_context->text_buffer); - - if (parse_context->mccmnc_matched && parse_context->found_internet_apn) - parse_context->state = PARSER_DONE; - else - parse_context->state = PARSER_METHOD_GSM; - - } + if (strcmp(name, "username") == 0) { + nm_clear_g_free(&parse_context->username); + parse_context->username = g_steal_pointer(&parse_context->text_buffer); + } else if (strcmp(name, "password") == 0) { + nm_clear_g_free(&parse_context->password); + parse_context->password = g_steal_pointer(&parse_context->text_buffer); + } else if (strcmp(name, "dns") == 0) { + parse_context->dns = + g_slist_prepend(parse_context->dns, g_steal_pointer(&parse_context->text_buffer)); + } else if (strcmp(name, "gateway") == 0) { + nm_clear_g_free(&parse_context->gateway); + parse_context->gateway = g_steal_pointer(&parse_context->text_buffer); + } else if (strcmp(name, "apn") == 0) { + nm_clear_g_free(&parse_context->text_buffer); + + if (parse_context->mccmnc_matched && parse_context->found_internet_apn) + parse_context->state = PARSER_DONE; + else + parse_context->state = PARSER_METHOD_GSM; + } } static void -parser_cdma_end (ParseContext *parse_context, - const char *name) +parser_cdma_end(ParseContext *parse_context, const char *name) { - if (strcmp (name, "cdma") == 0) { - nm_clear_g_free (&parse_context->text_buffer); - parse_context->state = PARSER_PROVIDER; - } + if (strcmp(name, "cdma") == 0) { + nm_clear_g_free(&parse_context->text_buffer); + parse_context->state = PARSER_PROVIDER; + } } static void -parser_end_element (GMarkupParseContext *context, - const char *element_name, - gpointer user_data, - GError **error) +parser_end_element(GMarkupParseContext *context, + const char * element_name, + gpointer user_data, + GError ** error) { - ParseContext *parse_context = user_data; - - switch (parse_context->state) { - case PARSER_TOPLEVEL: - break; - case PARSER_COUNTRY: - parser_country_end (parse_context, element_name); - break; - case PARSER_PROVIDER: - parser_provider_end (parse_context, element_name); - break; - case PARSER_METHOD_GSM: - parser_gsm_end (parse_context, element_name); - break; - case PARSER_METHOD_GSM_APN: - parser_gsm_apn_end (parse_context, element_name); - break; - case PARSER_METHOD_CDMA: - parser_cdma_end (parse_context, element_name); - break; - case PARSER_ERROR: - break; - case PARSER_DONE: - break; - } + ParseContext *parse_context = user_data; + + switch (parse_context->state) { + case PARSER_TOPLEVEL: + break; + case PARSER_COUNTRY: + parser_country_end(parse_context, element_name); + break; + case PARSER_PROVIDER: + parser_provider_end(parse_context, element_name); + break; + case PARSER_METHOD_GSM: + parser_gsm_end(parse_context, element_name); + break; + case PARSER_METHOD_GSM_APN: + parser_gsm_apn_end(parse_context, element_name); + break; + case PARSER_METHOD_CDMA: + parser_cdma_end(parse_context, element_name); + break; + case PARSER_ERROR: + break; + case PARSER_DONE: + break; + } } static void -parser_text (GMarkupParseContext *context, - const char *text, - gsize text_len, - gpointer user_data, - GError **error) +parser_text(GMarkupParseContext *context, + const char * text, + gsize text_len, + gpointer user_data, + GError ** error) { - ParseContext *parse_context = user_data; + ParseContext *parse_context = user_data; - g_free (parse_context->text_buffer); - parse_context->text_buffer = g_strdup (text); + g_free(parse_context->text_buffer); + parse_context->text_buffer = g_strdup(text); } static const GMarkupParser parser = { - .start_element = parser_start_element, - .end_element = parser_end_element, - .text = parser_text, - .passthrough = NULL, - .error = NULL, + .start_element = parser_start_element, + .end_element = parser_end_element, + .text = parser_text, + .passthrough = NULL, + .error = NULL, }; /*****************************************************************************/ static void -finish_parse_context (ParseContext *parse_context, GError *error) +finish_parse_context(ParseContext *parse_context, GError *error) { - if (parse_context->callback) { - if (error) { - parse_context->callback (NULL, NULL, NULL, NULL, NULL, - NULL, error, - parse_context->user_data); - } else { - parse_context->callback (parse_context->apn, - parse_context->username, - parse_context->password, - parse_context->gateway, - parse_context->auth_method, - parse_context->dns, - error, - parse_context->user_data); - } - } - - g_free (parse_context->mccmnc); - g_markup_parse_context_free (parse_context->ctx); - - g_free (parse_context->text_buffer); - g_free (parse_context->apn); - g_free (parse_context->username); - g_free (parse_context->password); - g_free (parse_context->gateway); - g_free (parse_context->auth_method); - g_slist_free_full (parse_context->dns, g_free); - - g_slice_free (ParseContext, parse_context); + if (parse_context->callback) { + if (error) { + parse_context + ->callback(NULL, NULL, NULL, NULL, NULL, NULL, error, parse_context->user_data); + } else { + parse_context->callback(parse_context->apn, + parse_context->username, + parse_context->password, + parse_context->gateway, + parse_context->auth_method, + parse_context->dns, + error, + parse_context->user_data); + } + } + + g_free(parse_context->mccmnc); + g_markup_parse_context_free(parse_context->ctx); + + g_free(parse_context->text_buffer); + g_free(parse_context->apn); + g_free(parse_context->username); + g_free(parse_context->password); + g_free(parse_context->gateway); + g_free(parse_context->auth_method); + g_slist_free_full(parse_context->dns, g_free); + + g_slice_free(ParseContext, parse_context); } -static void -read_next_chunk (GInputStream *stream, ParseContext *parse_context); +static void read_next_chunk(GInputStream *stream, ParseContext *parse_context); static void -stream_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +stream_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - GInputStream *stream = G_INPUT_STREAM (source_object); - ParseContext *parse_context = user_data; - gssize len; - GError *error = NULL; - - len = g_input_stream_read_finish (stream, res, &error); - if (len == -1) { - g_prefix_error (&error, "Error reading service provider database: "); - finish_parse_context (parse_context, error); - g_clear_error (&error); - return; - } - - if (len == 0) { - g_set_error (&error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "Operator ID '%s' not found in service provider database", - parse_context->mccmnc); - finish_parse_context (parse_context, error); - g_clear_error (&error); - return; - } - - if (!g_markup_parse_context_parse (parse_context->ctx, parse_context->buffer, len, &error)) { - g_prefix_error (&error, "Error parsing service provider database: "); - finish_parse_context (parse_context, error); - g_clear_error (&error); - return; - } - - if (parse_context->state == PARSER_DONE) { - finish_parse_context (parse_context, NULL); - return; - } - - read_next_chunk (stream, parse_context); + GInputStream *stream = G_INPUT_STREAM(source_object); + ParseContext *parse_context = user_data; + gssize len; + GError * error = NULL; + + len = g_input_stream_read_finish(stream, res, &error); + if (len == -1) { + g_prefix_error(&error, "Error reading service provider database: "); + finish_parse_context(parse_context, error); + g_clear_error(&error); + return; + } + + if (len == 0) { + g_set_error(&error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "Operator ID '%s' not found in service provider database", + parse_context->mccmnc); + finish_parse_context(parse_context, error); + g_clear_error(&error); + return; + } + + if (!g_markup_parse_context_parse(parse_context->ctx, parse_context->buffer, len, &error)) { + g_prefix_error(&error, "Error parsing service provider database: "); + finish_parse_context(parse_context, error); + g_clear_error(&error); + return; + } + + if (parse_context->state == PARSER_DONE) { + finish_parse_context(parse_context, NULL); + return; + } + + read_next_chunk(stream, parse_context); } static void -read_next_chunk (GInputStream *stream, ParseContext *parse_context) +read_next_chunk(GInputStream *stream, ParseContext *parse_context) { - g_input_stream_read_async (stream, - parse_context->buffer, - sizeof (parse_context->buffer), - G_PRIORITY_DEFAULT, - parse_context->cancellable, - stream_read_cb, - parse_context); + g_input_stream_read_async(stream, + parse_context->buffer, + sizeof(parse_context->buffer), + G_PRIORITY_DEFAULT, + parse_context->cancellable, + stream_read_cb, + parse_context); } static void -file_read_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +file_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - GFile *file = G_FILE (source_object); - ParseContext *parse_context = user_data; - GFileInputStream *stream; - gs_free_error GError *error = NULL; + GFile * file = G_FILE(source_object); + ParseContext * parse_context = user_data; + GFileInputStream *stream; + gs_free_error GError *error = NULL; - stream = g_file_read_finish (file, res, &error); - if (!stream) { - g_prefix_error (&error, "Error opening service provider database: "); - finish_parse_context (parse_context, error); - return; - } + stream = g_file_read_finish(file, res, &error); + if (!stream) { + g_prefix_error(&error, "Error opening service provider database: "); + finish_parse_context(parse_context, error); + return; + } - read_next_chunk (G_INPUT_STREAM (stream), parse_context); + read_next_chunk(G_INPUT_STREAM(stream), parse_context); - g_object_unref (stream); + g_object_unref(stream); } /*****************************************************************************/ void -nm_service_providers_find_gsm_apn (const char *service_providers, - const char *mccmnc, - GCancellable *cancellable, - NMServiceProvidersGsmApnCallback callback, - gpointer user_data) +nm_service_providers_find_gsm_apn(const char * service_providers, + const char * mccmnc, + GCancellable * cancellable, + NMServiceProvidersGsmApnCallback callback, + gpointer user_data) { - GFile *file; - ParseContext *parse_context; + GFile * file; + ParseContext *parse_context; - parse_context = g_slice_new0 (ParseContext); - parse_context->mccmnc = g_strdup (mccmnc); - parse_context->cancellable = cancellable; - parse_context->callback = callback; - parse_context->user_data = user_data; - parse_context->ctx = g_markup_parse_context_new (&parser, 0, parse_context, NULL); + parse_context = g_slice_new0(ParseContext); + parse_context->mccmnc = g_strdup(mccmnc); + parse_context->cancellable = cancellable; + parse_context->callback = callback; + parse_context->user_data = user_data; + parse_context->ctx = g_markup_parse_context_new(&parser, 0, parse_context, NULL); - file = g_file_new_for_path (service_providers); + file = g_file_new_for_path(service_providers); - g_file_read_async (file, G_PRIORITY_DEFAULT, cancellable, file_read_cb, parse_context); + g_file_read_async(file, G_PRIORITY_DEFAULT, cancellable, file_read_cb, parse_context); - g_object_unref (file); + g_object_unref(file); } diff --git a/src/devices/wwan/nm-service-providers.h b/src/devices/wwan/nm-service-providers.h index 35ad2fc1..093bcd5b 100644 --- a/src/devices/wwan/nm-service-providers.h +++ b/src/devices/wwan/nm-service-providers.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2019 Red Hat, Inc. */ @@ -6,19 +6,19 @@ #ifndef __NETWORKMANAGER_SERVICE_PROVIDERS_H__ #define __NETWORKMANAGER_SERVICE_PROVIDERS_H__ -typedef void (*NMServiceProvidersGsmApnCallback) (const char *apn, - const char *username, - const char *password, - const char *gateway, - const char *auth_method, - const GSList *dns, - GError *error, - gpointer user_data); +typedef void (*NMServiceProvidersGsmApnCallback)(const char * apn, + const char * username, + const char * password, + const char * gateway, + const char * auth_method, + const GSList *dns, + GError * error, + gpointer user_data); -void nm_service_providers_find_gsm_apn (const char *service_providers, - const char *mccmnc, - GCancellable *cancellable, - NMServiceProvidersGsmApnCallback callback, - gpointer user_data); +void nm_service_providers_find_gsm_apn(const char * service_providers, + const char * mccmnc, + GCancellable * cancellable, + NMServiceProvidersGsmApnCallback callback, + gpointer user_data); #endif /* __NETWORKMANAGER_SERVICE_PROVIDERS_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index 9a85f936..1c3406da 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -16,134 +16,131 @@ /*****************************************************************************/ -#define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type ()) -#define NM_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory)) -#define NM_WWAN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass)) -#define NM_IS_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WWAN_FACTORY)) -#define NM_IS_WWAN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WWAN_FACTORY)) -#define NM_WWAN_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass)) +#define NM_TYPE_WWAN_FACTORY (nm_wwan_factory_get_type()) +#define NM_WWAN_FACTORY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactory)) +#define NM_WWAN_FACTORY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass)) +#define NM_IS_WWAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_WWAN_FACTORY)) +#define NM_IS_WWAN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_WWAN_FACTORY)) +#define NM_WWAN_FACTORY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_WWAN_FACTORY, NMWwanFactoryClass)) typedef struct { - NMModemManager *mm; + NMModemManager *mm; } NMWwanFactoryPrivate; typedef struct { - NMDeviceFactory parent; - NMWwanFactoryPrivate _priv; + NMDeviceFactory parent; + NMWwanFactoryPrivate _priv; } NMWwanFactory; typedef struct { - NMDeviceFactoryClass parent; + NMDeviceFactoryClass parent; } NMWwanFactoryClass; -static GType nm_wwan_factory_get_type (void); +static GType nm_wwan_factory_get_type(void); -G_DEFINE_TYPE (NMWwanFactory, nm_wwan_factory, NM_TYPE_DEVICE_FACTORY) +G_DEFINE_TYPE(NMWwanFactory, nm_wwan_factory, NM_TYPE_DEVICE_FACTORY) -#define NM_WWAN_FACTORY_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMWwanFactory, NM_IS_WWAN_FACTORY) +#define NM_WWAN_FACTORY_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMWwanFactory, NM_IS_WWAN_FACTORY) /*****************************************************************************/ -NM_DEVICE_FACTORY_DECLARE_TYPES ( - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WWAN_NET) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME) -) +NM_DEVICE_FACTORY_DECLARE_TYPES(NM_DEVICE_FACTORY_DECLARE_LINK_TYPES( + NM_LINK_TYPE_WWAN_NET) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_GSM_SETTING_NAME, + NM_SETTING_CDMA_SETTING_NAME)) G_MODULE_EXPORT NMDeviceFactory * -nm_device_factory_create (GError **error) + nm_device_factory_create(GError **error) { - return (NMDeviceFactory *) g_object_new (NM_TYPE_WWAN_FACTORY, NULL); + return (NMDeviceFactory *) g_object_new(NM_TYPE_WWAN_FACTORY, NULL); } /*****************************************************************************/ static void -modem_added_cb (NMModemManager *manager, - NMModem *modem, - gpointer user_data) +modem_added_cb(NMModemManager *manager, NMModem *modem, gpointer user_data) { - NMWwanFactory *self = NM_WWAN_FACTORY (user_data); - gs_unref_object NMDevice *device = NULL; - const char *driver; - - if (nm_modem_is_claimed (modem)) - return; - - driver = nm_modem_get_driver (modem); - - /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore - * it. The rfcomm port (and thus the modem) gets created automatically - * by the Bluetooth code during the connection process. - */ - if ( driver - && strstr (driver, "bluetooth")) { - nm_log_dbg (LOGD_MB, "WWAN factory ignores bluetooth modem '%s' which should be handled by bluetooth plugin", - nm_modem_get_control_port (modem)); - return; - } - - /* Make the new modem device */ - device = nm_device_modem_new (modem); - g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); + NMWwanFactory * self = NM_WWAN_FACTORY(user_data); + gs_unref_object NMDevice *device = NULL; + const char * driver; + + if (nm_modem_is_claimed(modem)) + return; + + driver = nm_modem_get_driver(modem); + + /* If it was a Bluetooth modem and no bluetooth device claimed it, ignore + * it. The rfcomm port (and thus the modem) gets created automatically + * by the Bluetooth code during the connection process. + */ + if (driver && strstr(driver, "bluetooth")) { + nm_log_dbg( + LOGD_MB, + "WWAN factory ignores bluetooth modem '%s' which should be handled by bluetooth plugin", + nm_modem_get_control_port(modem)); + return; + } + + /* Make the new modem device */ + device = nm_device_modem_new(modem); + g_signal_emit_by_name(self, NM_DEVICE_FACTORY_DEVICE_ADDED, device); } static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) +create_device(NMDeviceFactory * factory, + const char * iface, + const NMPlatformLink *plink, + NMConnection * connection, + gboolean * out_ignore) { - g_return_val_if_fail (plink, NULL); - g_return_val_if_fail (plink->type == NM_LINK_TYPE_WWAN_NET, NULL); - *out_ignore = TRUE; - return NULL; + g_return_val_if_fail(plink, NULL); + g_return_val_if_fail(plink->type == NM_LINK_TYPE_WWAN_NET, NULL); + *out_ignore = TRUE; + return NULL; } static void -start (NMDeviceFactory *factory) +start(NMDeviceFactory *factory) { - NMWwanFactory *self = NM_WWAN_FACTORY (factory); - NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); + NMWwanFactory * self = NM_WWAN_FACTORY(factory); + NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE(self); - priv->mm = g_object_ref (nm_modem_manager_get ()); + priv->mm = g_object_ref(nm_modem_manager_get()); - g_signal_connect (priv->mm, - NM_MODEM_MANAGER_MODEM_ADDED, - G_CALLBACK (modem_added_cb), - self); + g_signal_connect(priv->mm, NM_MODEM_MANAGER_MODEM_ADDED, G_CALLBACK(modem_added_cb), self); } /*****************************************************************************/ static void -nm_wwan_factory_init (NMWwanFactory *self) -{ -} +nm_wwan_factory_init(NMWwanFactory *self) +{} static void -dispose (GObject *object) +dispose(GObject *object) { - NMWwanFactory *self = NM_WWAN_FACTORY (object); - NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); + NMWwanFactory * self = NM_WWAN_FACTORY(object); + NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE(self); - if (priv->mm) - g_signal_handlers_disconnect_by_func (priv->mm, modem_added_cb, self); - g_clear_object (&priv->mm); + if (priv->mm) + g_signal_handlers_disconnect_by_func(priv->mm, modem_added_cb, self); + g_clear_object(&priv->mm); - /* Chain up to the parent class */ - G_OBJECT_CLASS (nm_wwan_factory_parent_class)->dispose (object); + /* Chain up to the parent class */ + G_OBJECT_CLASS(nm_wwan_factory_parent_class)->dispose(object); } static void -nm_wwan_factory_class_init (NMWwanFactoryClass *klass) +nm_wwan_factory_class_init(NMWwanFactoryClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS(klass); - object_class->dispose = dispose; + object_class->dispose = dispose; - factory_class->get_supported_types = get_supported_types; - factory_class->create_device = create_device; - factory_class->start = start; + factory_class->get_supported_types = get_supported_types; + factory_class->create_device = create_device; + factory_class->start = start; } diff --git a/src/devices/wwan/tests/test-service-providers.c b/src/devices/wwan/tests/test-service-providers.c index 33402cd5..ec19d588 100644 --- a/src/devices/wwan/tests/test-service-providers.c +++ b/src/devices/wwan/tests/test-service-providers.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2019 Red Hat */ @@ -10,115 +10,121 @@ #include "nm-test-utils-core.h" static void -test_positive_cb (const char *apn, - const char *username, - const char *password, - const char *gateway, - const char *auth_method, - const GSList *dns, - GError *error, - gpointer user_data) +test_positive_cb(const char * apn, + const char * username, + const char * password, + const char * gateway, + const char * auth_method, + const GSList *dns, + GError * error, + gpointer user_data) { - GMainLoop *loop = user_data; - - g_main_loop_quit (loop); - g_assert_no_error (error); - g_assert_cmpstr (apn, ==, "gprs.example.com"); - g_assert_cmpstr (username, ==, "praise"); - g_assert_cmpstr (password, ==, "santa"); - g_assert_cmpstr (gateway, ==, "192.0.2.3"); - g_assert_cmpstr (auth_method, ==, "pap"); - - g_assert_nonnull (dns); - g_assert_cmpstr (dns->data, ==, "192.0.2.2"); - dns = dns->next; - g_assert_nonnull (dns); - g_assert_cmpstr (dns->data, ==, "192.0.2.1"); - g_assert_null (dns->next); + GMainLoop *loop = user_data; + + g_main_loop_quit(loop); + g_assert_no_error(error); + g_assert_cmpstr(apn, ==, "gprs.example.com"); + g_assert_cmpstr(username, ==, "praise"); + g_assert_cmpstr(password, ==, "santa"); + g_assert_cmpstr(gateway, ==, "192.0.2.3"); + g_assert_cmpstr(auth_method, ==, "pap"); + + g_assert_nonnull(dns); + g_assert_cmpstr(dns->data, ==, "192.0.2.2"); + dns = dns->next; + g_assert_nonnull(dns); + g_assert_cmpstr(dns->data, ==, "192.0.2.1"); + g_assert_null(dns->next); } static void -test_positive (void) +test_positive(void) { - GMainLoop *loop = g_main_loop_new (NULL, FALSE); - - nm_service_providers_find_gsm_apn (NM_BUILD_SRCDIR"/src/devices/wwan/tests/test-service-providers.xml", - "13337", NULL, test_positive_cb, loop); - g_main_loop_run (loop); - g_main_loop_unref (loop); + GMainLoop *loop = g_main_loop_new(NULL, FALSE); + + nm_service_providers_find_gsm_apn(NM_BUILD_SRCDIR + "/src/devices/wwan/tests/test-service-providers.xml", + "13337", + NULL, + test_positive_cb, + loop); + g_main_loop_run(loop); + g_main_loop_unref(loop); } /*****************************************************************************/ static void -test_negative_cb (const char *apn, - const char *username, - const char *password, - const char *gateway, - const char *auth_method, - const GSList *dns, - GError *error, - gpointer user_data) +test_negative_cb(const char * apn, + const char * username, + const char * password, + const char * gateway, + const char * auth_method, + const GSList *dns, + GError * error, + gpointer user_data) { - GMainLoop *loop = user_data; + GMainLoop *loop = user_data; - g_main_loop_quit (loop); - g_assert_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN); + g_main_loop_quit(loop); + g_assert_error(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN); } static void -test_negative (void) +test_negative(void) { - GMainLoop *loop = g_main_loop_new (NULL, FALSE); - - nm_service_providers_find_gsm_apn (NM_BUILD_SRCDIR"/src/devices/wwan/tests/test-service-providers.xml", - "78130", NULL, test_negative_cb, loop); - g_main_loop_run (loop); - g_main_loop_unref (loop); + GMainLoop *loop = g_main_loop_new(NULL, FALSE); + + nm_service_providers_find_gsm_apn(NM_BUILD_SRCDIR + "/src/devices/wwan/tests/test-service-providers.xml", + "78130", + NULL, + test_negative_cb, + loop); + g_main_loop_run(loop); + g_main_loop_unref(loop); } /*****************************************************************************/ static void -test_nonexistent_cb (const char *apn, - const char *username, - const char *password, - const char *gateway, - const char *auth_method, - const GSList *dns, - GError *error, - gpointer user_data) +test_nonexistent_cb(const char * apn, + const char * username, + const char * password, + const char * gateway, + const char * auth_method, + const GSList *dns, + GError * error, + gpointer user_data) { - GMainLoop *loop = user_data; + GMainLoop *loop = user_data; - g_main_loop_quit (loop); - g_assert_error (error, G_IO_ERROR, G_IO_ERROR_AGAIN); + g_main_loop_quit(loop); + g_assert_error(error, G_IO_ERROR, G_IO_ERROR_AGAIN); } static void -test_nonexistent (void) +test_nonexistent(void) { - GMainLoop *loop = g_main_loop_new (NULL, FALSE); + GMainLoop *loop = g_main_loop_new(NULL, FALSE); - nm_service_providers_find_gsm_apn ("nonexistent.xml", "13337", NULL, - test_nonexistent_cb, loop); - g_main_loop_run (loop); - g_main_loop_unref (loop); + nm_service_providers_find_gsm_apn("nonexistent.xml", "13337", NULL, test_nonexistent_cb, loop); + g_main_loop_run(loop); + g_main_loop_unref(loop); } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) +main(int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); - g_test_add_func ("/service-providers/positive", test_positive); - g_test_add_func ("/service-providers/negative", test_negative); - g_test_add_func ("/service-providers/nonexistent", test_nonexistent); + g_test_add_func("/service-providers/positive", test_positive); + g_test_add_func("/service-providers/negative", test_negative); + g_test_add_func("/service-providers/nonexistent", test_nonexistent); - return g_test_run (); + return g_test_run(); } - -- cgit 1.3.0-6-gf8a5 From f2ddac4cbc895837ddcc55015fae112f9859cd0a Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Tue, 20 Oct 2020 22:07:24 +0200 Subject: New upstream version 1.27.91 --- src/devices/wifi/nm-device-iwd.c | 44 +++++++++++++------------------ src/devices/wifi/nm-iwd-manager.c | 52 +++++++++++++++++++++++++------------ src/devices/wifi/nm-wifi-p2p-peer.c | 15 ++++++++--- 3 files changed, 65 insertions(+), 46 deletions(-) (limited to 'src/devices') diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index fb113f83..64ac3de7 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1952,36 +1952,39 @@ schedule_periodic_scan(NMDeviceIwd *self, gboolean initial_scan) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE(self); GVariant * value; - gboolean disconnected; + gboolean disconnected = TRUE; guint interval; - if (!priv->can_scan || priv->scan_requested) - return; - - value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State"); - disconnected = nm_streq0(get_variant_state(value), "disconnected"); - g_variant_unref(value); + if (priv->can_scan) { + value = g_dbus_proxy_get_cached_property(priv->dbus_station_proxy, "State"); + disconnected = nm_streq0(get_variant_state(value), "disconnected"); + g_variant_unref(value); + } /* Start scan immediately after a disconnect, mode change or - * device UP, otherwise wait a period dependent on the current - * state. + * device UP, otherwise wait 10 seconds. When connected, update + * AP list mainly on UI requests. * * (initial_scan && disconnected) override priv->scanning below * because of an IWD quirk where a device will often be in the * autoconnect state and scanning at the time of our initial_scan, - * but our logic will the send it a Disconnect() causing IWD to + * but our logic will then send it a Disconnect() causing IWD to * exit autoconnect and interrupt the ongoing scan, meaning that * we still want a new scan ASAP. */ - if (initial_scan && disconnected) + if (!priv->can_scan || !disconnected || priv->scan_requested || priv->scanning) + interval = -1; + else if (initial_scan) interval = 0; - else if (!priv->periodic_scan_id && !priv->scanning) - interval = disconnected ? 10 : 20; + else if (!priv->periodic_scan_id) + interval = 10; else return; nm_clear_g_source(&priv->periodic_scan_id); - priv->periodic_scan_id = g_timeout_add_seconds(interval, periodic_scan_timeout_cb, self); + + if (interval != (guint) -1) + priv->periodic_scan_id = g_timeout_add_seconds(interval, periodic_scan_timeout_cb, self); } static void @@ -2384,7 +2387,6 @@ powered_changed(NMDeviceIwd *self, gboolean new_powered) update_aps(self); } else { set_can_scan(self, FALSE); - nm_clear_g_source(&priv->periodic_scan_id); priv->scanning = FALSE; priv->scan_requested = FALSE; priv->can_connect = FALSE; @@ -2600,17 +2602,7 @@ dispose(GObject *object) nm_clear_g_cancellable(&priv->cancellable); - nm_clear_g_source(&priv->periodic_scan_id); - - cleanup_association_attempt(self, TRUE); - - g_clear_object(&priv->dbus_device_proxy); - g_clear_object(&priv->dbus_station_proxy); - g_clear_object(&priv->dbus_ap_proxy); - g_clear_object(&priv->dbus_adhoc_proxy); - g_clear_object(&priv->dbus_obj); - - remove_all_aps(self); + nm_device_iwd_set_dbus_object(self, NULL); G_OBJECT_CLASS(nm_device_iwd_parent_class)->dispose(object); diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index bdff20ac..6a562014 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -631,6 +631,38 @@ interface_removed(GDBusObjectManager *object_manager, } } +static void +object_added(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + GList *interfaces, *iter; + + interfaces = g_dbus_object_get_interfaces(object); + + for (iter = interfaces; iter; iter = iter->next) { + GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); + + interface_added(NULL, object, interface, user_data); + } + + g_list_free_full(interfaces, g_object_unref); +} + +static void +object_removed(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + GList *interfaces, *iter; + + interfaces = g_dbus_object_get_interfaces(object); + + for (iter = interfaces; iter; iter = iter->next) { + GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); + + interface_removed(NULL, object, interface, user_data); + } + + g_list_free_full(interfaces, g_object_unref); +} + static void connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) { @@ -696,22 +728,6 @@ _om_has_name_owner(GDBusObjectManager *object_manager) return !!name_owner; } -static void -object_added(NMIwdManager *self, GDBusObject *object) -{ - GList *interfaces, *iter; - - interfaces = g_dbus_object_get_interfaces(object); - - for (iter = interfaces; iter; iter = iter->next) { - GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); - - interface_added(NULL, object, interface, self); - } - - g_list_free_full(interfaces, g_object_unref); -} - static void release_object_manager(NMIwdManager *self) { @@ -852,12 +868,14 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) "interface-removed", G_CALLBACK(interface_removed), self); + g_signal_connect(priv->object_manager, "object-added", G_CALLBACK(object_added), self); + g_signal_connect(priv->object_manager, "object-removed", G_CALLBACK(object_removed), self); g_hash_table_remove_all(priv->known_networks); objects = g_dbus_object_manager_get_objects(object_manager); for (iter = objects; iter; iter = iter->next) - object_added(self, G_DBUS_OBJECT(iter->data)); + object_added(NULL, G_DBUS_OBJECT(iter->data), self); g_list_free_full(objects, g_object_unref); diff --git a/src/devices/wifi/nm-wifi-p2p-peer.c b/src/devices/wifi/nm-wifi-p2p-peer.c index fe6ad0a0..a194f168 100644 --- a/src/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/devices/wifi/nm-wifi-p2p-peer.c @@ -47,7 +47,8 @@ struct _NMWifiP2PPeerPrivate { char *address; GBytes *wfd_ies; - char ** groups; + + const char **groups; guint8 strength; @@ -281,7 +282,7 @@ nm_wifi_p2p_peer_get_groups(const NMWifiP2PPeer *peer) { g_return_val_if_fail(NM_IS_WIFI_P2P_PEER(peer), NULL); - return (const char *const *) NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->groups; + return NM_WIFI_P2P_PEER_GET_PRIVATE(peer)->groups; } const char * @@ -404,6 +405,14 @@ nm_wifi_p2p_peer_update_from_properties(NMWifiP2PPeer *peer, const NMSupplicantP changed |= nm_wifi_p2p_peer_set_wfd_ies(peer, peer_info->ies); changed |= nm_wifi_p2p_peer_set_last_seen(peer, peer_info->last_seen_msec / 1000u); + /* We currently only use the groups information internally to check if + * the peer is still joined. */ + if (!_nm_utils_strv_equal((char **) priv->groups, (char **) peer_info->groups)) { + g_free(priv->groups); + priv->groups = nm_utils_strv_dup_packed(peer_info->groups, -1); + changed |= TRUE; + } + g_object_thaw_notify(G_OBJECT(peer)); return changed; @@ -566,7 +575,7 @@ finalize(GObject *object) g_free(priv->serial); g_free(priv->address); g_bytes_unref(priv->wfd_ies); - g_strfreev(priv->groups); + g_free(priv->groups); G_OBJECT_CLASS(nm_wifi_p2p_peer_parent_class)->finalize(object); } -- cgit 1.3.0-6-gf8a5 From 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sun, 6 Dec 2020 21:57:59 +0100 Subject: New upstream version 1.28.0 --- src/devices/nm-device-bridge.c | 14 ++++++++++ src/devices/nm-device.c | 16 +++++++++++ src/devices/nm-device.h | 11 ++++++++ src/devices/ovs/nm-ovsdb.c | 50 ++++++++++++++++++++++++----------- src/devices/wifi/nm-device-wifi.c | 10 +++---- src/devices/wifi/nm-iwd-manager.c | 5 ++-- src/devices/wifi/nm-wifi-ap.c | 18 ++++++++----- src/devices/wwan/nm-modem-broadband.c | 7 +++-- 8 files changed, 100 insertions(+), 31 deletions(-) (limited to 'src/devices') diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 3c27b349..48dcec1b 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -1027,6 +1027,7 @@ create_and_realize(NMDevice * device, const NMPlatformLink **out_plink, GError ** error) { + NMSettingWired * s_wired; NMSettingBridge * s_bridge; const char * iface = nm_device_get_iface(device); const char * hwaddr; @@ -1034,12 +1035,17 @@ create_and_realize(NMDevice * device, guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; NMPlatformLnkBridge props; int r; + guint32 mtu = 0; nm_assert(iface); s_bridge = nm_connection_get_setting_bridge(connection); nm_assert(s_bridge); + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + mtu = nm_setting_wired_get_mtu(s_wired); + hwaddr = nm_setting_bridge_get_mac_address(s_bridge); if (!hwaddr && nm_device_hw_addr_get_cloned(device, connection, FALSE, &hwaddr_cloned, NULL, NULL)) { @@ -1097,10 +1103,17 @@ create_and_realize(NMDevice * device, to_sysfs_group_address_sys(nm_setting_bridge_get_group_address(s_bridge), &props.group_addr); + /* If mtu != 0, we set the MTU of the new bridge at creation time. However, kernel will still + * automatically adjust the MTU of the bridge based on the minimum of the slave's MTU. + * We don't want this automatism as the user asked for a fixed MTU. + * + * To workaround this behavior of kernel, we will later toggle the MTU twice. See + * NMDeviceClass.mtu_force_set. */ r = nm_platform_link_bridge_add(nm_device_get_platform(device), iface, hwaddr ? mac_address : NULL, hwaddr ? ETH_ALEN : 0, + mtu, &props, out_plink); if (r < 0) { @@ -1152,6 +1165,7 @@ nm_device_bridge_class_init(NMDeviceBridgeClass *klass) device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BRIDGE); device_class->is_master = TRUE; + device_class->mtu_force_set = TRUE; device_class->get_generic_capabilities = get_generic_capabilities; device_class->check_connection_compatible = check_connection_compatible; device_class->check_connection_available = check_connection_available; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2dab5075..0be05f23 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -659,6 +659,8 @@ typedef struct _NMDevicePrivate { guint64 tx_bytes; guint64 rx_bytes; } stats; + + bool mtu_force_set_done : 1; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -10433,6 +10435,18 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) } } + if (mtu_desired && NM_DEVICE_GET_CLASS(self)->mtu_force_set && !priv->mtu_force_set_done) { + priv->mtu_force_set_done = TRUE; + + if (mtu_desired == mtu_plat) { + mtu_plat--; + if (NM_DEVICE_GET_CLASS(self)->set_platform_mtu(self, mtu_desired - 1)) { + _LOGD(LOGD_DEVICE, "mtu: force-set MTU to %u", mtu_desired - 1); + } else + _LOGW(LOGD_DEVICE, "mtu: failure to force-set MTU to %u", mtu_desired - 1); + } + } + _LOGT(LOGD_DEVICE, "mtu: device-mtu: %u%s, ipv6-mtu: %u%s, ifindex: %d", (guint) mtu_desired, @@ -15773,6 +15787,8 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type) priv->linklocal6_dad_counter = 0; + priv->mtu_force_set_done = FALSE; + /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 13782417..3eae9318 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -232,6 +232,17 @@ typedef struct _NMDeviceClass { * type (NMDeviceClass), not the actual device instance. */ bool is_master : 1; + /* Force setting the MTU actually means first setting the MTU + * to (desired_MTU-1) and then setting the desired_MTU + * so that kernel actually applies the MTU, otherwise + * kernel will ignore the request if the link's MTU is the + * same as the desired one. + * + * This is just a workaround made for bridges (ATM) that employ + * a auto-MTU adjust mechanism if no MTU is manually set. + */ + bool mtu_force_set : 1; + void (*state_changed)(NMDevice * device, NMDeviceState new_state, NMDeviceState old_state, diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c index 9826c1b7..27ef789f 100644 --- a/src/devices/ovs/nm-ovsdb.c +++ b/src/devices/ovs/nm-ovsdb.c @@ -707,7 +707,7 @@ _add_interface(NMOvsdb * self, nm_auto_decref_json json_t *interfaces = NULL; nm_auto_decref_json json_t *new_interfaces = NULL; gboolean has_interface = FALSE; - gboolean interface_is_internal; + gboolean interface_is_local; gs_free char * bridge_cloned_mac = NULL; gs_free char * interface_cloned_mac = NULL; GError * error = NULL; @@ -721,10 +721,10 @@ _add_interface(NMOvsdb * self, new_ports = json_array(); new_interfaces = json_array(); - bridge_name = nm_connection_get_interface_name(bridge); - port_name = nm_connection_get_interface_name(port); - interface_name = nm_connection_get_interface_name(interface); - interface_is_internal = nm_streq0(bridge_name, interface_name); + bridge_name = nm_connection_get_interface_name(bridge); + port_name = nm_connection_get_interface_name(port); + interface_name = nm_connection_get_interface_name(interface); + interface_is_local = nm_streq0(bridge_name, interface_name); /* Determine cloned MAC addresses */ if (!nm_device_hw_addr_get_cloned(bridge_device, @@ -733,7 +733,7 @@ _add_interface(NMOvsdb * self, &bridge_cloned_mac, NULL, &error)) { - _LOGW("Cannot determine cloned mac for OVS %s '%s': %s", + _LOGW("Cannot determine cloned MAC for OVS %s '%s': %s", "bridge", bridge_name, error->message); @@ -746,18 +746,34 @@ _add_interface(NMOvsdb * self, &interface_cloned_mac, NULL, &error)) { - _LOGW("Cannot determine cloned mac for OVS %s '%s': %s", + _LOGW("Cannot determine cloned MAC for OVS %s '%s': %s", "interface", interface_name, error->message); g_clear_error(&error); } - if (interface_is_internal && !bridge_cloned_mac && interface_cloned_mac) { - _LOGT("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'", - interface_name, - bridge_name); - bridge_cloned_mac = g_steal_pointer(&interface_cloned_mac); + /* For local interfaces, ovs complains if it finds a + * MAC address in the Interface table because it only takes + * the MAC from the Bridge table. + * Set any cloned MAC present in a local interface connection + * into the Bridge table, unless conflicting with the bridge MAC. */ + if (interface_is_local && interface_cloned_mac) { + if (bridge_cloned_mac && !nm_streq(interface_cloned_mac, bridge_cloned_mac)) { + _LOGW("Cloned MAC '%s' of local ovs-interface '%s' conflicts with MAC '%s' of bridge " + "'%s'", + interface_cloned_mac, + interface_name, + bridge_cloned_mac, + bridge_name); + nm_clear_g_free(&interface_cloned_mac); + } else { + nm_clear_g_free(&bridge_cloned_mac); + bridge_cloned_mac = g_steal_pointer(&interface_cloned_mac); + _LOGT("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'", + interface_name, + bridge_name); + } } g_hash_table_iter_init(&iter, priv->bridges); @@ -823,7 +839,7 @@ _add_interface(NMOvsdb * self, g_return_if_fail(ovs_bridge); _expect_bridge_ports(params, ovs_bridge->name, ports); _set_bridge_ports(params, bridge_name, new_ports); - if (bridge_cloned_mac && interface_is_internal) + if (bridge_cloned_mac && interface_is_local) _set_bridge_mac(params, bridge_name, bridge_cloned_mac); } @@ -1175,8 +1191,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) } if (ovs) { - iter = json_object_iter(ovs); - priv->db_uuid = iter ? g_strdup(json_object_iter_key(iter)) : NULL; + const char *s; + + iter = json_object_iter(ovs); + s = json_object_iter_key(iter); + if (s) + nm_utils_strdup_reset(&priv->db_uuid, s); } /* Interfaces */ diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 55062644..980916dd 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1390,11 +1390,11 @@ _hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset) * a new one.*/ priv->hw_addr_scan_expire = now + SCAN_RAND_MAC_ADDRESS_EXPIRE_SEC; - generate_mac_address_mask = - nm_config_data_get_device_config(NM_CONFIG_GET_DATA, - "wifi.scan-generate-mac-address-mask", - device, - NULL); + generate_mac_address_mask = nm_config_data_get_device_config( + NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK, + device, + NULL); priv->scan_last_request_started_at_msec = G_MININT64; priv->scan_periodic_next_msec = 0; diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 6a562014..c7e99e0b 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -673,15 +673,16 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint gboolean mapped; KnownNetworkData * data; KnownNetworkId id; + gs_free char * ssid_str = NULL; id.security = nm_wifi_connection_get_iwd_security(conn, &mapped); if (!mapped) return; s_wireless = nm_connection_get_setting_wireless(conn); - id.name = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless)); + ssid_str = _nm_utils_ssid_to_utf8(nm_setting_wireless_get_ssid(s_wireless)); + id.name = ssid_str; data = g_hash_table_lookup(priv->known_networks, &id); - g_free((char *) id.name); if (!data) return; diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index fe26421d..55438a53 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -113,22 +113,26 @@ nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid) g_return_val_if_fail(NM_IS_WIFI_AP(ap), FALSE); - if (ssid) { - l = g_bytes_get_size(ssid); - if (l == 0 || l > 32) - g_return_val_if_reached(FALSE); + if (!ssid) { + /* we don't clear the SSID, once we have it. We can only update + * it by a better value. */ + return FALSE; } + l = g_bytes_get_size(ssid); + if (l == 0 || l > 32) + g_return_val_if_reached(FALSE); + priv = NM_WIFI_AP_GET_PRIVATE(ap); if (ssid == priv->ssid) return FALSE; - if (ssid && priv->ssid && g_bytes_equal(ssid, priv->ssid)) + if (priv->ssid && g_bytes_equal(ssid, priv->ssid)) return FALSE; + g_bytes_ref(ssid); nm_clear_pointer(&priv->ssid, g_bytes_unref); - if (ssid) - priv->ssid = g_bytes_ref(ssid); + priv->ssid = ssid; _notify(ap, PROP_SSID); return TRUE; diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 633878ce..7b3a13a3 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -39,8 +39,11 @@ MODEM_CAPS_3GPP(MMModemCapability caps) #define MODEM_CAPS_3GPP2(caps) (caps & (MM_MODEM_CAPABILITY_CDMA_EVDO)) -/* Maximum time to keep the DBus call waiting for a connection result */ -#define MODEM_CONNECT_TIMEOUT_SECS 120 +/* Maximum time to keep the DBus call waiting for a connection result. + * This value is greater than the default timeout in ModemManager (180s since + * 1.16), so that whenever possible the timeout happens first there instead of + * in NetworkManager. */ +#define MODEM_CONNECT_TIMEOUT_SECS 200 /*****************************************************************************/ -- cgit 1.3.0-6-gf8a5