diff options
| author | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-10-01 23:05:04 +0200 |
| commit | e74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch) | |
| tree | 3469f17ea9af91f7ff169b890633bda68b0cf76e /src/core/devices | |
| parent | bfe522304da217296e2a61040f58e35ec5d6f3f2 (diff) | |
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'src/core/devices')
68 files changed, 3499 insertions, 1749 deletions
diff --git a/src/core/devices/adsl/meson.build b/src/core/devices/adsl/meson.build index 95f61d95..ef87c6e8 100644 --- a/src/core/devices/adsl/meson.build +++ b/src/core/devices/adsl/meson.build @@ -7,7 +7,6 @@ libnm_device_plugin_adsl = shared_module( 'nm-device-adsl.c', ), dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/adsl/nm-atm-manager.c b/src/core/devices/adsl/nm-atm-manager.c index 9be9b5ce..bd9ed8cc 100644 --- a/src/core/devices/adsl/nm-atm-manager.c +++ b/src/core/devices/adsl/nm-atm-manager.c @@ -11,8 +11,8 @@ #include "nm-setting-adsl.h" #include "nm-device-adsl.h" #include "devices/nm-device-factory.h" -#include "platform/nm-platform.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-udev-aux/nm-udev-utils.h" /*****************************************************************************/ diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c index 34c062a8..4e4c9dcc 100644 --- a/src/core/devices/adsl/nm-device-adsl.c +++ b/src/core/devices/adsl/nm-device-adsl.c @@ -17,7 +17,7 @@ #include "nm-ip4-config.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" #include "nm-setting-adsl.h" @@ -265,7 +265,7 @@ pppoe_vcc_config(NMDeviceAdsl *self) _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); + nm_platform_link_change_flags(nm_device_get_platform(device), priv->nas_ifindex, IFF_UP, TRUE); return TRUE; } @@ -674,12 +674,8 @@ dispose(GObject *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/bluetooth/meson.build b/src/core/devices/bluetooth/meson.build index d5f26068..5b196d08 100644 --- a/src/core/devices/bluetooth/meson.build +++ b/src/core/devices/bluetooth/meson.build @@ -8,11 +8,11 @@ libnm_device_plugin_bluetooth_static = static_library( 'nm-device-bt.c', ) + (enable_bluez5_dun ? files('nm-bluez5-dun.c') : files()), dependencies: [ + libnm_core_public_dep, core_default_dep, libnm_wwan_dep, bluez5_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_bluetooth_static_dep = declare_dependency( diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index 459ea409..fc081580 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -12,8 +12,9 @@ #include <gmodule.h> #include <linux/if_ether.h> -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-manager.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-bridge.h" @@ -23,9 +24,9 @@ #include "nm-device-bt.h" #include "nm-manager.h" #include "nm-bluez5-dun.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-std-aux/nm-dbus-compat.h" /*****************************************************************************/ @@ -574,11 +575,12 @@ _bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) #define _LOG_bzobj(bzobj, context) \ G_STMT_START \ { \ - const BzDBusObj *const _bzobj = (bzobj); \ + const BzDBusObj *const _bzobj = (bzobj); \ + const char *const _context = (context); \ char _buf[500]; \ \ _LOGT("change %-21s %s : { %s }", \ - (context), \ + _context, \ _bzobj->object_path, \ _bzobj_to_string(_bzobj, _buf, sizeof(_buf))); \ } \ @@ -1321,7 +1323,7 @@ _conn_create_panu_connection(NMBluezManager *self, BzDBusObj *bzobj) char uuid[37]; gs_free_error GError *error = NULL; - nm_utils_uuid_generate_buf(uuid); + nm_uuid_generate_random_str_arr(uuid); id = g_strdup_printf(_("%s Network"), bzobj->d_device.name); connection = nm_simple_connection_new(); diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index c07be2d3..8f4ceba7 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -10,7 +10,7 @@ #include <stdio.h> #include <linux/if_ether.h> -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-manager.h" #include "devices/nm-device-private.h" @@ -26,7 +26,7 @@ #include "nm-utils.h" #include "nm-bt-error.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "devices/wwan/nm-modem-manager.h" #include "devices/wwan/nm-modem.h" @@ -1317,16 +1317,12 @@ finalize(GObject *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Name", "s", NM_DEVICE_BT_NAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("BtCapabilities", + "u", + NM_DEVICE_BT_CAPABILITIES), ), ), }; static void diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c index 81a28797..145947bb 100644 --- a/src/core/devices/nm-acd-manager.c +++ b/src/core/devices/nm-acd-manager.c @@ -12,7 +12,7 @@ #include <sys/wait.h> #include <linux/if_ether.h> -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" #include "n-acd/src/n-acd.h" diff --git a/src/core/devices/nm-device-6lowpan.c b/src/core/devices/nm-device-6lowpan.c index fe116dd4..96218658 100644 --- a/src/core/devices/nm-device-6lowpan.c +++ b/src/core/devices/nm-device-6lowpan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "settings/nm-settings.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-6lowpan.h" #include "nm-utils.h" diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index 9c1c484f..b208e2c0 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-ip4-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceBond @@ -601,16 +601,10 @@ nm_device_bond_init(NMDeviceBond *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index c919d85d..a095dc3e 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceBridge #include "nm-device-logging.h" @@ -1033,7 +1033,7 @@ create_and_realize(NMDevice * device, 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]; + guint8 mac_address[_NM_UTILS_HWADDR_LEN_MAX]; NMPlatformLnkBridge props; int r; guint32 mtu = 0; @@ -1142,16 +1142,10 @@ nm_device_bridge_init(NMDeviceBridge *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c index 13cfd3b0..488f0ba0 100644 --- a/src/core/devices/nm-device-dummy.c +++ b/src/core/devices/nm-device-dummy.c @@ -13,10 +13,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-dummy.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceDummy #include "nm-device-logging.h" @@ -121,12 +121,10 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; static void diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 59f6c613..95336c7a 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -14,6 +14,7 @@ #include <libudev.h> #include <linux/if_ether.h> +#include "libnm-glib-aux/nm-uuid.h" #include "nm-device-private.h" #include "nm-act-request.h" #include "nm-ip4-config.h" @@ -24,17 +25,17 @@ #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "nm-dcb.h" #include "settings/nm-settings-connection.h" #include "nm-config.h" #include "nm-device-ethernet-utils.h" #include "settings/nm-settings.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-udev-aux/nm-udev-utils.h" #include "nm-device-veth.h" #define _NMLOG_DEVICE_TYPE NMDeviceEthernet @@ -922,31 +923,33 @@ link_negotiation_set(NMDevice *device) 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)", + "set-link: configure %snegotiation (%u Mbit, %s duplex)", 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 ? "" : "*"); + speed, + nm_platform_link_duplex_type_to_string(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 (link_autoneg) { + /* with autoneg, we only support advertising one speed/duplex. Likewise + * our nm_platform_ethtool_get_link_settings() can only return the current + * speed/duplex, but not all the modes that we were advertising. + * + * Do the best we can do: remember to re-enable autoneg, but don't restrict + * the mode. */ + priv->ethtool_prev_speed = 0; + priv->ethtool_prev_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN; + } else { + priv->ethtool_prev_speed = link_speed; + priv->ethtool_prev_duplex = link_duplex; + } + priv->ethtool_prev_set = TRUE; } if (!nm_platform_ethtool_set_link_settings(nm_device_get_platform(device), @@ -1718,11 +1721,11 @@ new_default_connection(NMDevice *self) /* 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); + uuid = nm_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, @@ -1747,7 +1750,7 @@ new_default_connection(NMDevice *self) if (dev) uprop = udev_device_get_property_value(dev, "NM_AUTO_DEFAULT_LINK_LOCAL_ONLY"); - if (nm_udev_utils_property_as_boolean(uprop)) { + if (_nm_utils_ascii_str_to_bool(uprop, FALSE)) { setting = nm_setting_ip4_config_new(); g_object_set(setting, NM_SETTING_IP_CONFIG_METHOD, @@ -1786,7 +1789,8 @@ update_connection(NMDevice *device, NMConnection *connection) const char * mac = nm_device_get_hw_address(device); const char * mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GHashTableIter iter; - gpointer key, value; + const char * key; + const char * value; if (!s_wired) { s_wired = (NMSettingWired *) nm_setting_wired_new(); @@ -1824,8 +1828,8 @@ update_connection(NMDevice *device, NMConnection *connection) _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); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_setting_wired_add_s390_option(s_wired, key, value); } static void @@ -2000,24 +2004,16 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Speed", "u", NM_DEVICE_ETHERNET_SPEED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("S390Subchannels", + "as", + NM_DEVICE_ETHERNET_S390_SUBCHANNELS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 81124a8d..bdc64135 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -11,9 +11,9 @@ #include <sys/stat.h> #include <gmodule.h> -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-setting-bluetooth.h" #define PLUGIN_PREFIX "libnm-device-plugin-" diff --git a/src/core/devices/nm-device-generic.c b/src/core/devices/nm-device-generic.c index a319666a..08ea5ac5 100644 --- a/src/core/devices/nm-device-generic.c +++ b/src/core/devices/nm-device-generic.c @@ -8,8 +8,8 @@ #include "nm-device-generic.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ @@ -191,16 +191,12 @@ dispose(GObject *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( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE( "TypeDescription", "s", NM_DEVICE_GENERIC_TYPE_DESCRIPTION), ), ), - .legacy_property_changed = TRUE, }; static void diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c index f54ffcf0..37065bc8 100644 --- a/src/core/devices/nm-device-infiniband.c +++ b/src/core/devices/nm-device-infiniband.c @@ -14,9 +14,9 @@ #include "nm-device-private.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition" @@ -366,15 +366,9 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c index da6afb3b..c55dd9f6 100644 --- a/src/core/devices/nm-device-ip-tunnel.c +++ b/src/core/devices/nm-device-ip-tunnel.c @@ -16,9 +16,9 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" @@ -1050,39 +1050,33 @@ dispose(GObject *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Local", "s", NM_DEVICE_IP_TUNNEL_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Remote", + "s", + NM_DEVICE_IP_TUNNEL_REMOTE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PathMtuDiscovery", + "b", + NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InputKey", + "s", + NM_DEVICE_IP_TUNNEL_INPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("OutputKey", + "s", + NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("EncapsulationLimit", + "y", + NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FlowLabel", + "u", + NM_DEVICE_IP_TUNNEL_FLOW_LABEL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", + "u", + NM_DEVICE_IP_TUNNEL_FLAGS), ), ), }; static void diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c index 51b820a1..51b7225b 100644 --- a/src/core/devices/nm-device-macsec.c +++ b/src/core/devices/nm-device-macsec.c @@ -11,11 +11,11 @@ #include "nm-act-request.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" #include "nm-setting-macsec.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "supplicant/nm-supplicant-manager.h" #include "supplicant/nm-supplicant-interface.h" #include "supplicant/nm-supplicant-config.h" @@ -870,40 +870,36 @@ dispose(GObject *object) 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Sci", "t", NM_DEVICE_MACSEC_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IcvLength", + "y", + NM_DEVICE_MACSEC_ICV_LENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("CipherSuite", + "t", + NM_DEVICE_MACSEC_CIPHER_SUITE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Window", "u", NM_DEVICE_MACSEC_WINDOW), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("EncodingSa", + "y", + NM_DEVICE_MACSEC_ENCODING_SA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Validation", + "s", + NM_DEVICE_MACSEC_VALIDATION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Encrypt", + "b", + NM_DEVICE_MACSEC_ENCRYPT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Protect", + "b", + NM_DEVICE_MACSEC_PROTECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IncludeSci", + "b", + NM_DEVICE_MACSEC_INCLUDE_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Es", "b", NM_DEVICE_MACSEC_ES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Scb", "b", NM_DEVICE_MACSEC_SCB), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ReplayProtect", + "b", + NM_DEVICE_MACSEC_REPLAY_PROTECT), ), ), }; static void diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c index e8b39ed6..7302ecdf 100644 --- a/src/core/devices/nm-device-macvlan.c +++ b/src/core/devices/nm-device-macvlan.c @@ -13,7 +13,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-macvlan.h" #include "nm-setting-wired.h" @@ -502,17 +502,13 @@ dispose(GObject *object) 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "s", NM_DEVICE_MACVLAN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NoPromisc", + "b", + NM_DEVICE_MACVLAN_NO_PROMISC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tab", "b", NM_DEVICE_MACVLAN_TAP), ), ), }; static void diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 4040f2d3..8df245bb 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -13,7 +13,7 @@ #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-pppoe.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" @@ -274,10 +274,7 @@ dispose(GObject *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, ), }; static void diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index 8675a699..eb37b14f 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -17,14 +17,6 @@ typedef enum { 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, -} NMDeviceIPState; - enum NMActStageReturn { NM_ACT_STAGE_RETURN_FAILURE = 0, /* Hard failure of activation */ NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */ @@ -117,8 +109,6 @@ nm_device_activate_ip6_state_done(NMDevice *self) 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); - gboolean nm_device_dhcp4_renew(NMDevice *device, gboolean release); gboolean nm_device_dhcp6_renew(NMDevice *device, gboolean release); diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index edca69e9..ebccddfc 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -14,10 +14,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceTun #include "nm-device-logging.h" @@ -444,22 +444,18 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Owner", "x", NM_DEVICE_TUN_OWNER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Group", "x", NM_DEVICE_TUN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "s", NM_DEVICE_TUN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NoPi", "b", NM_DEVICE_TUN_NO_PI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("VnetHdr", "b", NM_DEVICE_TUN_VNET_HDR), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("MultiQueue", + "b", + NM_DEVICE_TUN_MULTI_QUEUE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; static void diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c new file mode 100644 index 00000000..f40ca570 --- /dev/null +++ b/src/core/devices/nm-device-utils.c @@ -0,0 +1,356 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "src/core/nm-default-daemon.h" +#include "src/core/dns/nm-dns-manager.h" +#include "src/core/dns/nm-dns-systemd-resolved.h" + +#include "nm-device-utils.h" +#include "nm-core-utils.h" + +/*****************************************************************************/ + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_device_state_queued_state_to_str, + 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 nm_device_state_queued_state_to_str(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"), ); + +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_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_UTILS_LOOKUP_STR_DEFINE(nm_device_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"), ); + +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_str, + 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"), ); + +/*****************************************************************************/ + +#define SD_RESOLVED_DNS (1UL << 0) +/* Don't answer request from locally synthesized records (which includes /etc/hosts) */ +#define SD_RESOLVED_NO_SYNTHESIZE (1UL << 11) + +typedef struct { + int addr_family; + NMIPAddr address; + gulong cancellable_id; + GTask * task; + NMDnsSystemdResolvedResolveHandle *resolved_handle; +} ResolveAddrInfo; + +#define _NMLOG_PREFIX_NAME "resolve-addr" +#define _NMLOG_DOMAIN LOGD_CORE +#define _NMLOG2(level, info, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + ResolveAddrInfo *_info = (info); \ + char _addr_str[NM_UTILS_INET_ADDRSTRLEN]; \ + \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + _NMLOG_PREFIX_NAME "[" NM_HASH_OBFUSCATE_PTR_FMT \ + ",%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR(_info), \ + nm_utils_inet_ntop(_info->addr_family, &_info->address, _addr_str) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +static void +resolve_addr_info_free(ResolveAddrInfo *info) +{ + nm_assert(info->cancellable_id == 0); + nm_assert(!info->resolved_handle); + g_object_unref(info->task); + g_free(info); +} + +static void +resolve_addr_complete(ResolveAddrInfo *info, char *hostname_take, GError *error_take) +{ + nm_assert(!!hostname_take != !!error_take); + + nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id); + if (error_take) + g_task_return_error(info->task, error_take); + else + g_task_return_pointer(info->task, hostname_take, g_free); + + resolve_addr_info_free(info); +} + +static void +resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + gs_free_error GError *error = NULL; + gs_free char * output = NULL; + + output = nm_utils_spawn_helper_finish(result, &error); + if (nm_utils_error_is_cancelled(error)) + return; + + _LOG2D(info, "helper returned hostname '%s'", output); + + resolve_addr_complete(info, g_steal_pointer(&output), g_steal_pointer(&error)); +} + +static void +resolve_addr_spawn_helper(ResolveAddrInfo *info) +{ + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + + nm_utils_inet_ntop(info->addr_family, &info->address, addr_str); + _LOG2D(info, "start lookup via nm-daemon-helper"); + nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str), + g_task_get_cancellable(info->task), + resolve_addr_helper_cb, + info); +} + +static void +resolve_addr_resolved_cb(NMDnsSystemdResolved * resolved, + NMDnsSystemdResolvedResolveHandle * handle, + const NMDnsSystemdResolvedAddressResult *names, + guint names_len, + guint64 flags, + GError * error, + gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + + info->resolved_handle = NULL; + + if (nm_utils_error_is_cancelled(error)) + return; + + if (error) { + gs_free char *dbus_error = NULL; + + _LOG2D(info, "error resolving via systemd-resolved: %s", error->message); + + dbus_error = g_dbus_error_get_remote_error(error); + if (nm_streq0(dbus_error, "org.freedesktop.resolve1.DnsError.NXDOMAIN")) { + resolve_addr_complete(info, NULL, g_error_copy(error)); + return; + } + + resolve_addr_spawn_helper(info); + return; + } + + if (names_len == 0) { + _LOG2D(info, "systemd-resolved returned no result"); + resolve_addr_complete(info, g_strdup(""), NULL); + return; + } + + _LOG2D(info, "systemd-resolved returned hostname '%s'", names[0].name); + resolve_addr_complete(info, g_strdup(names[0].name), NULL); +} + +static void +resolve_addr_cancelled(GObject *object, gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + GError * error = NULL; + + nm_clear_g_signal_handler(g_task_get_cancellable(info->task), &info->cancellable_id); + nm_clear_pointer(&info->resolved_handle, nm_dns_systemd_resolved_resolve_cancel); + nm_utils_error_set_cancelled(&error, FALSE, NULL); + resolve_addr_complete(info, NULL, error); +} + +void +nm_device_resolve_address(int addr_family, + gconstpointer address, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer cb_data) +{ + ResolveAddrInfo * info; + NMDnsSystemdResolved *resolved; + + info = g_new(ResolveAddrInfo, 1); + *info = (ResolveAddrInfo){ + .task = nm_g_task_new(NULL, cancellable, nm_device_resolve_address, callback, cb_data), + .addr_family = addr_family, + .address = nm_ip_addr_init(addr_family, address), + }; + + if (cancellable) { + gulong signal_id; + + signal_id = + g_cancellable_connect(cancellable, G_CALLBACK(resolve_addr_cancelled), info, NULL); + if (signal_id == 0) { + /* the request is already cancelled. Return. */ + return; + } + info->cancellable_id = signal_id; + } + + resolved = (NMDnsSystemdResolved *) nm_dns_manager_get_systemd_resolved(nm_dns_manager_get()); + if (resolved) { + _LOG2D(info, "start lookup via systemd-resolved"); + info->resolved_handle = + nm_dns_systemd_resolved_resolve_address(resolved, + 0, + addr_family, + address, + SD_RESOLVED_DNS | SD_RESOLVED_NO_SYNTHESIZE, + 20000, + resolve_addr_resolved_cb, + info); + return; + } + + resolve_addr_spawn_helper(info); +} + +char * +nm_device_resolve_address_finish(GAsyncResult *result, GError **error) +{ + GTask *task = G_TASK(result); + + nm_assert(nm_g_task_is_valid(result, NULL, nm_device_resolve_address)); + + return g_task_propagate_pointer(task, error); +} diff --git a/src/core/devices/nm-device-utils.h b/src/core/devices/nm-device-utils.h new file mode 100644 index 00000000..8bc957a4 --- /dev/null +++ b/src/core/devices/nm-device-utils.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __DEVICES_NM_DEVICE_UTILS_H__ +#define __DEVICES_NM_DEVICE_UTILS_H__ + +/*****************************************************************************/ + +const char *nm_device_state_to_str(NMDeviceState state); +const char *nm_device_state_reason_to_str(NMDeviceStateReason reason); + +#define nm_device_state_reason_to_str_a(reason) \ + NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, reason) + +static inline NMDeviceStateReason +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; +} + +/*****************************************************************************/ + +#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-" + +const char *nm_device_state_queued_state_to_str(NMDeviceState state); + +/*****************************************************************************/ + +typedef enum { + NM_DEVICE_MTU_SOURCE_NONE, + NM_DEVICE_MTU_SOURCE_PARENT, + NM_DEVICE_MTU_SOURCE_IP_CONFIG, + NM_DEVICE_MTU_SOURCE_CONNECTION, +} NMDeviceMtuSource; + +const char *nm_device_mtu_source_to_str(NMDeviceMtuSource mtu_source); + +/*****************************************************************************/ + +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; + +const char *nm_device_sys_iface_state_to_str(NMDeviceSysIfaceState sys_iface_state); + +/*****************************************************************************/ + +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, +} NMDeviceIPState; + +const char *nm_device_ip_state_to_str(NMDeviceIPState ip_state); + +/*****************************************************************************/ + +/*****************************************************************************/ + +void nm_device_resolve_address(int addr_family, + gconstpointer address, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer cb_data); + +char *nm_device_resolve_address_finish(GAsyncResult *result, GError **error); + +#endif /* __DEVICES_NM_DEVICE_UTILS_H__ */ diff --git a/src/core/devices/nm-device-veth.c b/src/core/devices/nm-device-veth.c index e0ba843d..28831b75 100644 --- a/src/core/devices/nm-device-veth.c +++ b/src/core/devices/nm-device-veth.c @@ -7,11 +7,11 @@ #include <stdlib.h> -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-veth.h" #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-veth.h" @@ -161,12 +161,8 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Peer", "o", NM_DEVICE_VETH_PEER), ), ), }; static void diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c index bfde60ef..548245f8 100644 --- a/src/core/devices/nm-device-vlan.c +++ b/src/core/devices/nm-device-vlan.c @@ -16,11 +16,12 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" -#include "nm-core-internal.h" -#include "platform/nmp-object.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nm-platform-utils.h" #define _NMLOG_DEVICE_TYPE NMDeviceVlan #include "nm-device-logging.h" @@ -436,7 +437,7 @@ update_connection(NMDevice *device, NMConnection *connection) const NMPlatformLink *plink; const NMPObject * polnk; guint vlan_id; - guint vlan_flags; + _NMVlanFlags vlan_flags; if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); @@ -463,9 +464,9 @@ update_connection(NMDevice *device, NMConnection *connection) 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); + vlan_flags = _NM_VLAN_FLAG_REORDER_HEADERS; + if (NM_VLAN_FLAGS_CAST(vlan_flags) != nm_setting_vlan_get_flags(s_vlan)) + g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAGS_CAST(vlan_flags), NULL); if (polnk) { _nm_setting_vlan_set_priorities(s_vlan, @@ -507,7 +508,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) nm_platform_link_vlan_change(nm_device_get_platform(device), nm_device_get_ifindex(device), - NM_VLAN_FLAGS_ALL, + _NM_VLAN_FLAGS_ALL, nm_setting_vlan_get_flags(s_vlan), TRUE, ingress_map, @@ -546,17 +547,11 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("VlanId", "u", NM_DEVICE_VLAN_ID), ), ), }; static void @@ -674,7 +669,7 @@ get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const c * 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)); + return nmp_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index 4fec59ba..2a1f42c6 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -4,12 +4,12 @@ #include "nm-device-vrf.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-factory.h" #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-vrf.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceVrf diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c index f16a52c4..f9dfad2a 100644 --- a/src/core/devices/nm-device-vxlan.c +++ b/src/core/devices/nm-device-vxlan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "nm-device-factory.h" #include "nm-setting-vxlan.h" @@ -17,7 +17,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceVxlan #include "nm-device-logging.h" @@ -576,38 +576,34 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Id", "u", NM_DEVICE_VXLAN_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Group", "s", NM_DEVICE_VXLAN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Local", "s", NM_DEVICE_VXLAN_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tos", "y", NM_DEVICE_VXLAN_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ttl", "y", NM_DEVICE_VXLAN_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Learning", + "b", + NM_DEVICE_VXLAN_LEARNING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ageing", "u", NM_DEVICE_VXLAN_AGEING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Limit", "u", NM_DEVICE_VXLAN_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DstPort", + "q", + NM_DEVICE_VXLAN_DST_PORT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("SrcPortMin", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MIN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("SrcPortMax", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MAX), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Proxy", "b", NM_DEVICE_VXLAN_PROXY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Rsc", "b", NM_DEVICE_VXLAN_RSC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("L3miss", + "b", + NM_DEVICE_VXLAN_L3MISS), ), ), }; static void diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index 5bee09e6..aa9c46eb 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -11,12 +11,12 @@ #include <linux/fib_rules.h> #include "nm-setting-wireguard.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-secret-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-secret-utils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "nm-device-factory.h" #include "nm-active-connection.h" #include "nm-act-request.h" @@ -66,7 +66,7 @@ G_STATIC_ASSERT(NM_WIREGUARD_SYMMETRIC_KEY_LEN == NMP_WIREGUARD_SYMMETRIC_KEY_LE * 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, @@ -669,7 +669,7 @@ _peers_resolve_retry_reschedule(NMDeviceWireGuard *self, gint64 new_next_try_at_ * 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)); + (gint64) (24 * 60 * 60 * 1000)); _LOGT(LOGD_DEVICE, "wireguard-peers: schedule rechecking peer endpoints in %u msec", @@ -1939,11 +1939,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 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)); + g_value_take_variant( + value, + nm_g_variant_new_ay(priv->lnk_curr.public_key, sizeof(priv->lnk_curr.public_key))); break; case PROP_LISTEN_PORT: g_value_set_uint(value, priv->lnk_curr.listen_port); diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c index 2f3b16ff..73d79410 100644 --- a/src/core/devices/nm-device-wpan.c +++ b/src/core/devices/nm-device-wpan.c @@ -15,10 +15,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-wpan.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceWpan #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 3874e586..50386d00 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -23,22 +23,23 @@ #include <linux/if_ether.h> #include <linux/if_infiniband.h> -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-random-utils.h" -#include "systemd/nm-sd-utils-shared.h" - -#include "nm-base/nm-ethtool-base.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" + +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-core-aux-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" -#include "nm-platform/nm-platform-utils.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" #include "dhcp/nm-dhcp-manager.h" @@ -51,7 +52,8 @@ #include "dnsmasq/nm-dnsmasq-manager.h" #include "nm-dhcp-config.h" #include "nm-rfkill-manager.h" -#include "nm-firewall-manager.h" +#include "nm-firewall-utils.h" +#include "nm-firewalld-manager.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-setting-ethtool.h" @@ -65,12 +67,13 @@ #include "c-list/src/c-list.h" #include "dns/nm-dns-manager.h" #include "nm-acd-manager.h" -#include "nm-core-internal.h" -#include "systemd/nm-sd.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-systemd-core/nm-sd.h" #include "nm-lldp-listener.h" #include "nm-audit-manager.h" #include "nm-connectivity.h" #include "nm-dbus-interface.h" +#include "nm-hostname-manager.h" #include "nm-device-generic.h" #include "nm-device-vlan.h" @@ -207,6 +210,7 @@ typedef struct { NMOptionBool requested[_NM_ETHTOOL_ID_FEATURE_NUM]; NMEthtoolCoalesceState *coalesce; NMEthtoolRingState * ring; + NMEthtoolPauseState * pause; } EthtoolState; typedef enum { @@ -217,7 +221,6 @@ typedef enum { typedef struct { ResolverState state; - GResolver * resolver; GInetAddress *address; GCancellable *cancellable; char * hostname; @@ -496,11 +499,18 @@ typedef struct _NMDevicePrivate { NMDeviceStageState stage1_sriov_state : 3; - /* Generic DHCP stuff */ - char *dhcp_anycast_address; + bool ip_config_started : 1; char *current_stable_id; + union { + struct { + GSource *ip_req_timeout_source_6; + GSource *ip_req_timeout_source_4; + }; + GSource *ip_req_timeout_source_x[2]; + }; + /* Proxy Configuration */ NMProxyConfig * proxy_config; NMPacrunnerConfId *pacrunner_conf_id; @@ -592,9 +602,9 @@ typedef struct _NMDevicePrivate { gulong dnsmasq_state_id; /* Firewall */ - FirewallState fw_state : 4; - NMFirewallManager * fw_mgr; - NMFirewallManagerCallId *fw_call; + FirewallState fw_state : 4; + NMFirewalldManager * fw_mgr; + NMFirewalldManagerCallId *fw_call; /* IPv4LL stuff */ sd_ipv4ll *ipv4ll; @@ -693,6 +703,8 @@ typedef struct _NMDevicePrivate { } stats; bool mtu_force_set_done : 1; + + NMOptionBool promisc_reset; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -764,139 +776,7 @@ static void sriov_op_cb(GError *error, gpointer user_data); static void device_ifindex_changed_cb(NMManager *manager, NMDevice *device_changed, NMDevice *self); static gboolean device_link_changed(NMDevice *self); - -/*****************************************************************************/ - -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"), ); +static void check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update); /*****************************************************************************/ @@ -908,7 +788,6 @@ _hostname_resolver_free(HostnameResolver *resolver) nm_clear_g_source(&resolver->timeout_id); nm_clear_g_cancellable(&resolver->cancellable); - nm_g_object_unref(resolver->resolver); nm_g_object_unref(resolver->address); g_free(resolver->hostname); nm_g_slice_free(resolver); @@ -952,8 +831,7 @@ _prop_get_connection_stable_id(NMDevice * self, * 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; + gs_free char * generated = NULL; NMUtilsStableType stable_type; NMSettingConnection *s_con; gboolean hwaddr_is_fake; @@ -966,11 +844,10 @@ _prop_get_connection_stable_id(NMDevice * self, stable_id = nm_setting_connection_get_stable_id(s_con); if (!stable_id) { - default_id = + stable_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); @@ -1029,7 +906,6 @@ _prop_get_ipv6_dhcp_duid(NMDevice * self, { NMSettingIPConfig *s_ip6; const char * duid; - gs_free char * duid_default = NULL; const char * duid_error; GBytes * duid_out; gboolean duid_enforce = TRUE; @@ -1042,10 +918,9 @@ _prop_get_ipv6_dhcp_duid(NMDevice * self, 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; + duid = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.dhcp-duid"), + self); if (!duid) duid = "lease"; } @@ -1396,7 +1271,7 @@ _prop_get_ipvx_route_table(NMDevice *self, int addr_family) _LOGT(LOGD_DEVICE, "ipv%c.route-table = %u%s", nm_utils_addr_family_to_char(addr_family), - (guint)(route_table ?: RT_TABLE_MAIN), + (guint) (route_table ?: RT_TABLE_MAIN), route_table != 0u ? "" : " (policy routing not enabled)"); return route_table; @@ -1500,6 +1375,40 @@ out: return timeout; } +static guint32 +_prop_get_ipvx_required_timeout(NMDevice *self, int addr_family) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip; + int timeout; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert_addr_family(addr_family); + + connection = nm_device_get_applied_connection(self); + if (!connection) + return 0; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (!s_ip) + return 0; + + timeout = nm_setting_ip_config_get_required_timeout(s_ip); + nm_assert(timeout >= -1); + + if (timeout > -1) + return (guint32) timeout; + + return nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + NM_IS_IPv4(addr_family) ? NM_CON_DEFAULT("ipv4.required-timeout") + : NM_CON_DEFAULT("ipv6.required-timeout"), + self, + 0, + G_MAXINT32, + 0); +} + /** * _prop_get_ipvx_dhcp_iaid: * @self: the #NMDevice @@ -1522,7 +1431,6 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, const int IS_IPv4 = NM_IS_IPv4(addr_family); NMSettingIPConfig *s_ip; const char * iaid_str; - gs_free char * iaid_str_free = NULL; guint32 iaid; const char * iface; const char * fail_reason; @@ -1531,11 +1439,10 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, 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, - IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-iaid") : NM_CON_DEFAULT("ipv6.dhcp-iaid"), - self); - iaid_str = iaid_str_free; + iaid_str = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-iaid") + : NM_CON_DEFAULT("ipv6.dhcp-iaid"), + self); if (!iaid_str) { iaid_str = NM_IAID_IFNAME; is_explicit = FALSE; @@ -1566,7 +1473,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, 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]; + guint8 hwaddr_buf[_NM_UTILS_HWADDR_LEN_MAX]; const char *hwaddr_str; gsize hwaddr_len; @@ -1692,12 +1599,10 @@ _prop_get_ipvx_dhcp_hostname_flags(NMDevice *self, int addr_family) } static const char * -_prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con, char **out_mud_url) +_prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con) { - const char * mud_url; - gs_free char *s = NULL; - - nm_assert(out_mud_url && !*out_mud_url); + const char *mud_url; + const char *s; mud_url = nm_setting_connection_get_mud_url(s_con); @@ -1714,7 +1619,7 @@ _prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con, char ** 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 s; } return NULL; @@ -1725,10 +1630,9 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * { 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]; + guint8 hwaddr_bin_buf[_NM_UTILS_HWADDR_LEN_MAX]; const guint8 * hwaddr_bin; int arp_type; gsize hwaddr_len; @@ -1739,13 +1643,12 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * 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]) { + client_id = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-client-id"), + self); + if (client_id && !client_id[0]) { /* a non-empty client-id is always valid, see nm_dhcp_utils_client_id_string_to_bytes(). */ - client_id = client_id_default; + client_id = NULL; } } @@ -1877,8 +1780,7 @@ out_good: 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; + gs_free char *to_free = NULL; const char * conn_prop; GBytes * bytes = NULL; const char * bin; @@ -1888,13 +1790,13 @@ _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config * if (!conn_prop) { /* set in NetworkManager.conf ? */ - config_data_prop = nm_config_data_get_connection_default( + conn_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 && !nm_utils_validate_dhcp4_vendor_class_id(conn_prop, NULL)) + conn_prop = NULL; } if (conn_prop) { @@ -1960,16 +1862,11 @@ _prop_get_ipv6_ip6_privacy(NMDevice *self) } static const char * -_prop_get_x_cloned_mac_address(NMDevice * self, - NMConnection *connection, - gboolean is_wifi, - char ** out_addr) +_prop_get_x_cloned_mac_address(NMDevice *self, NMConnection *connection, gboolean is_wifi) { 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) { @@ -1978,7 +1875,7 @@ _prop_get_x_cloned_mac_address(NMDevice * self, } if (!addr) { - gs_free char *a = NULL; + const char *a; a = nm_config_data_get_connection_default( NM_CONFIG_GET_DATA, @@ -1993,36 +1890,28 @@ _prop_get_x_cloned_mac_address(NMDevice * self, NMSettingMacRandomization v; /* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */ - a = nm_config_data_get_connection_default( + v = nm_config_data_get_connection_default_int64( 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); + self, + 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); + addr = a; } return addr; } static const char * -_prop_get_x_generate_mac_address_mask(NMDevice * self, - NMConnection *connection, - gboolean is_wifi, - char ** out_value) +_prop_get_x_generate_mac_address_mask(NMDevice *self, NMConnection *connection, gboolean is_wifi) { NMSetting * setting; - const char *value = NULL; - char * a; - - nm_assert(out_value && !*out_value); + const char *value; setting = nm_connection_get_setting(connection, is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); @@ -2035,15 +1924,11 @@ _prop_get_x_generate_mac_address_mask(NMDevice * self, return value; } - a = nm_config_data_get_connection_default( + return 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; } /*****************************************************************************/ @@ -2272,6 +2157,113 @@ _ethtool_ring_set(NMDevice * self, } static void +_ethtool_pause_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) +{ + gs_free NMEthtoolPauseState *pause = NULL; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(ethtool_state); + + pause = g_steal_pointer(ðtool_state->pause); + if (!pause) + return; + + if (!nm_platform_ethtool_set_pause(platform, ethtool_state->ifindex, pause)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more pause settings"); + else + _LOGD(LOGD_DEVICE, "ethtool: pause settings successfully reset"); +} + +static void +_ethtool_pause_set(NMDevice * self, + NMPlatform * platform, + EthtoolState * ethtool_state, + NMSettingEthtool *s_ethtool) +{ + NMEthtoolPauseState pause_old; + NMEthtoolPauseState pause_new; + GHashTable * hash; + GHashTableIter iter; + const char * name; + GVariant * variant; + gboolean has_old = FALSE; + NMTernary pause_autoneg = NM_TERNARY_DEFAULT; + NMTernary pause_rx = NM_TERNARY_DEFAULT; + NMTernary pause_tx = NM_TERNARY_DEFAULT; + + 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->pause); + + 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_pause(ethtool_id)) + continue; + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + + if (!has_old) { + if (!nm_platform_ethtool_get_link_pause(platform, ethtool_state->ifindex, &pause_old)) { + _LOGW(LOGD_DEVICE, + "ethtool: failure setting pause options (cannot read " + "existing setting)"); + return; + } + has_old = TRUE; + } + + switch (ethtool_id) { + case NM_ETHTOOL_ID_PAUSE_AUTONEG: + pause_autoneg = g_variant_get_boolean(variant); + break; + case NM_ETHTOOL_ID_PAUSE_RX: + pause_rx = g_variant_get_boolean(variant); + break; + case NM_ETHTOOL_ID_PAUSE_TX: + pause_tx = g_variant_get_boolean(variant); + break; + default: + nm_assert_not_reached(); + } + } + + if (!has_old) + return; + + if (pause_rx != NM_TERNARY_DEFAULT || pause_tx != NM_TERNARY_DEFAULT) { + /* this implies to explicitly disable autoneg. */ + nm_assert(pause_autoneg != NM_TERNARY_TRUE); + pause_autoneg = NM_TERNARY_FALSE; + } + + pause_new = pause_old; + if (pause_autoneg != NM_TERNARY_DEFAULT) + pause_new.autoneg = !!pause_autoneg; + if (pause_rx != NM_TERNARY_DEFAULT) + pause_new.rx = !!pause_rx; + if (pause_tx != NM_TERNARY_DEFAULT) + pause_new.tx = !!pause_tx; + + ethtool_state->pause = nm_memdup(&pause_old, sizeof(pause_old)); + + if (!nm_platform_ethtool_set_pause(platform, ethtool_state->ifindex, &pause_new)) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting pause settings"); + return; + } + + _LOGD(LOGD_DEVICE, "ethtool: pause settings successfully set"); +} + +static void _ethtool_state_reset(NMDevice *self) { NMPlatform * platform = nm_device_get_platform(self); @@ -2287,6 +2279,8 @@ _ethtool_state_reset(NMDevice *self) _ethtool_coalesce_reset(self, platform, ethtool_state); if (ethtool_state->ring) _ethtool_ring_reset(self, platform, ethtool_state); + if (ethtool_state->pause) + _ethtool_pause_reset(self, platform, ethtool_state); } static void @@ -2320,8 +2314,10 @@ _ethtool_state_set(NMDevice *self) _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); + _ethtool_pause_set(self, platform, ethtool_state, s_ethtool); - if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring) + if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring + || ethtool_state->pause) priv->ethtool_state = g_steal_pointer(ðtool_state); } @@ -2520,15 +2516,6 @@ applied_config_reset_nameservers(AppliedConfig *config) /*****************************************************************************/ -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) { @@ -2567,8 +2554,8 @@ nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_st 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)); + nm_device_sys_iface_state_to_str(priv->sys_iface_state), + nm_device_sys_iface_state_to_str(sys_iface_state)); priv->sys_iface_state_ = sys_iface_state; } @@ -2599,6 +2586,42 @@ _active_connection_set_state_flags(NMDevice *self, NMActivationStateFlags flags) /*****************************************************************************/ +static gboolean +set_interface_flags_full(NMDevice * self, + NMDeviceInterfaceFlags mask, + NMDeviceInterfaceFlags interface_flags, + gboolean notify) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceInterfaceFlags f; + + nm_assert(!!mask); + nm_assert(!NM_FLAGS_ANY(mask, ~_NM_DEVICE_INTERFACE_FLAG_ALL)); + nm_assert(!NM_FLAGS_ANY(interface_flags, ~mask)); + + f = (priv->interface_flags & ~mask) | (interface_flags & mask); + + if (f == priv->interface_flags) + return FALSE; + + priv->interface_flags = f; + if (notify) + _notify(self, PROP_INTERFACE_FLAGS); + return TRUE; +} + +static gboolean +set_interface_flags(NMDevice * self, + NMDeviceInterfaceFlags interface_flags, + gboolean set, + gboolean notify) +{ + return set_interface_flags_full(self, + interface_flags, + set ? interface_flags : NM_DEVICE_INTERFACE_FLAG_NONE, + notify); +} + void nm_device_assume_state_get(NMDevice * self, gboolean * out_assume_state_guess_assume, @@ -2809,23 +2832,72 @@ _add_capabilities(NMDevice *self, NMDeviceCapabilities 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 gboolean +ip_required_timeout_x(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + _LOGD(LOGD_CORE, + "required-timeout expired for IPv%c", + nm_utils_addr_family_to_char(addr_family)); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_x[NM_IS_IPv4(addr_family)]); + check_ip_state(self, FALSE, TRUE); + return G_SOURCE_CONTINUE; +} + +static gboolean +ip_required_timeout_4(gpointer data) +{ + return ip_required_timeout_x(data, AF_INET); +} + +static gboolean +ip_required_timeout_6(gpointer data) +{ + return ip_required_timeout_x(data, AF_INET6); +} static void _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); const int IS_IPv4 = NM_IS_IPv4(addr_family); + guint timeout_msec; + int v4; nm_assert_addr_family(addr_family); + if (new_state == NM_DEVICE_IP_STATE_CONF && !priv->ip_config_started) { + /* Start the required-timeout timers when one of IPv4/IPv6 + * enters the CONF state. This means that if there is no carrier and + * ipv4.method=auto,ipv6.method=manual, the timeout for IPv4 will + * start as soon as connection is activated, even if DHCPv4 did not + * start yet. + */ + priv->ip_config_started = TRUE; + + for (v4 = 1; v4 >= 0; v4--) { + char buf[32]; + + nm_assert(!priv->ip_req_timeout_source_x[v4]); + if ((timeout_msec = _prop_get_ipvx_required_timeout(self, v4 ? AF_INET : AF_INET6))) { + _LOGD(LOGD_CORE, + "required-timeout in %s msec for IPv%c", + timeout_msec == G_MAXINT32 ? "∞" : nm_sprintf_buf(buf, "%u", timeout_msec), + v4 ? '4' : '6'); + + if (timeout_msec == G_MAXINT32) { + priv->ip_req_timeout_source_x[v4] = g_source_ref(nm_g_source_sentinel_get(0)); + } else { + priv->ip_req_timeout_source_x[v4] = + nm_g_timeout_add_source(timeout_msec, + v4 ? ip_required_timeout_4 : ip_required_timeout_6, + self); + } + } + } + } + if (priv->ip_state_x[IS_IPv4] == new_state) return; @@ -2833,7 +2905,7 @@ _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) "ip%c-state: set to %d (%s)", nm_utils_addr_family_to_char(addr_family), (int) new_state, - _ip_state_to_string(new_state)); + nm_device_ip_state_to_str(new_state)); priv->ip_state_x_[IS_IPv4] = new_state; @@ -2942,10 +3014,10 @@ nm_device_take_over_link(NMDevice *self, int ifindex, char **old_name, GError ** /* Rename the link to the device ifname */ if (up) - nm_platform_link_set_down(platform, ifindex); + nm_platform_link_change_flags(platform, ifindex, IFF_UP, FALSE); success = nm_platform_link_set_name(platform, ifindex, nm_device_get_iface(self)); if (up) - nm_platform_link_set_up(platform, ifindex, NULL); + nm_platform_link_change_flags(platform, ifindex, IFF_UP, TRUE); if (!success) { nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "failure renaming link %d", ifindex); @@ -3073,7 +3145,7 @@ _set_ip_ifindex(NMDevice *self, int ifindex, const char *ifname) 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); + nm_platform_link_change_flags(platform, priv->ip_ifindex, IFF_UP, TRUE); } /* We don't care about any saved values from the old iface */ @@ -4865,7 +4937,6 @@ void nm_device_update_dynamic_ip_setup(NMDevice *self) { NMDevicePrivate *priv; - GError * error = NULL; g_return_if_fail(NM_IS_DEVICE(self)); @@ -4898,17 +4969,6 @@ nm_device_update_dynamic_ip_setup(NMDevice *self) 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); - } - } } /*****************************************************************************/ @@ -5025,18 +5085,12 @@ nm_device_set_carrier(NMDevice *self, gboolean carrier) 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; + notify_flags = set_interface_flags(self, NM_DEVICE_INTERFACE_FLAG_CARRIER, carrier, FALSE); } priv->carrier = carrier; - if (notify_flags) - nm_gobject_notify_together(self, PROP_CARRIER, PROP_INTERFACE_FLAGS); - else - _notify(self, PROP_CARRIER); + + nm_gobject_notify_together(self, PROP_CARRIER, notify_flags ? PROP_INTERFACE_FLAGS : PROP_0); if (priv->carrier) { _LOGI(LOGD_DEVICE, "carrier: link connected"); @@ -5215,11 +5269,11 @@ ndisc_set_router_config(NMNDisc *ndisc, NMDevice *self) if (addr->plen != 64) continue; - lifetime = nm_utils_lifetime_get(addr->timestamp, - addr->lifetime, - addr->preferred, - NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, - &preferred); + lifetime = nmp_utils_lifetime_get(addr->timestamp, + addr->lifetime, + addr->preferred, + NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, + &preferred); if (!lifetime) continue; @@ -5271,6 +5325,8 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink) 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_PROMISC)) + flags |= NM_DEVICE_INTERFACE_FLAG_PROMISC; if (NM_FLAGS_ALL(priv->capabilities, NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { @@ -5281,10 +5337,12 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink) flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; } - if (flags != priv->interface_flags) { - priv->interface_flags = flags; - _notify(self, PROP_INTERFACE_FLAGS); - } + set_interface_flags_full(self, + NM_DEVICE_INTERFACE_FLAG_UP | NM_DEVICE_INTERFACE_FLAG_LOWER_UP + | NM_DEVICE_INTERFACE_FLAG_CARRIER + | NM_DEVICE_INTERFACE_FLAG_PROMISC, + flags, + TRUE); } static gboolean @@ -5891,16 +5949,19 @@ sriov_op_queue(NMDevice * self, static void 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); 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); + int num_vfs; + + num_vfs = nm_config_data_get_device_config_int64(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS, + self, + 10, + 0, + G_MAXINT32, + -1, + -1); if (num_vfs >= 0) sriov_op_queue(self, num_vfs, NM_OPTION_BOOL_DEFAULT, NULL, NULL); } @@ -6618,6 +6679,7 @@ check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update) gboolean ip4_disabled = FALSE, ip6_disabled = FALSE; NMSettingIPConfig *s_ip4, *s_ip6; NMDeviceState state; + int IS_IPv4; if (full_state_update && nm_device_get_state(self) != NM_DEVICE_STATE_IP_CONFIG) return; @@ -6647,6 +6709,13 @@ check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update) return; } + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { + if (priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_CONF + && priv->ip_req_timeout_source_x[IS_IPv4]) { + 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 @@ -7170,6 +7239,16 @@ _get_maybe_ipv6_disabled(NMDevice *self) return (nm_platform_sysctl_get_int32(platform, NMP_SYSCTL_PATHID_ABSOLUTE(path), 0) == 0); } +/* + * nm_device_generate_connection: + * + * Generates a connection from an existing interface. + * + * If the device doesn't have an IP configuration and it's not a port or a + * controller, then no connection gets generated and the function returns + * %NULL. In such case, @maybe_later is set to %TRUE if a connection can be + * generated later when an IP address is assigned to the interface. + */ NMConnection * nm_device_generate_connection(NMDevice *self, NMDevice *master, @@ -7214,7 +7293,7 @@ nm_device_generate_connection(NMDevice *self, g_object_set(s_con, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_buf(uuid), + nm_uuid_generate_random_str_arr(uuid), NM_SETTING_CONNECTION_ID, ifname, NM_SETTING_CONNECTION_AUTOCONNECT, @@ -7426,6 +7505,8 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e gs_free char * conn_iface = NULL; NMDeviceClass * klass; NMSettingMatch * s_match; + const GSList * specs; + gboolean has_match = FALSE; klass = NM_DEVICE_GET_CLASS(self); if (klass->connection_type_check_compatible) { @@ -7466,11 +7547,10 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e 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)) { + if (num_patterns > 0 && !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"); @@ -7485,9 +7565,9 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e 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)) { + patterns = nm_setting_match_get_drivers(s_match, &num_patterns); + if (num_patterns > 0 + && !nm_wildcard_match_check(nm_device_get_driver(self), patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "device does not satisfy match.driver property"); @@ -7495,7 +7575,7 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e } patterns = nm_setting_match_get_paths(s_match, &num_patterns); - if (!nm_wildcard_match_check(priv->path, patterns, num_patterns)) { + if (num_patterns > 0 && !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"); @@ -7503,6 +7583,15 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e } } + specs = + nm_config_data_get_device_allowed_connections_specs(NM_CONFIG_GET_DATA, self, &has_match); + if (has_match && !nm_utils_connection_match_spec_list(connection, specs, FALSE)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_DISALLOWED, + "device configuration doesn't allow this connection"); + return FALSE; + } + return TRUE; } @@ -7569,7 +7658,7 @@ 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 +gboolean nm_device_can_assume_connections(NMDevice *self) { return !!NM_DEVICE_GET_CLASS(self)->update_connection; @@ -7924,14 +8013,6 @@ master_ready_cb(NMActiveConnection *active, GParamSpec *pspec, NMDevice *self) 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 NMPlatformVF * sriov_vf_config_to_platform(NMDevice *self, NMSriovVF *vf, GError **error) { @@ -8219,38 +8300,56 @@ act_stage2_config(NMDevice *self, NMDeviceStateReason *out_failure_reason) } static void -lldp_init(NMDevice *self, gboolean restart) +_lldp_neighbors_changed_cb(NMLldpListener *lldp_listener, gpointer user_data) +{ + _notify(user_data, PROP_LLDP_NEIGHBORS); +} + +static void +lldp_setup(NMDevice *self, NMTernary enabled) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int ifindex; + gboolean notify_lldp_neighbors = FALSE; + gboolean notify_interface_flags = FALSE; - if (priv->ifindex > 0 && _prop_get_connection_lldp(self)) { - gs_free_error GError *error = NULL; + ifindex = nm_device_get_ifindex(self); - 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 (ifindex <= 0) + enabled = FALSE; + else if (enabled == NM_TERNARY_DEFAULT) + enabled = _prop_get_connection_lldp(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); - } + if (priv->lldp_listener) { + if (!enabled || nm_lldp_listener_get_ifindex(priv->lldp_listener) != ifindex) { + nm_clear_pointer(&priv->lldp_listener, nm_lldp_listener_destroy); + notify_lldp_neighbors = TRUE; } - } else { - if (priv->lldp_listener) - nm_lldp_listener_stop(priv->lldp_listener); } + + if (enabled && !priv->lldp_listener) { + gs_free_error GError *error = NULL; + + priv->lldp_listener = + nm_lldp_listener_new(ifindex, _lldp_neighbors_changed_cb, self, &error); + if (!priv->lldp_listener) { + /* This really shouldn't happen. It's likely a bug. Investigate when this happens! */ + _LOGW(LOGD_DEVICE, + "LLDP listener for ifindex %d could not be started: %s", + ifindex, + error->message); + } else + notify_lldp_neighbors = TRUE; + } + + notify_interface_flags = set_interface_flags(self, + NM_DEVICE_INTERFACE_FLAG_LLDP_CLIENT_ENABLED, + !!priv->lldp_listener, + FALSE); + + nm_gobject_notify_together(self, + notify_lldp_neighbors ? PROP_LLDP_NEIGHBORS : PROP_0, + notify_interface_flags ? PROP_INTERFACE_FLAGS : PROP_0); } /* set-mode can be: @@ -8401,8 +8500,10 @@ activate_stage2_device_config(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMDeviceClass * klass; NMActStageReturn ret; + NMSettingWired * s_wired; gboolean no_firmware = FALSE; CList * iter; + NMTernary accept_all_mac_addresses; nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); @@ -8460,7 +8561,30 @@ activate_stage2_device_config(NMDevice *self) nm_device_queue_recheck_assume(info->slave); } - lldp_init(self, TRUE); + s_wired = nm_device_get_applied_setting(self, NM_TYPE_SETTING_WIRED); + accept_all_mac_addresses = + s_wired ? nm_setting_wired_get_accept_all_mac_addresses(s_wired) : NM_TERNARY_DEFAULT; + if (accept_all_mac_addresses != NM_TERNARY_DEFAULT) { + int ifindex = nm_device_get_ip_ifindex(self); + + if (ifindex > 0) { + int ifi_flags = + nm_platform_link_get_ifi_flags(nm_device_get_platform(self), ifindex, IFF_PROMISC); + + if (ifi_flags >= 0 && ((!!ifi_flags) != (!!accept_all_mac_addresses))) { + nm_platform_link_change_flags(nm_device_get_platform(self), + ifindex, + IFF_PROMISC, + !!accept_all_mac_addresses); + if (priv->promisc_reset == NM_OPTION_BOOL_DEFAULT) + priv->promisc_reset = !accept_all_mac_addresses; + } + } + } + + lldp_setup(self, NM_TERNARY_DEFAULT); + + _commit_mtu(self, NULL); nm_device_activate_schedule_stage3_ip_config_start(self); } @@ -8877,6 +9001,21 @@ ensure_con_ip_config(NMDevice *self, int addr_family) /*****************************************************************************/ +static const char * +_device_get_dhcp_anycast_address(NMDevice *self) +{ + NMDeviceClass *klass; + + nm_assert(NM_IS_DEVICE(self)); + + klass = NM_DEVICE_GET_CLASS(self); + + if (klass->get_dhcp_anycast_address) + return klass->get_dhcp_anycast_address(self); + + return NULL; +} + static void dhcp4_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) { @@ -9234,7 +9373,7 @@ dhcp4_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP4, "DHCPv4 failed (ip_state %s, was_active %d)", - _ip_state_to_string(priv->ip_state_4), + nm_device_ip_state_to_str(priv->ip_state_4), priv->dhcp_data_4.was_active); /* The client is always left running after a failure. */ @@ -9382,12 +9521,13 @@ dhcp4_start(NMDevice *self) 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; + gboolean request_broadcast; + const char * str; connection = nm_device_get_applied_connection(self); g_return_val_if_fail(connection, FALSE); @@ -9401,10 +9541,22 @@ dhcp4_start(NMDevice *self) nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config); priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET); + request_broadcast = 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); bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast); + + str = nmp_object_link_udev_device_get_property_value(NMP_OBJECT_UP_CAST(pllink), + "ID_NET_DHCP_BROADCAST"); + if (str && _nm_utils_ascii_str_to_bool(str, FALSE)) { + /* Use the device property ID_NET_DHCP_BROADCAST setting, which may be set for interfaces + * requiring that the DHCPOFFER message is being broadcast because they can't handle unicast + * messages while not fully configured. + */ + request_broadcast = TRUE; + } } client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr); @@ -9413,28 +9565,29 @@ dhcp4_start(NMDevice *self) 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); + 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), + request_broadcast ? NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST : NM_DHCP_CLIENT_FLAGS_NONE, + 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), + client_id, + _prop_get_ipvx_dhcp_timeout(self, AF_INET), + _device_get_dhcp_anycast_address(self), + 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); @@ -9665,7 +9818,7 @@ dhcp6_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP6, "DHCPv6 failed (ip_state %s, was_active %d)", - _ip_state_to_string(priv->ip_state_6), + nm_device_ip_state_to_str(priv->ip_state_6), priv->dhcp_data_6.was_active); /* The client is always left running after a failure. */ @@ -9831,12 +9984,12 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) gs_unref_bytes GBytes * duid = NULL; gboolean enforce_duid = FALSE; const NMPlatformLink * pllink; - gs_free char * mud_url_free = NULL; - GError * error = NULL; + GError * error = NULL; guint32 iaid; gboolean iaid_explicit; NMSettingConnection * s_con; const NMPlatformIP6Address *ll_addr = NULL; + int ip_ifindex; g_return_val_if_fail(connection, FALSE); @@ -9846,9 +9999,9 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *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); + ll_addr = nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); } if (!ll_addr) { @@ -9856,7 +10009,13 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) return FALSE; } - pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + ip_ifindex = nm_device_get_ip_ifindex(self); + if (ip_ifindex <= 0) { + _LOGD(LOGD_DHCP6, "can't start DHCPv6: interface is gone"); + return FALSE; + } + + pllink = nm_platform_link_get(nm_device_get_platform(self), ip_ifindex); if (pllink) hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address); @@ -9867,22 +10026,23 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) nm_dhcp_manager_get(), nm_device_get_multi_index(self), nm_device_get_ip_iface(self), - nm_device_get_ip_ifindex(self), + ip_ifindex, &ll_addr->address, nm_connection_get_uuid(connection), nm_device_get_route_table(self, AF_INET6), nm_device_get_route_metric(self, AF_INET6), + (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY + : NM_DHCP_CLIENT_FLAGS_NONE, 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), + _prop_get_connection_mud_url(self, s_con), 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, + _device_get_dhcp_anycast_address(self), nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)), priv->dhcp6.needed_prefixes, &error); @@ -10088,9 +10248,9 @@ linklocal6_check_complete(NMDevice *self) } 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_ip_config_find_first_address(NM_IP_CONFIG(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; } @@ -10136,10 +10296,10 @@ check_and_add_ipv6ll_addr(NMDevice *self) 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)) { + && nm_ip_config_find_first_address(NM_IP_CONFIG(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; } @@ -10209,9 +10369,9 @@ linklocal6_start(NMDevice *self) 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)) + && nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) return TRUE; _LOGD(LOGD_DEVICE, @@ -10456,9 +10616,9 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) _LOGT(LOGD_DEVICE, "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", (guint) mtu, - mtu_source_to_str(source), + nm_device_mtu_source_to_str(source), (guint) source, - mtu_source_to_str(priv->mtu_source), + nm_device_mtu_source_to_str(priv->mtu_source), (guint) priv->mtu_source, force ? " (forced)" : ""); } @@ -10522,10 +10682,30 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) } } +#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 && NM_DEVICE_GET_CLASS(self)->mtu_force_set && !priv->mtu_force_set_done) { priv->mtu_force_set_done = TRUE; - if (mtu_desired == mtu_plat) { + 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(); + } 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); @@ -10544,20 +10724,6 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) 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; @@ -10790,9 +10956,9 @@ ndisc_ra_timeout(NMNDisc *ndisc, NMDevice *self) * 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_ip_config_find_first_address(NM_IP_CONFIG(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); @@ -11395,10 +11561,10 @@ activate_stage3_ip_config_start(NMDevice *self) } static void -fw_change_zone_cb(NMFirewallManager * firewall_manager, - NMFirewallManagerCallId *call_id, - GError * error, - gpointer user_data) +fw_change_zone_cb(NMFirewalldManager * firewalld_manager, + NMFirewalldManagerCallId *call_id, + GError * error, + gpointer user_data) { NMDevice * self = user_data; NMDevicePrivate *priv; @@ -11450,12 +11616,12 @@ fw_change_zone(NMDevice *self) nm_assert(s_con); if (priv->fw_call) { - nm_firewall_manager_cancel_call(priv->fw_call); + nm_firewalld_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()); + priv->fw_mgr = g_object_ref(nm_firewalld_manager_get()); zone = nm_setting_connection_get_zone(s_con); #if WITH_FIREWALLD_ZONE @@ -11467,12 +11633,12 @@ fw_change_zone(NMDevice *self) 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_firewalld_manager_add_or_change_zone(priv->fw_mgr, + nm_device_get_ip_iface(self), + zone, + FALSE, /* change zone */ + fw_change_zone_cb, + self); } /* @@ -11632,7 +11798,7 @@ share_init(NMDevice *self, GError **error) } for (i = 0; i < G_N_ELEMENTS(modules); i++) - nm_utils_modprobe(NULL, FALSE, modules[i], NULL); + nmp_utils_modprobe(NULL, FALSE, modules[i], NULL); return TRUE; } @@ -11648,7 +11814,7 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) NMConnection * conn; NMSettingConnection * s_con; gboolean announce_android_metered; - NMUtilsShareRules * share_rules; + NMFirewallConfig * firewall_config; g_return_val_if_fail(config, FALSE); @@ -11673,11 +11839,9 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) req = nm_device_get_act_request(self); g_return_val_if_fail(req, FALSE); - share_rules = nm_utils_share_rules_new(); - - nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen); + firewall_config = nm_firewall_config_new(ip_iface, ip4_addr->address, ip4_addr->plen); - nm_act_request_set_shared(req, share_rules); + nm_act_request_set_shared(req, firewall_config); conn = nm_act_request_get_applied_connection(req); s_con = nm_connection_get_setting_connection(conn); @@ -11792,13 +11956,15 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) req = nm_device_get_act_request(self); g_assert(req); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_x[IS_IPv4]); + /* 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); + nm_platform_link_change_flags(nm_device_get_platform(self), ip_ifindex, IFF_UP, TRUE); if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex)) _LOGW(LOGD_DEVICE, "interface %s not up for IP configuration", @@ -12660,7 +12826,7 @@ check_and_reapply_connection(NMDevice * self, klass->reapply_connection(self, con_old, con_new); if (priv->state >= NM_DEVICE_STATE_CONFIG) - lldp_init(self, FALSE); + lldp_setup(self, NM_TERNARY_DEFAULT); if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { s_ip4_old = nm_connection_get_setting_ip4_config(con_old); @@ -12891,9 +13057,10 @@ impl_device_get_applied_connection(NMDBusObject * obj, return; } - var_settings = nm_connection_to_dbus(applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + var_settings = + nm_connection_to_dbus(applied_connection, NM_CONNECTION_SERIALIZE_WITH_NON_SECRET); if (!var_settings) - var_settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + var_settings = nm_g_variant_singleton_aLsaLsvII(); g_dbus_method_invocation_return_value( invocation, @@ -13568,7 +13735,7 @@ nm_device_set_ip_config(NMDevice * self, 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, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, "update-external", NULL); } @@ -13660,18 +13827,24 @@ void nm_device_replace_vpn6_config(NMDevice *self, NMIP6Config *old, NMIP6Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceState state; nm_assert(!old || NM_IS_IP6_CONFIG(old)); + nm_assert(!old || nm_ip6_config_get_ifindex(old) > 0); + nm_assert(!old || nm_device_get_ip_ifindex(self) == 0 + || nm_device_get_ip_ifindex(self) == nm_ip6_config_get_ifindex(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(!config || nm_ip6_config_get_ifindex(config) > 0); + nm_assert(!config || nm_device_get_ip_ifindex(self) == nm_ip6_config_get_ifindex(config)); 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"); + state = nm_device_get_state(self); + if (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_ACTIVATED) { + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed to set VPN routes for device"); + } } NMIP6Config * @@ -13979,13 +14152,14 @@ nm_device_is_up(NMDevice *self) static gint64 _get_carrier_wait_ms(NMDevice *self) { - 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); + return nm_config_data_get_device_config_int64(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + self, + 10, + 0, + G_MAXINT32, + CARRIER_WAIT_TIME_MS, + CARRIER_WAIT_TIME_MS); } gboolean @@ -13995,6 +14169,7 @@ nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware) gboolean device_is_up = FALSE; NMDeviceCapabilities capabilities; int ifindex; + int r; g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); @@ -14010,7 +14185,9 @@ nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware) if (ifindex <= 0) { /* assume success. */ } else { - if (!nm_platform_link_set_up(nm_device_get_platform(self), ifindex, no_firmware)) + r = nm_platform_link_change_flags(nm_device_get_platform(self), ifindex, IFF_UP, TRUE); + NM_SET_OUT(no_firmware, (r == -NME_PL_NO_FIRMWARE)); + if (r < 0) return FALSE; } @@ -14097,7 +14274,7 @@ nm_device_take_down(NMDevice *self, gboolean block) return; } - if (!nm_platform_link_set_down(nm_device_get_platform(self), ifindex)) + if (!nm_platform_link_change_flags(nm_device_get_platform(self), ifindex, IFF_UP, FALSE)) return; device_is_up = nm_device_is_up(self); @@ -14827,7 +15004,7 @@ _set_unmanaged_flags(NMDevice * self, flags, NM_PRINT_FMT_QUOTED(allow_state_transition, ", reason ", - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), transition_state ? ", transition-state" : "", "")); @@ -15017,20 +15194,6 @@ nm_device_set_unmanaged_by_quitting(NMDevice *self) /*****************************************************************************/ void -nm_device_set_dhcp_anycast_address(NMDevice *self, const char *addr) -{ - NMDevicePrivate *priv; - - 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); - - g_free(priv->dhcp_anycast_address); - priv->dhcp_anycast_address = g_strdup(addr); -} - -void nm_device_reapply_settings_immediately(NMDevice *self) { NMConnection * applied_connection; @@ -15702,7 +15865,7 @@ _cancel_activation(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); if (priv->fw_call) { - nm_firewall_manager_cancel_call(priv->fw_call); + nm_firewalld_manager_cancel_call(priv->fw_call); nm_assert(!priv->fw_call); priv->fw_call = NULL; priv->fw_state = FIREWALL_STATE_INITIALIZED; @@ -15732,11 +15895,11 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type) 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); + nm_firewalld_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); @@ -15750,6 +15913,10 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type) _cleanup_ip_pre(self, AF_INET, cleanup_type); _cleanup_ip_pre(self, AF_INET6, cleanup_type); + + priv->ip_config_started = FALSE; + nm_clear_g_source_inst(&priv->ip_req_timeout_source_4); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_6); } static void @@ -15847,7 +16014,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu else _LOGD(LOGD_DEVICE, "deactivating device (reason '%s') [%d]", - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), reason); /* Save whether or not we tried IPv6 for later */ @@ -15902,8 +16069,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - if (priv->lldp_listener) - nm_lldp_listener_stop(priv->lldp_listener); + lldp_setup(self, NM_TERNARY_FALSE); nm_device_update_metered(self); @@ -15954,6 +16120,14 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu _ethtool_state_reset(self); + if (priv->promisc_reset != NM_OPTION_BOOL_DEFAULT && ifindex > 0) { + nm_platform_link_change_flags(nm_device_get_platform(self), + ifindex, + IFF_PROMISC, + !!priv->promisc_reset); + priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; + } + _cleanup_generic_post(self, cleanup_type); } @@ -16068,7 +16242,8 @@ nm_device_spawn_iface_helper(NMDevice *self) 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)) + if (NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(priv->dhcp_data_4.client), + NM_DHCP_CLIENT_FLAGS_USE_FQDN)) g_ptr_array_add(argv, g_strdup("--dhcp4-fqdn")); else g_ptr_array_add(argv, g_strdup("--dhcp4-hostname")); @@ -16335,8 +16510,8 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, "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), + nm_device_state_reason_to_str_a(reason), + nm_device_sys_iface_state_to_str(priv->sys_iface_state), priv->firmware_missing ? ", missing firmware" : ""); return; } @@ -16345,8 +16520,8 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, "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)); + nm_device_state_reason_to_str_a(reason), + nm_device_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 @@ -16692,7 +16867,7 @@ queued_state_set(gpointer user_data) _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), + nm_device_state_reason_to_str_a(priv->queued_state.reason), priv->queued_state.id, "change state"); @@ -16704,7 +16879,7 @@ queued_state_set(gpointer user_data) 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_remove_pending_action(self, nm_device_state_queued_state_to_str(new_state), TRUE); return G_SOURCE_REMOVE; } @@ -16722,12 +16897,12 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r _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), + nm_device_state_reason_to_str_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), + nm_device_state_reason_to_str_a(reason), ")", "")); return; @@ -16735,20 +16910,21 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r /* 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); + nm_device_add_pending_action(self, nm_device_state_queued_state_to_str(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), + nm_device_state_reason_to_str_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); + nm_device_remove_pending_action( + self, + nm_device_state_queued_state_to_str(priv->queued_state.state), + TRUE); } priv->queued_state.state = state; @@ -16758,7 +16934,7 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", nm_device_state_to_str(state), - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), priv->queued_state.id, "queue state change"); } @@ -16774,11 +16950,13 @@ queued_state_clear(NMDevice *self) _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), + nm_device_state_reason_to_str_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); + nm_device_remove_pending_action(self, + nm_device_state_queued_state_to_str(priv->queued_state.state), + TRUE); } NMDeviceState @@ -16796,7 +16974,7 @@ const char * nm_device_get_hw_address(NMDevice *self) { NMDevicePrivate *priv; - char buf[NM_UTILS_HWADDR_LEN_MAX]; + char buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; g_return_val_if_fail(NM_IS_DEVICE(self), NULL); @@ -16890,7 +17068,7 @@ 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]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; size_t len = 0; gboolean success_read; int ifindex; @@ -17008,7 +17186,7 @@ _hw_addr_set(NMDevice * self, NMDevicePrivate *priv; gboolean success = FALSE; int r; - guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; + guint8 addr_bytes[_NM_UTILS_HWADDR_LEN_MAX]; gsize addr_len; gboolean was_taken_down = FALSE; gboolean retry_down; @@ -17209,14 +17387,13 @@ _hw_addr_get_cloned(NMDevice * self, gboolean * preserve, char ** hwaddr, HwAddrType * hwaddr_type, - char ** hwaddr_detail, + const 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; + gs_free char * hw_addr_generated = NULL; + const char * addr; + const char * addr_setting; char * addr_out; HwAddrType type_out; @@ -17229,15 +17406,16 @@ _hw_addr_get_cloned(NMDevice * 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); + addr_setting = _prop_get_x_cloned_mac_address(self, connection, is_wifi); + + addr = addr_setting; 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)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; } @@ -17250,8 +17428,7 @@ _hw_addr_get_cloned(NMDevice * self, 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)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; } else if (!addr) { g_set_error_literal(error, @@ -17271,10 +17448,7 @@ _hw_addr_get_cloned(NMDevice * self, } 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)); + _prop_get_x_generate_mac_address_mask(self, connection, is_wifi)); if (!hw_addr_generated) { g_set_error(error, NM_DEVICE_ERROR, @@ -17302,10 +17476,7 @@ _hw_addr_get_cloned(NMDevice * self, 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)); + _prop_get_x_generate_mac_address_mask(self, connection, is_wifi)); if (!hw_addr_generated) { g_set_error(error, NM_DEVICE_ERROR, @@ -17329,7 +17500,7 @@ _hw_addr_get_cloned(NMDevice * self, 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)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; out_no_action: NM_SET_OUT(preserve, FALSE); @@ -17359,7 +17530,7 @@ nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean NMDevicePrivate *priv; gboolean preserve = FALSE; gs_free char * hwaddr = NULL; - gs_free char * detail = NULL; + const char * detail = NULL; HwAddrType type = HW_ADDR_TYPE_UNSET; gs_free_error GError *error = NULL; @@ -17599,23 +17770,38 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use { HostnameResolver *resolver; NMDevice * self; - gs_free char * hostname = NULL; gs_free char * addr_str = NULL; + gs_free char * output = NULL; gs_free_error GError *error = NULL; - hostname = g_resolver_lookup_by_address_finish(G_RESOLVER(source), result, &error); + output = nm_device_resolve_address_finish(result, &error); if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; - resolver = user_data; - self = resolver->device; - resolver->state = RESOLVER_DONE; - resolver->hostname = g_strdup(hostname); + resolver = user_data; + self = resolver->device; + resolver->state = RESOLVER_DONE; + + if (error) { + _LOGD(LOGD_DNS, + "hostname-from-dns: lookup error for %s: %s", + (addr_str = g_inet_address_to_string(resolver->address)), + error->message); + } else { + gboolean valid; + + resolver->hostname = g_steal_pointer(&output); + valid = nm_hostname_manager_validate_hostname(resolver->hostname); + + _LOGD(LOGD_DNS, + "hostname-from-dns: lookup done for %s, result %s%s%s%s", + (addr_str = g_inet_address_to_string(resolver->address)), + NM_PRINT_FMT_QUOTE_STRING(resolver->hostname), + valid ? "" : " (invalid)"); - _LOGD(LOGD_DNS, - "hostname-from-dns: lookup done for %s, result %s%s%s", - (addr_str = g_inet_address_to_string(resolver->address)), - NM_PRINT_FMT_QUOTE_STRING(hostname)); + if (!valid) + g_clear_pointer(&resolver->hostname, g_free); + } nm_clear_g_cancellable(&resolver->cancellable); g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0); @@ -17713,7 +17899,6 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean if (!resolver) { resolver = g_slice_new(HostnameResolver); *resolver = (HostnameResolver){ - .resolver = g_resolver_get_default(), .device = self, .addr_family = addr_family, .state = RESOLVER_WAIT_ADDRESS, @@ -17721,13 +17906,36 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean priv->hostname_resolver_x[IS_IPv4] = resolver; } - /* Determine the first address of the interface and - * whether it changed from the previous lookup */ + /* Determine the most suitable address of the interface + * and whether it changed from the previous lookup */ ip_config = priv->ip_config_x[IS_IPv4]; if (ip_config) { - const NMPlatformIPAddress *addr; + const NMPlatformIPAddress *addr = NULL; + + if (IS_IPv4) { + addr = nm_ip_config_get_first_address(ip_config); + } else { + /* For IPv6 prefer, in order: + * - !link-local, !deprecated + * - !link-local, deprecated + * - link-local + */ + addr = nm_ip_config_find_first_address(ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); + if (!addr) { + addr = nm_ip_config_find_first_address( + ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_DEPRECATED); + } + if (!addr) { + addr = nm_ip_config_find_first_address(ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY); + } + } - addr = nm_ip_config_get_first_address(ip_config); if (addr) { new_address = g_inet_address_new_from_bytes(addr->address_ptr, IS_IPv4 ? G_SOCKET_FAMILY_IPV4 @@ -17763,20 +17971,15 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean } if (address_changed && new_address) { - gs_free char *str = NULL; - - _LOGT(LOGD_DNS, - "hostname-from-dns: starting lookup for address %s", - (str = g_inet_address_to_string(new_address))); - resolver->state = RESOLVER_IN_PROGRESS; resolver->cancellable = g_cancellable_new(); resolver->address = g_steal_pointer(&new_address); - g_resolver_lookup_by_address_async(resolver->resolver, - resolver->address, - resolver->cancellable, - hostname_dns_lookup_callback, - resolver); + + nm_device_resolve_address(addr_family, + g_inet_address_to_bytes(resolver->address), + resolver->cancellable, + hostname_dns_lookup_callback, + resolver); nm_clear_g_source(&resolver->timeout_id); } @@ -17826,7 +18029,6 @@ 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: @@ -17977,12 +18179,10 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 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)); - } + g_value_set_variant(value, + priv->lldp_listener + ? nm_lldp_listener_get_neighbors(priv->lldp_listener) + : nm_g_variant_singleton_aaLsvI()); break; case PROP_REAL: g_value_set_boolean(value, nm_device_is_real(self)); @@ -18162,6 +18362,8 @@ nm_device_init(NMDevice *self) priv->v4_commit_first_time = TRUE; priv->v6_commit_first_time = TRUE; + + priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; } static GObject * @@ -18191,7 +18393,7 @@ constructor(GType type, guint n_construct_params, GObjectConstructParam *constru } if (priv->hw_addr_perm) { - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; if (!_nm_utils_hwaddr_aton(priv->hw_addr_perm, buf, sizeof(buf), &l)) { @@ -18339,13 +18541,7 @@ dispose(GObject *object) 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); - } + lldp_setup(self, FALSE); nm_clear_g_source(&priv->concheck_x[0].p_cur_id); nm_clear_g_source(&priv->concheck_x[1].p_cur_id); @@ -18388,7 +18584,6 @@ finalize(GObject *object) 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); @@ -18443,75 +18638,69 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { .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("Udi", "s", NM_DEVICE_UDI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Path", "s", NM_DEVICE_PATH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Interface", "s", NM_DEVICE_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IpInterface", "s", NM_DEVICE_IP_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Driver", "s", NM_DEVICE_DRIVER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DriverVersion", + "s", + NM_DEVICE_DRIVER_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FirmwareVersion", + "s", + NM_DEVICE_FIRMWARE_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Capabilities", + "u", + NM_DEVICE_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Address", + "u", + NM_DEVICE_IP4_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("State", "u", NM_DEVICE_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("StateReason", + "(uu)", + NM_DEVICE_STATE_REASON), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ActiveConnection", + "o", + NM_DEVICE_ACTIVE_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Config", "o", NM_DEVICE_IP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Dhcp4Config", + "o", + NM_DEVICE_DHCP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip6Config", "o", NM_DEVICE_IP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Dhcp6Config", + "o", + NM_DEVICE_DHCP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE("Managed", + "b", + NM_DEVICE_MANAGED, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_MANAGED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE("Autoconnect", + "b", + NM_DEVICE_AUTOCONNECT, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_AUTOCONNECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FirmwareMissing", + "b", + NM_DEVICE_FIRMWARE_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NmPluginMissing", + "b", + NM_DEVICE_NM_PLUGIN_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceType", + "u", + NM_DEVICE_DEVICE_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AvailableConnections", + "ao", + NM_DEVICE_AVAILABLE_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PhysicalPortId", + "s", + NM_DEVICE_PHYSICAL_PORT_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mtu", "u", NM_DEVICE_MTU), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Metered", "u", NM_DEVICE_METERED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LldpNeighbors", + "aa{sv}", + NM_DEVICE_LLDP_NEIGHBORS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Real", "b", NM_DEVICE_REAL), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Connectivity", "u", NM_DEVICE_IP4_CONNECTIVITY), @@ -18526,10 +18715,9 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { NM_DEVICE_HW_ADDRESS), ), ), }; -const NMDBusInterfaceInfoExtended nm_interface_info_device_statistics = { +static const NMDBusInterfaceInfoExtended 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", @@ -18555,7 +18743,7 @@ nm_device_class_init(NMDeviceClass *klass) 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); + NM_DBUS_INTERFACE_INFOS(&interface_info_device, &interface_info_device_statistics); object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 68343ef5..f59b6fa8 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -15,54 +15,7 @@ #include "nm-connection.h" #include "nm-rfkill-manager.h" #include "NetworkManagerUtils.h" - -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, -} NMDeviceMtuSource; - -static inline NMDeviceStateReason -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; -} - -#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-" +#include "nm-device-utils.h" /* Properties */ #define NM_DEVICE_UDI "udi" @@ -109,10 +62,10 @@ nm_device_state_reason_check(NMDeviceStateReason reason) * NMDeviceOvsBridge and NMDeviceOvsPort. */ #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 */ @@ -459,6 +412,8 @@ typedef struct _NMDeviceClass { gboolean (*set_platform_mtu)(NMDevice *self, guint32 mtu); + const char *(*get_dhcp_anycast_address)(NMDevice *self); + } NMDeviceClass; GType nm_device_get_type(void); @@ -572,6 +527,7 @@ nm_device_check_connection_compatible(NMDevice *device, NMConnection *connection gboolean nm_device_check_slave_connection_compatible(NMDevice *device, NMConnection *connection); +gboolean nm_device_can_assume_connections(NMDevice *self); gboolean nm_device_unmanage_on_quit(NMDevice *self); gboolean nm_device_spec_match_list(NMDevice *device, const GSList *specs); @@ -862,9 +818,6 @@ struct _NMBtVTableNetworkServer { 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); - gboolean nm_device_is_vpn(NMDevice *self); const char * diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index c60fb3ad..aba972ae 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -9,12 +9,15 @@ #include <net/ethernet.h> -#include "nm-std-aux/unaligned.h" -#include "platform/nm-platform.h" -#include "nm-glib-aux/nm-c-list.h" +#include "NetworkManagerUtils.h" +#include "libnm-core-public/nm-errors.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-utils.h" -#include "systemd/nm-sd.h" +#include "libnm-systemd-core/nm-sd.h" #define MAX_NEIGHBORS 128 #define MIN_UPDATE_INTERVAL_NSEC (2 * NM_UTILS_NSEC_PER_SEC) @@ -28,34 +31,21 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE(NMLldpListener, PROP_NEIGHBORS, ); - -typedef struct { +struct _NMLldpListener { sd_lldp * lldp_handle; GHashTable *lldp_neighbors; GVariant * variant; + NMLldpListenerNotify notify_callback; + gpointer notify_user_data; + /* the timestamp in nsec until which we delay updates. */ - gint64 ratelimit_next_nsec; - guint ratelimit_id; + GSource *ratelimit_source; + gint64 ratelimit_next_nsec; int ifindex; -} NMLldpListenerPrivate; - -struct _NMLldpListener { - GObject parent; - NMLldpListenerPrivate _priv; -}; - -struct _NMLldpListenerClass { - GObjectClass parent; }; -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) - /*****************************************************************************/ typedef struct { @@ -71,27 +61,28 @@ typedef struct { #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__)); \ - } \ - } \ +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) { \ + char _sbuf[100]; \ + \ + _nm_log(_level, \ + _NMLOG_DOMAIN, \ + 0, \ + (self) ? 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, \ + "[" NM_HASH_OBFUSCATE_PTR_FMT ",%d]", \ + NM_HASH_OBFUSCATE_PTR(self), \ + (self)->ifindex) \ + : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ G_STMT_END #define LOG_NEIGH_FMT "CHASSIS=%u/%s PORT=%u/%s" @@ -809,80 +800,73 @@ nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len) /*****************************************************************************/ static void -data_changed_notify(NMLldpListener *self, NMLldpListenerPrivate *priv) +data_changed_notify(NMLldpListener *self) { - nm_clear_g_variant(&priv->variant); - _notify(self, PROP_NEIGHBORS); + nm_clear_g_variant(&self->variant); + + self->notify_callback(self, self->notify_user_data); } static gboolean data_changed_timeout(gpointer user_data) { - NMLldpListener * self = user_data; - NMLldpListenerPrivate *priv; + NMLldpListener *self = user_data; - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), G_SOURCE_REMOVE); - - 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; + nm_clear_g_source_inst(&self->ratelimit_source); + self->ratelimit_next_nsec = nm_utils_get_monotonic_timestamp_nsec() + MIN_UPDATE_INTERVAL_NSEC; + data_changed_notify(self); + return G_SOURCE_CONTINUE; } static void data_changed_schedule(NMLldpListener *self) { - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - gint64 now_nsec; + gint64 now_nsec; - if (priv->ratelimit_id != 0) + if (self->ratelimit_source) 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; + if (now_nsec < self->ratelimit_next_nsec) { + self->ratelimit_source = nm_g_timeout_source_new( + NM_UTILS_NSEC_TO_MSEC_CEIL(self->ratelimit_next_nsec - now_nsec), + G_PRIORITY_LOW, + data_changed_timeout, + self, + NULL); + } else { + self->ratelimit_source = + nm_g_idle_source_new(G_PRIORITY_LOW, data_changed_timeout, self, NULL); } - priv->ratelimit_id = g_idle_add_full(G_PRIORITY_LOW, data_changed_timeout, self, NULL); + g_source_attach(self->ratelimit_source, NULL); } static void 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; - g_return_if_fail(NM_IS_LLDP_LISTENER(self)); + nm_assert(self); + nm_assert(self->lldp_handle); + nm_assert(self->lldp_neighbors); - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - g_return_if_fail(priv->lldp_handle); g_return_if_fail(neighbor_sd); - nm_assert(priv->lldp_neighbors); - 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(self->lldp_neighbors, 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); + g_hash_table_remove(self->lldp_neighbors, neigh_old); goto handle_changed; } return; @@ -893,14 +877,14 @@ process_lldp_neighbor(NMLldpListener *self, sd_lldp_neighbor *neighbor_sd, gbool _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(self->lldp_neighbors, g_steal_pointer(&neigh)); handle_changed: 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_t event, sd_lldp_neighbor *n, void *userdata) { process_lldp_neighbor( userdata, @@ -908,25 +892,57 @@ lldp_event_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void !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) +/*****************************************************************************/ + +int +nm_lldp_listener_get_ifindex(NMLldpListener *self) { - NMLldpListenerPrivate *priv; - int ret; + g_return_val_if_fail(self, 0); - 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); + return self->ifindex; +} - 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; +GVariant * +nm_lldp_listener_get_neighbors(NMLldpListener *self) +{ + g_return_val_if_fail(self, FALSE); + + if (G_UNLIKELY(!self->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(self->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])); + self->variant = g_variant_ref_sink(g_variant_builder_end(&array_builder)); } - ret = sd_lldp_new(&priv->lldp_handle); - if (ret < 0) { + return self->variant; +} + +/*****************************************************************************/ + +NMLldpListener * +nm_lldp_listener_new(int ifindex, + NMLldpListenerNotify notify_callback, + gpointer notify_user_data, + GError ** error) +{ + NMLldpListener *self = NULL; + sd_lldp * lldp_handle; + int r; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + g_return_val_if_fail(notify_callback, FALSE); + + r = sd_lldp_new(&lldp_handle); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -934,189 +950,77 @@ nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error) return FALSE; } - ret = sd_lldp_set_ifindex(priv->lldp_handle, ifindex); - if (ret < 0) { + r = sd_lldp_set_ifindex(lldp_handle, ifindex); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "failed setting ifindex"); - goto err; + goto fail_handle; } - 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; - } + r = sd_lldp_set_neighbors_max(lldp_handle, MAX_NEIGHBORS); + nm_assert(r == 0); - ret = sd_lldp_set_neighbors_max(priv->lldp_handle, MAX_NEIGHBORS); - nm_assert(ret == 0); + self = g_slice_new(NMLldpListener); + *self = (NMLldpListener){ + .ifindex = ifindex, + .notify_callback = notify_callback, + .notify_user_data = notify_user_data, + }; - priv->ifindex = ifindex; + r = sd_lldp_set_callback(lldp_handle, lldp_event_handler, self); + if (r < 0) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "set callback failed"); + goto fail_handle; + } - ret = sd_lldp_attach_event(priv->lldp_handle, NULL, 0); - if (ret < 0) { + r = sd_lldp_attach_event(lldp_handle, NULL, 0); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "attach event failed"); - goto err_free; + goto fail_attached; } - ret = sd_lldp_start(priv->lldp_handle); - if (ret < 0) { + r = sd_lldp_start(lldp_handle); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "start failed"); - goto err; + goto fail_attached; } - priv->lldp_neighbors = g_hash_table_new_full(lldp_neighbor_id_hash, + self->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); -err_free: - sd_lldp_unref(priv->lldp_handle); - priv->lldp_handle = NULL; - priv->ifindex = 0; - return FALSE; + self->lldp_handle = lldp_handle; + + _LOGD("start lldp listener"); + return self; + +fail_attached: + sd_lldp_detach_event(lldp_handle); +fail_handle: + if (self) + nm_g_slice_free(self); + sd_lldp_unref(lldp_handle); + return NULL; } void -nm_lldp_listener_stop(NMLldpListener *self) +nm_lldp_listener_destroy(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; - } + g_return_if_fail(self); - nm_clear_g_source(&priv->ratelimit_id); - priv->ratelimit_next_nsec = 0; - priv->ifindex = 0; + sd_lldp_stop(self->lldp_handle); + sd_lldp_detach_event(self->lldp_handle); + sd_lldp_unref(self->lldp_handle); - if (changed) - data_changed_notify(self, priv); -} - -gboolean -nm_lldp_listener_is_running(NMLldpListener *self) -{ - NMLldpListenerPrivate *priv; - - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - return !!priv->lldp_handle; -} - -GVariant * -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; -} - -static void -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; - } -} - -static void -nm_lldp_listener_init(NMLldpListener *self) -{ - _LOGT("lldp listener created"); -} + nm_clear_g_source_inst(&self->ratelimit_source); -NMLldpListener * -nm_lldp_listener_new(void) -{ - return g_object_new(NM_TYPE_LLDP_LISTENER, NULL); -} + g_hash_table_destroy(self->lldp_neighbors); -static void -dispose(GObject *object) -{ - nm_lldp_listener_stop(NM_LLDP_LISTENER(object)); - - G_OBJECT_CLASS(nm_lldp_listener_parent_class)->dispose(object); -} - -static void -finalize(GObject *object) -{ - NMLldpListener * self = NM_LLDP_LISTENER(object); - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - nm_lldp_listener_stop(self); - - nm_clear_g_variant(&priv->variant); + nm_g_variant_unref(self->variant); _LOGT("lldp listener destroyed"); - G_OBJECT_CLASS(nm_lldp_listener_parent_class)->finalize(object); -} - -static void -nm_lldp_listener_class_init(NMLldpListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - 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); - - g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + nm_g_slice_free(self); } diff --git a/src/core/devices/nm-lldp-listener.h b/src/core/devices/nm-lldp-listener.h index 9d3e2436..762eb3d2 100644 --- a/src/core/devices/nm-lldp-listener.h +++ b/src/core/devices/nm-lldp-listener.h @@ -6,28 +6,21 @@ #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_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); +/*****************************************************************************/ +typedef void (*NMLldpListenerNotify)(NMLldpListener *self, gpointer user_data); + +NMLldpListener *nm_lldp_listener_new(int ifindex, + NMLldpListenerNotify notify_callback, + gpointer notify_user_data, + GError ** error); +void nm_lldp_listener_destroy(NMLldpListener *self); + +int nm_lldp_listener_get_ifindex(NMLldpListener *self); GVariant *nm_lldp_listener_get_neighbors(NMLldpListener *self); +/*****************************************************************************/ + GVariant *nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len); #endif /* __NM_LLDP_LISTENER__ */ diff --git a/src/core/devices/ovs/meson.build b/src/core/devices/ovs/meson.build index 81c29bd6..1974ff4c 100644 --- a/src/core/devices/ovs/meson.build +++ b/src/core/devices/ovs/meson.build @@ -13,7 +13,6 @@ libnm_device_plugin_ovs = shared_module( core_plugin_dep, jansson_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c index 3ae8a481..26a5ba00 100644 --- a/src/core/devices/ovs/nm-device-ovs-bridge.c +++ b/src/core/devices/ovs/nm-device-ovs-bridge.c @@ -16,7 +16,7 @@ #include "nm-setting-connection.h" #include "nm-setting-ovs-bridge.h" #include "nm-setting-ovs-external-ids.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceOvsBridge #include "devices/nm-device-logging.h" @@ -134,9 +134,7 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 0a537f7a..46a612ac 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -414,10 +414,7 @@ dispose(GObject *object) } 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, ), }; static void diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index 2ecb95e8..f11c5852 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -167,9 +167,7 @@ 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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c index e7af38d8..6f5d8832 100644 --- a/src/core/devices/ovs/nm-ovs-factory.c +++ b/src/core/devices/ovs/nm-ovs-factory.c @@ -10,8 +10,8 @@ #include "nm-device-ovs-interface.h" #include "nm-device-ovs-port.h" #include "nm-device-ovs-bridge.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-private.h" diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index da3a7989..b8d5311a 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -10,10 +10,10 @@ #include <gmodule.h> #include <gio/gunixsocketaddress.h> -#include "nm-glib-aux/nm-jansson.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-core-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device.h" #include "nm-manager.h" #include "nm-setting-ovs-external-ids.h" diff --git a/src/core/devices/team/meson.build b/src/core/devices/team/meson.build index d0ff4caa..b1ee9103 100644 --- a/src/core/devices/team/meson.build +++ b/src/core/devices/team/meson.build @@ -11,7 +11,6 @@ libnm_device_plugin_team = shared_module( jansson_dep, libteamdctl_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index d2d71729..0f1a8c4c 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -15,15 +15,15 @@ #include <teamdctl.h> #include <stdlib.h> -#include "nm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-jansson.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "nm-ip4-config.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #define _NMLOG_DEVICE_TYPE NMDeviceTeam #include "devices/nm-device-logging.h" @@ -829,12 +829,12 @@ enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gbool "enslaved team port %s config not changed, not connected to teamd", slave_iface); } else { - int err; - char *sanitized_config; + gs_free char *sanitized_config = NULL; + int err; - sanitized_config = g_strdelimit(g_strdup(config), "\r\n", ' '); + sanitized_config = g_strdup(config); + g_strdelimit(sanitized_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)", @@ -1042,17 +1042,13 @@ dispose(GObject *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Config", + "s", + NM_DEVICE_TEAM_CONFIG), ), ), }; static void diff --git a/src/core/devices/team/nm-team-factory.c b/src/core/devices/team/nm-team-factory.c index 57b51bf8..e2040d19 100644 --- a/src/core/devices/team/nm-team-factory.c +++ b/src/core/devices/team/nm-team-factory.c @@ -10,8 +10,8 @@ #include "nm-manager.h" #include "devices/nm-device-factory.h" #include "nm-device-team.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/devices/tests/test-acd.c b/src/core/devices/tests/test-acd.c index b0af59db..b4b65165 100644 --- a/src/core/devices/tests/test-acd.c +++ b/src/core/devices/tests/test-acd.c @@ -78,8 +78,8 @@ fixture_setup(test_fixture *fixture, gconstpointer user_data) 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)); + g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex0, IFF_UP, TRUE) >= 0); + g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex1, IFF_UP, TRUE) >= 0); fixture->hwaddr0 = nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len); diff --git a/src/core/devices/tests/test-lldp.c b/src/core/devices/tests/test-lldp.c index ef0b1549..c64c7c11 100644 --- a/src/core/devices/tests/test-lldp.c +++ b/src/core/devices/tests/test-lldp.c @@ -13,7 +13,7 @@ #include <sys/types.h> #include "devices/nm-lldp-listener.h" -#include "systemd/nm-sd.h" +#include "libnm-systemd-core/nm-sd.h" #include "platform/tests/test-common.h" @@ -83,6 +83,7 @@ typedef struct { 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 = { \ @@ -92,11 +93,17 @@ typedef struct { } typedef struct { + int num_called; + GMainLoop *loop_to_quit; +} TestRecvCallbackInfo; + +typedef struct { guint expected_num_called; gsize frames_len; const TestRecvFrame *frames[10]; - void (*check)(GMainLoop *loop, NMLldpListener *listener); + void (*check)(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info); } TestRecvData; + #define TEST_RECV_DATA_DEFINE(name, _expected_num_called, _check, ...) \ static const TestRecvData name = { \ .expected_num_called = _expected_num_called, \ @@ -213,7 +220,7 @@ _test_recv_data0_check_do(GMainLoop *loop, NMLldpListener *listener, const TestR } static void -_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { _test_recv_data0_check_do(loop, listener, &_test_recv_data0_frame0); } @@ -528,7 +535,7 @@ TEST_RECV_FRAME_DEFINE( ); static void -_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { GVariant * neighbors, *attr, *child; gs_unref_variant GVariant *neighbor = NULL; @@ -756,21 +763,17 @@ TEST_RECV_FRAME_DEFINE( ); static void -_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { - 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); + info->loop_to_quit = loop; if (!nmtst_main_loop_run(loop, 5000)) g_assert_not_reached(); - nm_clear_g_signal_handler(listener, ¬ify_id); + info->loop_to_quit = NULL; neighbors = nm_lldp_listener_get_neighbors(listener); nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); @@ -852,46 +855,37 @@ again: memcpy(fixture->mac, link->l_address.data, ETH_ALEN); } -typedef struct { - int num_called; -} TestRecvCallbackInfo; - static void -lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) +lldp_neighbors_changed(NMLldpListener *lldp_listener, gpointer user_data) { TestRecvCallbackInfo *info = user_data; info->num_called++; + if (info->loop_to_quit) + g_main_loop_quit(info->loop_to_quit); } static void 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; + NMLldpListener * listener; + GMainLoop * loop; + TestRecvCallbackInfo info = {}; + gsize i_frames; + GError * error = NULL; + guint sd_id; 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(fixture->ifindex, lldp_neighbors_changed, &info, &error); + nmtst_assert_success(listener, 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(); + 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]; @@ -904,9 +898,9 @@ test_recv(TestRecvFixture *fixture, gconstpointer user_data) g_assert_cmpint(info.num_called, ==, data->expected_num_called); - nm_clear_g_signal_handler(listener, ¬ify_id); + data->check(loop, listener, &info); - data->check(loop, listener); + nm_clear_pointer(&listener, nm_lldp_listener_destroy); nm_clear_g_source(&sd_id); nm_clear_pointer(&loop, g_main_loop_unref); diff --git a/src/core/devices/wifi/meson.build b/src/core/devices/wifi/meson.build index 743937db..85553c53 100644 --- a/src/core/devices/wifi/meson.build +++ b/src/core/devices/wifi/meson.build @@ -22,7 +22,6 @@ libnm_device_plugin_wifi_static = static_library( dependencies: [ core_plugin_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_wifi_static_dep = declare_dependency( @@ -38,7 +37,6 @@ libnm_device_plugin_wifi = shared_module( core_plugin_dep, libnm_device_plugin_wifi_static_dep ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 01f2a303..56338743 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -13,16 +13,16 @@ #include "devices/nm-device.h" #include "nm-act-request.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-iwd-manager.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-wireless-security.h" #include "nm-setting-wireless.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" #include "nm-wifi-common.h" #include "nm-wifi-utils.h" @@ -55,7 +55,7 @@ typedef struct { CList aps_lst_head; NMWifiAP * current_ap; GCancellable * cancellable; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; NMActRequestGetSecretsCallId *wifi_secrets_id; guint periodic_scan_id; guint periodic_update_id; @@ -265,7 +265,7 @@ ap_from_network(NMDeviceIwd *self, .bss_path = bss_path, .last_seen_msec = last_seen_msec, .bssid_valid = TRUE, - .mode = NM_802_11_MODE_INFRA, + .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), @@ -812,7 +812,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Access Point mode"); @@ -830,7 +830,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Ad-Hoc mode"); @@ -1045,16 +1045,15 @@ complete_connection(NMDevice * device, } ssid_utf8 = iwd_ssid_to_str(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); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + ssid_utf8, + ssid_utf8, + NULL, + NULL, + TRUE); if (hidden) g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -1317,6 +1316,7 @@ static gboolean try_reply_agent_request(NMDeviceIwd * self, NMConnection * connection, GDBusMethodInvocation *invocation, + gboolean allow_existing, const char ** setting_name, const char ** setting_key, gboolean * replied) @@ -1331,56 +1331,64 @@ try_reply_agent_request(NMDeviceIwd * self, *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"); + if (allow_existing) { + const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); - *replied = TRUE; - return TRUE; + 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"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_private_key_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + 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; + const char *identity; 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; + if (allow_existing) { + const char *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; @@ -1390,18 +1398,19 @@ try_reply_agent_request(NMDeviceIwd * self, *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"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + 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; @@ -1452,6 +1461,8 @@ wifi_secrets_cb(NMActRequest * req, gboolean replied; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_utils_user_data_unpack(user_data, &self, &invocation); @@ -1484,9 +1495,18 @@ wifi_secrets_cb(NMActRequest * req, goto secrets_error; } + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + } + if (!try_reply_agent_request(self, - nm_act_request_get_applied_connection(req), + connection, invocation, + TRUE, &setting_name, &setting_key, &replied)) @@ -1512,9 +1532,6 @@ wifi_secrets_cb(NMActRequest * req, 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; @@ -1606,8 +1623,6 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data) dbus_error = g_dbus_error_get_remote_error(error); 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") && priv->secrets_failed) { @@ -2621,9 +2636,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_MODE: if (!priv->current_ap) - g_value_set_uint(value, NM_802_11_MODE_UNKNOWN); + 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); + g_value_set_uint(value, _NM_802_11_MODE_AP); else g_value_set_uint(value, nm_wifi_ap_get_mode(priv->current_ap)); @@ -3045,7 +3060,7 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) GVariantIter * iter; const char * mode; gboolean powered; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; if (!nm_g_object_ref_set(&priv->dbus_obj, object)) return; @@ -3107,14 +3122,14 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) goto error; } - capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; + 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; + capabilities |= _NM_WIFI_DEVICE_CAP_AP; else if (nm_streq(mode, "ad-hoc")) - capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; + capabilities |= _NM_WIFI_DEVICE_CAP_ADHOC; } g_variant_iter_free(iter); @@ -3156,8 +3171,11 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) const char * setting_key; gboolean replied; NMWifiAP * ap; + gboolean allow_existing = FALSE; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_auto_ref_string NMRefString *network_path = NULL; if (!invocation) { @@ -3261,9 +3279,37 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) /* Otherwise handle as usual */ } + /* Normally for PSK networks require new secret every time IWD asks for + * it. IWD only queries us if it has not saved the PSK (e.g. by policy) + * or a previous attempt has failed with current secrets so it wants a + * fresh value. It doesn't know about agent-owned secrets so whenever + * possible and the PSK is saved and not asked from NM. 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). + * + * For 802.1x, since IWD assumes the network is pre-provisioned by an + * admin and tested, there's no reason for IWD to save secrets in + * the network config file and there's no reason to ask for a new value + * of a saved (i.e. system-owned) secret because it can't be wrong. + * Since NM has a richer set of secret storage options we never specify + * NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW and let + * nm_settings_connection_get_secrets decide. + */ + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + else + allow_existing = TRUE; + } + if (!try_reply_agent_request(self, - nm_device_get_applied_connection(device), + connection, invocation, + allow_existing, &setting_name, &setting_key, &replied)) { @@ -3274,17 +3320,6 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) 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_device_get_settings_connection(device), NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NO_SECRETS); wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); @@ -3463,9 +3498,9 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) 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, + _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, @@ -3496,7 +3531,7 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_IWD_SCANNING, diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index af83c4a3..040350d5 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -28,7 +28,7 @@ #include "nm-setting-connection.h" #include "nm-setting-olpc-mesh.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh #include "devices/nm-device-logging.h" @@ -122,6 +122,17 @@ complete_connection(NMDevice * device, /*****************************************************************************/ +static const char * +get_dhcp_anycast_address(NMDevice *device) +{ + NMSettingOlpcMesh *s_mesh; + + s_mesh = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OLPC_MESH); + return s_mesh ? nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh) : NULL; +} + +/*****************************************************************************/ + static NMActStageReturn act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { @@ -178,7 +189,6 @@ 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); @@ -197,9 +207,6 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) 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; @@ -492,19 +499,15 @@ dispose(GObject *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( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Companion", + "o", + NM_DEVICE_OLPC_MESH_COMPANION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE( "ActiveChannel", "u", NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), ), ), - .legacy_property_changed = TRUE, }; static void @@ -531,6 +534,7 @@ nm_device_olpc_mesh_class_init(NMDeviceOlpcMeshClass *klass) 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; + device_class->get_dhcp_anycast_address = get_dhcp_anycast_address; obj_properties[PROP_COMPANION] = g_param_spec_string(NM_DEVICE_OLPC_MESH_COMPANION, "", diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c index fb987600..a8ea2ed7 100644 --- a/src/core/devices/wifi/nm-device-wifi-p2p.c +++ b/src/core/devices/wifi/nm-device-wifi-p2p.c @@ -15,16 +15,16 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" #include "nm-act-request.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-ip4-config.h" #include "nm-manager.h" #include "nm-manager.h" #include "nm-setting-wifi-p2p.h" #include "nm-utils.h" #include "nm-wifi-p2p-peer.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifiP2P @@ -1149,7 +1149,6 @@ static const NMDBusInterfaceInfoExtended interface_info_device_wifi_p2p = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Peers", "ao", NM_DEVICE_WIFI_P2P_PEERS), ), ), - .legacy_property_changed = FALSE, }; /*****************************************************************************/ diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index c9655eea..fca2fde5 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -12,11 +12,11 @@ #include <unistd.h> #include <linux/if_ether.h> -#include "nm-glib-aux/nm-ref-string.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-device-wifi-p2p.h" #include "nm-wifi-ap.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-dbus-manager.h" @@ -33,13 +33,13 @@ #include "nm-setting-ip4-config.h" #include "nm-ip4-config.h" #include "nm-setting-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-auth-utils.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-wifi-utils.h" #include "nm-wifi-common.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifi @@ -114,11 +114,11 @@ typedef struct { 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; + _NM80211Mode mode; guint32 failed_iface_count; gint32 hw_addr_scan_expire; @@ -487,7 +487,7 @@ _scan_notify_allowed(NMDeviceWifi *self, NMTernary do_kickoff) 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)) { + } 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)) { @@ -678,7 +678,7 @@ update_seen_bssids_cache(NMDeviceWifi *self, NMWifiAP *ap) return; /* Don't cache the BSSID for Ad-Hoc APs */ - if (nm_wifi_ap_get_mode(ap) != NM_802_11_MODE_INFRA) + 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 @@ -712,10 +712,11 @@ set_current_ap(NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available_ priv->current_ap = NULL; if (old_ap) { - NM80211Mode mode = nm_wifi_ap_get_mode(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)) + 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); } @@ -750,7 +751,7 @@ periodic_update(NMDeviceWifi *self) return; } - if (priv->mode == NM_802_11_MODE_AP) { + if (priv->mode == _NM_802_11_MODE_AP) { /* In AP mode we currently have nothing to do. */ return; } @@ -845,14 +846,14 @@ remove_all_aps(NMDeviceWifi *self) static gboolean 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) + if (w == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + 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); @@ -937,14 +938,14 @@ deactivate(NMDevice *device) * (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_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_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; + if (priv->mode != _NM_802_11_MODE_INFRA) { + priv->mode = _NM_802_11_MODE_INFRA; _notify(self, PROP_MODE); } @@ -1010,14 +1011,14 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * /* 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)) { + 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)) { + 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"); @@ -1034,7 +1035,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * } } } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { + 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"); @@ -1381,8 +1382,8 @@ _hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset) 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; + gs_free char *hw_addr_scan = NULL; + const char * generate_mac_address_mask; /* the random MAC address for scanning expires after a while. * @@ -1433,7 +1434,7 @@ ssids_options_to_ptrarray(GVariant *value, GError **error) v = g_variant_get_child_value(value, i); bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8)); - if (len > 32) { + if (len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_ARGUMENT, @@ -1822,7 +1823,7 @@ _scan_kickoff(NMDeviceWifi *self) 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] = _nm_utils_ssid_to_string_gbytes(ssids->pdata[i]); strv[i] = NULL; nm_assert(ssids->len > 0); @@ -1884,13 +1885,13 @@ ap_list_dump(gpointer user_data) _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), + (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)) + (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); @@ -1986,19 +1987,19 @@ supplicant_iface_bss_changed_cb(NMSupplicantInterface *iface, /* 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)) { + if (!ssid || _nm_utils_is_empty_ssid_gbytes(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)) { + if (ssid && !_nm_utils_is_empty_ssid_gbytes(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))); + (s = _nm_utils_ssid_to_string_gbytes(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)); @@ -2481,9 +2482,9 @@ supplicant_iface_state(NMDeviceWifi * self, _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))); + priv->mode == _NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" + : "Connected to wireless network", + (ssid_str = _nm_utils_ssid_to_string_gbytes(ssid))); nm_device_activate_schedule_stage3_ip_config_start(device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update(self); @@ -2599,9 +2600,9 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, _LOGD(LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", old_bssid ?: "(none)", - (old_ssid_s = _nm_utils_ssid_to_string(old_ssid)), + (old_ssid_s = _nm_utils_ssid_to_string_gbytes(old_ssid)), new_bssid ?: "(none)", - (new_ssid_s = _nm_utils_ssid_to_string(new_ssid))); + (new_ssid_s = _nm_utils_ssid_to_string_gbytes(new_ssid))); if (new_bssid) { /* The new AP could be in a different layer 3 network @@ -2790,21 +2791,21 @@ supplicant_connection_timeout_cb(gpointer user_data) 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)) { + 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"); + 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); + g_assert(priv->mode == _NM_802_11_MODE_INFRA); if (priv->ssid_found && nm_connection_get_setting_wireless_security(connection)) { guint64 timestamp = 0; @@ -2956,9 +2957,10 @@ error: static gboolean wake_on_wlan_enable(NMDeviceWifi *self) { - NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - NMSettingWirelessWakeOnWLan wowl; - NMSettingWireless * s_wireless; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWirelessWakeOnWLan wowl; + _NMSettingWirelessWakeOnWLan wowl2; + NMSettingWireless * s_wireless; s_wireless = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_WIRELESS); if (s_wireless) { @@ -2990,9 +2992,11 @@ wake_on_wlan_enable(NMDeviceWifi *self) goto found; wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + found: - if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { - priv->wowlan_restore = wowl; + wowl2 = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_CAST(wowl); + if (wowl2 == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { + priv->wowlan_restore = wowl2; return TRUE; } @@ -3001,7 +3005,7 @@ found: return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self)), - wowl); + wowl2); } static NMActStageReturn @@ -3030,16 +3034,16 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) 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; + 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; + 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; + 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; + priv->mode = _NM_802_11_MODE_MESH; _notify(self, PROP_MODE); /* expire the temporary MAC address used during scanning */ @@ -3052,7 +3056,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) } /* 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)) { + 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; } @@ -3154,7 +3158,7 @@ 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; + _NM80211Mode ap_mode; NMActRequest * req; NMWifiAP * ap; NMConnection * connection; @@ -3221,10 +3225,11 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) * 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)) + 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) + if (ap_mode == _NM_802_11_MODE_INFRA) set_powersave(device); /* Build up the supplicant configuration */ @@ -3341,7 +3346,7 @@ act_stage4_ip_config_timeout(NMDevice * 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) + if (priv->mode == _NM_802_11_MODE_AP) goto call_parent; if (may_fail || !is_static_wep(connection)) { @@ -3694,8 +3699,8 @@ nm_device_wifi_init(NMDeviceWifi *self) 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->mode = _NM_802_11_MODE_INFRA; + priv->wowlan_restore = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; } static void @@ -3706,7 +3711,7 @@ constructed(GObject *object) G_OBJECT_CLASS(nm_device_wifi_parent_class)->constructed(object); - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + if (priv->capabilities & _NM_WIFI_DEVICE_CAP_AP) _LOGI(LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ @@ -3714,7 +3719,7 @@ constructed(GObject *object) } NMDevice * -nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities) +nm_device_wifi_new(const char *iface, _NMDeviceWifiCapabilities capabilities) { return g_object_new(NM_TYPE_DEVICE_WIFI, NM_DEVICE_IFACE, @@ -3822,9 +3827,9 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) 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, + _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, @@ -3855,7 +3860,7 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _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, diff --git a/src/core/devices/wifi/nm-device-wifi.h b/src/core/devices/wifi/nm-device-wifi.h index d9e9038c..c7ff1a14 100644 --- a/src/core/devices/wifi/nm-device-wifi.h +++ b/src/core/devices/wifi/nm-device-wifi.h @@ -33,7 +33,7 @@ typedef struct _NMDeviceWifiClass NMDeviceWifiClass; 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); diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index 68a74438..56386c57 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -8,14 +8,20 @@ #include "nm-iwd-manager.h" #include <net/if.h> +#include <glib/gstdio.h> +#include <errno.h> +#include <sys/stat.h> -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-manager.h" #include "nm-device-iwd.h" #include "nm-wifi-utils.h" -#include "nm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "settings/nm-settings.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" +#include "nm-config.h" /*****************************************************************************/ @@ -28,6 +34,7 @@ typedef struct { typedef struct { GDBusProxy * known_network; NMSettingsConnection *mirror_connection; + const KnownNetworkId *id; } KnownNetworkData; typedef struct { @@ -40,6 +47,8 @@ typedef struct { char * agent_path; GHashTable * known_networks; NMDeviceIwd * last_agent_call_device; + char * last_state_dir; + char * warned_state_dir; } NMIwdManagerPrivate; struct _NMIwdManager { @@ -419,25 +428,94 @@ known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data) variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); if (!variant) { nm_log_warn(LOGD_WIFI, - "Updating %s on IWD known network %s failed: %s", + "iwd: updating %s on IWD known network %s failed: %s", (const char *) user_data, g_dbus_proxy_get_object_path(G_DBUS_PROXY(source)), error->message); } } +static gboolean +iwd_config_write(GKeyFile * config, + const char * filepath, + const struct timespec *mtime, + GError ** error) +{ + gsize length; + gs_free char * data = g_key_file_to_data(config, &length, NULL); + struct timespec times[2] = {{.tv_nsec = UTIME_OMIT}, *mtime}; + + /* Atomically write or replace the file with the right permission bits + * and timestamps set. We rely on the temporary file created by + * nm_utils_file_set_contents having only upper-case letters and digits + * in the last few filename characters -- it cannot end in .open, .psk + * or .8021x. + */ + return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, error); +} + +static const char * +get_config_path(NMIwdManager *self) +{ + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + const char * path; + + path = nm_config_data_get_iwd_config_path(NM_CONFIG_GET_DATA); + if (path && path[0] == '\0') { + nm_clear_g_free(&priv->warned_state_dir); + return NULL; + } + + if (!path || nm_streq(path, "auto")) { + path = priv->last_state_dir; + if (!path) { + nm_clear_g_free(&priv->warned_state_dir); + return NULL; + } + } + + if (priv->warned_state_dir && !nm_streq(priv->warned_state_dir, path)) + nm_clear_g_free(&priv->warned_state_dir); + + if (path && (path[0] != '/' || !g_file_test(path, G_FILE_TEST_IS_DIR))) { + if (!priv->warned_state_dir) { + priv->warned_state_dir = g_strdup(path); + _LOGW("IWD StateDirectory '%s' not accessible", priv->warned_state_dir); + } + return NULL; + } + + return path; +} + static void -sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNetworkData *data) +sett_conn_changed(NMSettingsConnection * sett_conn, + guint update_reason, + const KnownNetworkData *data) { NMSettingsConnectionIntFlags flags; - NMConnection * conn = nm_settings_connection_get_connection(sett_conn); - NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); - gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); - gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(conn); + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + NMIwdNetworkSecurity security; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + gboolean removed; + GStatBuf statbuf; + gboolean have_mtime; nm_assert(sett_conn == data->mirror_connection); - if (iwd_autoconnectable == nm_autoconnectable) + if (!NM_FLAGS_ANY(update_reason, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS)) return; /* If this is a generated connection it may be ourselves updating it */ @@ -445,21 +523,131 @@ sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNet if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) return; + iwd_dir = get_config_path(nm_iwd_manager_get()); + if (!iwd_dir) { + gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); + gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + + if (iwd_autoconnectable != nm_autoconnectable) { + nm_log_dbg(LOGD_WIFI, + "iwd: updating AutoConnect on known network at %s based on connection %s", + g_dbus_proxy_get_object_path(data->known_network), + nm_settings_connection_get_id(data->mirror_connection)); + g_dbus_proxy_call(data->known_network, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", + NM_IWD_KNOWN_NETWORK_INTERFACE, + "AutoConnect", + g_variant_new_boolean(nm_autoconnectable)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + known_network_update_cb, + "AutoConnect"); + } + + return; + } + + /* If the SSID and the security type in the NMSettingsConnection haven't + * changed, we just need to overwrite the original IWD config file. + * Otherwise we need to call Forget on the original KnownNetwork or + * remove its file. IWD will have to delete one D-Bus object and + * create another anyway because the SSID and security type are in the + * D-Bus object path, so no point renaming the file. + */ + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + removed = FALSE; + have_mtime = FALSE; + + if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security) + || security != data->id->security || !ssid_data || ssid_len != strlen(data->id->name) + || memcmp(ssid_data, data->id->name, ssid_len)) { + gs_free char *orig_filename = + nm_wifi_utils_get_iwd_config_filename(data->id->name, -1, data->id->security); + gs_free char *orig_full_path = g_strdup_printf("%s/%s", iwd_dir, orig_filename); + + if (g_stat(orig_full_path, &statbuf) == 0) + have_mtime = TRUE; + + if (g_remove(orig_full_path) == 0) + nm_log_dbg(LOGD_WIFI, "iwd: profile at %s removed", orig_full_path); + else if (errno != ENOENT) + nm_log_dbg(LOGD_WIFI, + "iwd: profile at %s not removed: %s (%i)", + orig_full_path, + strerror(errno), + errno); + + removed = TRUE; + } + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless") + || !s_wifi) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + nm_log_dbg( + LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (removed && g_file_test(full_path, G_FILE_TEST_EXISTS)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because %s " + "already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!removed && g_stat(full_path, &statbuf) == 0) + have_mtime = TRUE; + + /* If modifying an existing network try to preserve the file mtime, + * otherwise use a small non-zero timespec value to signal that the + * network is autoconnectable (according to its AutoConnect value) + * but hasn't recently been connected to and thus shouldn't be + * prioritized by autoconnect. + */ + if (!have_mtime) { + statbuf.st_mtim.tv_sec = 1; + statbuf.st_mtim.tv_nsec = 0; + } + + if (!iwd_config_write(iwd_config, full_path, &statbuf.st_mtim, &error)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + nm_log_dbg(LOGD_WIFI, - "Updating AutoConnect on known network at %s based on connection %s", - g_dbus_proxy_get_object_path(data->known_network), - nm_settings_connection_get_id(data->mirror_connection)); - g_dbus_proxy_call(data->known_network, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new("(ssv)", - NM_IWD_KNOWN_NETWORK_INTERFACE, - "AutoConnect", - g_variant_new_boolean(nm_autoconnectable)), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - known_network_update_cb, - "AutoConnect"); + "iwd: changed Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } /* Look up an existing NMSettingsConnection for a network that has been @@ -590,8 +778,10 @@ mirror_connection(NMIwdManager * self, NULL); g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_HIDDEN, hidden, NULL); } else { - KnownNetworkData data = {known_network, settings_connection}; - sett_conn_changed(settings_connection, 0, &data); + KnownNetworkData data = {known_network, settings_connection, id}; + sett_conn_changed(settings_connection, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, + &data); } } @@ -621,7 +811,7 @@ mirror_connection(NMIwdManager * self, NM_SETTING_CONNECTION_ID, id->name, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_buf(uuid), + nm_uuid_generate_random_str_arr(uuid), NM_SETTING_CONNECTION_AUTOCONNECT, autoconnectable, NULL); @@ -779,6 +969,7 @@ interface_added(GDBusObjectManager *object_manager, } else { data = g_slice_new0(KnownNetworkData); data->known_network = g_object_ref(proxy); + data->id = id; g_hash_table_insert(priv->known_networks, id, data); } @@ -907,6 +1098,9 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint const guint8 * ssid_bytes; gsize ssid_len; NMSettingsConnection *new_mirror_conn; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &id.security)) return; @@ -923,8 +1117,12 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint ssid_buf[ssid_len] = '\0'; id.name = ssid_buf; data = g_hash_table_lookup(priv->known_networks, &id); - if (!data) - return; + if (!data) { + if (!g_utf8_validate((const char *) ssid_bytes, ssid_len, NULL)) + return; + + goto try_delete_file; + } if (data->mirror_connection != sett_conn) return; @@ -941,7 +1139,7 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint } if (!priv->running) - return; + goto try_delete_file; g_dbus_proxy_call(data->known_network, "Forget", @@ -951,6 +1149,91 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint NULL, NULL, NULL); + return; + +try_delete_file: + if (mirror_connection(self, &id, FALSE, NULL)) + return; + + iwd_dir = get_config_path(self); + if (!iwd_dir) + return; + + filename = nm_wifi_utils_get_iwd_config_filename(id.name, ssid_len, id.security); + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_remove(full_path) == 0) + _LOGD("IWD profile at %s removed", full_path); + else if (errno != ENOENT) + _LOGD("IWD profile at %s not removed: %s (%i)", full_path, strerror(errno), errno); +} + +static void +connection_added(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +{ + NMIwdManager * self = user_data; + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection *s_conn = nm_connection_get_setting_connection(conn); + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + NMSettingsConnectionIntFlags flags; + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless")) + return; + + iwd_dir = get_config_path(self); + if (!iwd_dir) + return; + + /* If this is a generated connection it may be ourselves creating it and + * directly assigning it to a KnownNetwork's .mirror_connection. + */ + flags = nm_settings_connection_get_flags(sett_conn); + if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_file_test(full_path, G_FILE_TEST_EXISTS)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because %s already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!g_key_file_save_to_file(iwd_config, full_path, &error)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + _LOGD("New Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } static gboolean @@ -1115,7 +1398,7 @@ device_removed(NMManager *manager, NMDevice *device, gpointer user_data) static int object_compare_interfaces(gconstpointer a, gconstpointer b) { - static const char *interface_order[] = { + static const char *const interface_order[] = { NM_IWD_KNOWN_NETWORK_INTERFACE, NM_IWD_NETWORK_INTERFACE, NM_IWD_DEVICE_INTERFACE, @@ -1146,6 +1429,56 @@ object_compare_interfaces(gconstpointer a, gconstpointer b) } static void +get_daemon_info_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv; + gs_unref_variant GVariant *properties = NULL; + gs_free_error GError *error = NULL; + GVariantIter * properties_iter; + const char * key; + GVariant * value; + + properties = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!properties) { + if (nm_utils_error_is_cancelled(error)) + return; + + nm_log_warn(LOGD_WIFI, "iwd: Daemon.GetInfo() failed: %s", error->message); + return; + } + + priv = NM_IWD_MANAGER_GET_PRIVATE(self); + + if (!g_variant_is_of_type(properties, G_VARIANT_TYPE("(a{sv})"))) { + _LOGE("Daemon.GetInfo returned type %s instead of (a{sv})", + g_variant_get_type_string(properties)); + return; + } + + g_variant_get(properties, "(a{sv})", &properties_iter); + + while (g_variant_iter_next(properties_iter, "{&sv}", &key, &value)) { + if (nm_streq(key, "StateDirectory")) { + if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + _LOGE("Daemon.GetInfo property %s is typed '%s' instead of 's'", + key, + g_variant_get_type_string(value)); + goto next; + } + + nm_clear_g_free(&priv->last_state_dir); + priv->last_state_dir = g_variant_dup_string(value, NULL); + } + +next: + g_variant_unref(value); + } + + g_variant_iter_free(properties_iter); +} + +static void got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) { NMIwdManager * self = user_data; @@ -1182,7 +1515,8 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) } if (_om_has_name_owner(object_manager)) { - GList *objects, *iter; + GList * objects, *iter; + gs_unref_object GDBusInterface *daemon = NULL; priv->running = true; @@ -1208,6 +1542,19 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) if (priv->agent_id) register_agent(self); + + daemon = g_dbus_object_manager_get_interface(object_manager, + "/net/connman/iwd", /* IWD 1.15+ */ + NM_IWD_DAEMON_INTERFACE); + if (daemon) + g_dbus_proxy_call(G_DBUS_PROXY(daemon), + "GetInfo", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + get_daemon_info_cb, + self); } } @@ -1305,11 +1652,31 @@ nm_iwd_manager_init(NMIwdManager *self) g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added), self); g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed), self); + /* The current logic is that we track all creations and removals but + * for modifications we only listen to those connections that are + * currently a KnownNetwork's mirror_connection. There may be multiple + * NMSettingsConnections referring to the same SSID+Security type tuple + * so to the same KnownNetwork. So to make connection profile editing + * work at least for the simple cases, we track one NMSettingsConnection + * out of those, and we map its changes to the IWD KnownNetwork. + * + * When an NMSettingsConnection is created by a user for a completely + * new network and the settings are compatible with IWD, we create an + * IWD KnownNetwork config file for it. IWD will notice that and a + * KnownNetwork objects pops up on D-Bus. We look up a suitable + * mirror_connection for it and only then subscribe to modification + * signals. There are various different ways that this could be done, + * it's not clear which one's the best. + */ priv->settings = g_object_ref(NM_SETTINGS_GET); g_signal_connect(priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK(connection_removed), self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK(connection_added), + self); priv->cancellable = g_cancellable_new(); @@ -1348,6 +1715,9 @@ dispose(GObject *object) priv->last_agent_call_device = NULL; + nm_clear_g_free(&priv->last_state_dir); + nm_clear_g_free(&priv->warned_state_dir); + G_OBJECT_CLASS(nm_iwd_manager_parent_class)->dispose(object); } diff --git a/src/core/devices/wifi/nm-iwd-manager.h b/src/core/devices/wifi/nm-iwd-manager.h index 466f67c7..e794e661 100644 --- a/src/core/devices/wifi/nm-iwd-manager.h +++ b/src/core/devices/wifi/nm-iwd-manager.h @@ -13,6 +13,7 @@ #define NM_IWD_BUS_TYPE G_BUS_TYPE_SYSTEM #define NM_IWD_SERVICE "net.connman.iwd" +#define NM_IWD_DAEMON_INTERFACE "net.connman.iwd.Daemon" #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" diff --git a/src/core/devices/wifi/nm-wifi-ap.c b/src/core/devices/wifi/nm-wifi-ap.c index 08fa10ec..20ed6833 100644 --- a/src/core/devices/wifi/nm-wifi-ap.c +++ b/src/core/devices/wifi/nm-wifi-ap.c @@ -13,13 +13,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-interface.h" #define PROTO_WPA "wpa" @@ -41,12 +41,12 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMWifiAP, 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) */ + 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). @@ -98,7 +98,7 @@ nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid) } l = g_bytes_get_size(ssid); - if (l == 0 || l > 32) + if (l == 0 || l > NM_IW_ESSID_MAX_SIZE) g_return_val_if_reached(FALSE); priv = NM_WIFI_AP_GET_PRIVATE(ap); @@ -191,24 +191,24 @@ nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr) return nm_wifi_ap_set_address_bin(ap, &addr_buf); } -NM80211Mode +_NM80211Mode 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; } 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)); + _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; @@ -513,34 +513,35 @@ nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64 nm_utils_get_monotonic_timestamp_msec_cached(&now_msec); - g_snprintf(str_buf, - buf_len, - "%17s %-35s [ %c %3u %3u%% %c%c %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->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', - priv->flags & NM_802_11_AP_FLAGS_WPS_PIN - ? 'p' - : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), - 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); + g_snprintf( + str_buf, + buf_len, + "%17s %-35s [ %c %3u %3u%% %c%c %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", + priv->address ?: "(none)", + (ssid_to_free = _nm_utils_ssid_to_string_gbytes(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->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', + priv->flags & NM_802_11_AP_FLAGS_WPS_PIN + ? 'p' + : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), + 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; } @@ -589,13 +590,13 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) mode = nm_setting_wireless_get_mode(s_wireless); if (mode) { - if (!strcmp(mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA)) + if (!strcmp(mode, "infrastructure") && (priv->mode != _NM_802_11_MODE_INFRA)) return FALSE; - if (!strcmp(mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC)) + 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)) + 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)) + if (!strcmp(mode, "mesh") && (priv->mode != _NM_802_11_MODE_MESH)) return FALSE; } @@ -624,7 +625,7 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) priv->flags, priv->wpa_flags, priv->rsn_flags, - priv->mode); + NM_802_11_MODE_CAST(priv->mode)); } gboolean @@ -713,7 +714,7 @@ nm_wifi_ap_init(NMWifiAP *self) c_list_init(&self->aps_lst); - priv->mode = NM_802_11_MODE_INFRA; + 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; @@ -758,19 +759,19 @@ nm_wifi_ap_new_fake_from_connection(NMConnection *connection) 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); + 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); + 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); + 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_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); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); } band = nm_setting_wireless_get_band(s_wireless); @@ -861,27 +862,21 @@ finalize(GObject *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, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", "u", NM_WIFI_AP_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ssid", "ay", NM_WIFI_AP_SSID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Frequency", "u", NM_WIFI_AP_FREQUENCY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_WIFI_AP_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_WIFI_AP_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("MaxBitrate", + "u", + NM_WIFI_AP_MAX_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Strength", "y", NM_WIFI_AP_STRENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastSeen", + "i", + NM_WIFI_AP_LAST_SEEN), ), ), }; static void @@ -955,9 +950,9 @@ nm_wifi_ap_class_init(NMWifiAPClass *ap_class) 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, + _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, diff --git a/src/core/devices/wifi/nm-wifi-ap.h b/src/core/devices/wifi/nm-wifi-ap.h index bdd72415..bffd28a8 100644 --- a/src/core/devices/wifi/nm-wifi-ap.h +++ b/src/core/devices/wifi/nm-wifi-ap.h @@ -10,6 +10,7 @@ #include "nm-dbus-object.h" #include "nm-dbus-interface.h" #include "nm-connection.h" +#include "libnm-base/nm-base.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)) @@ -69,7 +70,7 @@ 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); gboolean nm_wifi_ap_set_address_bin(NMWifiAP *ap, const NMEtherAddr *addr); -NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); +_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); diff --git a/src/core/devices/wifi/nm-wifi-common.c b/src/core/devices/wifi/nm-wifi-common.c index c715c07c..b98ef222 100644 --- a/src/core/devices/wifi/nm-wifi-common.c +++ b/src/core/devices/wifi/nm-wifi-common.c @@ -146,31 +146,25 @@ const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless = { .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, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&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("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_DEVICE_WIFI_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Bitrate", "u", NM_DEVICE_WIFI_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AccessPoints", + "ao", + NM_DEVICE_WIFI_ACCESS_POINTS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ActiveAccessPoint", + "o", + NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("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/core/devices/wifi/nm-wifi-factory.c b/src/core/devices/wifi/nm-wifi-factory.c index 40375e1c..d2269c74 100644 --- a/src/core/devices/wifi/nm-wifi-factory.c +++ b/src/core/devices/wifi/nm-wifi-factory.c @@ -15,7 +15,7 @@ #include "nm-device-olpc-mesh.h" #include "nm-device-iwd.h" #include "settings/nm-settings-connection.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" /*****************************************************************************/ @@ -74,7 +74,8 @@ create_device(NMDeviceFactory * factory, NMConnection * connection, gboolean * out_ignore) { - gs_free char *backend = NULL; + gs_free char *backend_free = NULL; + const char * backend; g_return_val_if_fail(iface != NULL, NULL); g_return_val_if_fail(plink != NULL, NULL); @@ -89,7 +90,7 @@ create_device(NMDeviceFactory * factory, plink, "wifi", NULL); - nm_strstrip(backend); + backend = nm_strstrip_avoid_copy_a(300, backend, &backend_free); nm_log_dbg(LOGD_PLATFORM | LOGD_WIFI, "(%s) config: backend is %s%s%s%s", @@ -97,9 +98,9 @@ create_device(NMDeviceFactory * factory, 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; + 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, @@ -114,7 +115,7 @@ create_device(NMDeviceFactory * factory, * 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) { + if (mode == _NM_802_11_MODE_UNKNOWN) { *out_ignore = TRUE; return NULL; } diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.c b/src/core/devices/wifi/nm-wifi-p2p-peer.c index 8488f32d..433c2833 100644 --- a/src/core/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/core/devices/wifi/nm-wifi-p2p-peer.c @@ -12,13 +12,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-types.h" /*****************************************************************************/ @@ -608,7 +608,6 @@ static const NMDBusInterfaceInfoExtended interface_info_p2p_peer = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastSeen", "i", NM_WIFI_P2P_PEER_LAST_SEEN), ), ), - .legacy_property_changed = FALSE, }; static void diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index aed236cc..15ced990 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -7,10 +7,14 @@ #include "nm-wifi-utils.h" +#include <arpa/inet.h> +#include <netinet/if_ether.h> #include <stdlib.h> #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-base/nm-config-base.h" static gboolean verify_no_wep(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -526,7 +530,7 @@ verify_adhoc(NMSettingWirelessSecurity *s_wsec, gboolean nm_wifi_utils_complete_connection(GBytes * ap_ssid, const char * bssid, - NM80211Mode ap_mode, + _NM80211Mode ap_mode, guint32 ap_freq, guint32 ap_flags, guint32 ap_wpa_flags, @@ -575,14 +579,14 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* 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) + 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) + 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) + if (ap_mode == _NM_802_11_MODE_MESH) valid = TRUE; mesh = TRUE; } @@ -600,10 +604,10 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, } } else { mode = NM_SETTING_WIRELESS_MODE_INFRA; - if (ap_mode == NM_802_11_MODE_ADHOC) { + 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) { + } else if (ap_mode == _NM_802_11_MODE_MESH) { mode = NM_SETTING_WIRELESS_MODE_MESH; mesh = TRUE; } @@ -810,15 +814,24 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, * 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)) { + } else if (nm_streq0(key_mgmt, "wpa-psk") + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE + && (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); + } else if (nm_streq0(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")) + } else if (nm_streq0(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, @@ -827,9 +840,8 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, 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)) { + } else if (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", @@ -839,7 +851,7 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* Leave proto/pairwise/group as client set them; if they are unset the * supplicant will figure out the best combination at connect time. */ - } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-eap-suite-b-192")) + } else if (nm_streq0(key_mgmt, "wpa-eap-suite-b-192") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192)) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, @@ -943,3 +955,865 @@ nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, return TRUE; } + +/*****************************************************************************/ + +/* Builds the IWD network configuration file name for a given SSID + * and security type pair. The SSID should be valid UTF-8 and in + * any case must contain no NUL-bytes. If @ssid is NUL-terminated, + * @ssid_len can be -1 instead of actual SSID length. + */ +char * +nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security) +{ + const char *security_suffix; + const char *ptr; + gboolean alnum_ssid = TRUE; + + for (ptr = ssid; ssid_len != 0 && *ptr != '\0'; ptr++, ssid_len--) + if (!g_ascii_isalnum(*ptr) && !strchr("-_ ", *ptr)) + alnum_ssid = FALSE; + + g_return_val_if_fail(ptr != ssid && ptr - ssid <= NM_IW_ESSID_MAX_SIZE, NULL); + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + security_suffix = "open"; + break; + case NM_IWD_NETWORK_SECURITY_PSK: + security_suffix = "psk"; + break; + case NM_IWD_NETWORK_SECURITY_8021X: + security_suffix = "8021x"; + break; + default: + return NULL; + } + + if (alnum_ssid) { + return g_strdup_printf("%.*s.%s", (int) (ptr - ssid), ssid, security_suffix); + } else { + char ssid_buf[NM_IW_ESSID_MAX_SIZE * 2 + 1]; + + return g_strdup_printf("=%s.%s", + nm_utils_bin2hexstr_full(ssid, ptr - ssid, '\0', FALSE, ssid_buf), + security_suffix); + } +} + +/*****************************************************************************/ + +#define SECRETS_DONT_STORE_FLAGS \ + (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED) + +static gboolean +psk_setting_to_iwd_config(GKeyFile *file, NMSettingWirelessSecurity *s_wsec, GError **error) +{ + NMSettingSecretFlags psk_flags = nm_setting_wireless_security_get_psk_flags(s_wsec); + const char * psk = nm_setting_wireless_security_get_psk(s_wsec); + gsize psk_len; + guint8 buffer[32]; + const char * key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + + if (!psk || NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) { + if (NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) { + nm_log_info( + LOGD_WIFI, + "IWD network config is being created wihout the PSK but IWD will save the PSK on " + "successful activation not honoring the psk-flags property"); + } + return TRUE; + } + + psk_len = strlen(psk); + if (nm_streq0(key_mgmt, "sae")) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len >= 8 && psk_len <= 63) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len == 64 && nm_utils_hexstr2bin_buf(psk, FALSE, FALSE, NULL, buffer)) { + g_key_file_set_string(file, "Security", "PreSharedKey", psk); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unknown PSK format"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_certs_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + bool phase2, + char * iwd_prefix, + GError ** error) +{ + NMSetting8021xCKScheme ca_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme(s_8021x) + : nm_setting_802_1x_get_ca_cert_scheme(s_8021x); + NMSetting8021xCKScheme client_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme(s_8021x) + : nm_setting_802_1x_get_client_cert_scheme(s_8021x); + NMSetting8021xCKScheme key_scheme; + NMSettingSecretFlags key_password_flags; + const char * ca_path = phase2 ? nm_setting_802_1x_get_phase2_ca_path(s_8021x) + : nm_setting_802_1x_get_ca_path(s_8021x); + const char * cert_path; + const char * key_path = NULL; + const char * key_password; + const char * domain_suffix_match; + const char * domain_match; + char setting_buf[128]; + + /* TODO: should check that all certificates and the key are RSA */ + /* Note: up to IWD 1.9 only the PEM encoding was supported for certificates + * and only PKCS#8 PEM for keys but we don't know the IWD version here. + * From IWD 1.10 raw (DER) X.509 certificates and PKCS#12 are also supported + * for certificates but a certificate list or chain still has to be PEM + * (i.e. if it contains more than one certificate.) Raw PKCS#12 and + * old-style OpenSSL PEM formats are also supported for keys. Hopefully + * this is in practice the same set of file:// formats as supported by + * nm_crypto_* / wpa_supplicant so we need no conversions here. + */ + + if (nm_setting_802_1x_get_system_ca_certs(s_8021x)) { + /* Either overrides or is added to the certificates in (phase2-)ca-cert + * and ca-path depending on whether it points to a file or a directory. + * We can't ignore this property so it's an error if it is set. + * Fortunately not used by nm-connection-editor. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The system-ca-certs property is not supported"); + return FALSE; + } + + if (ca_path) { + /* To support this (and this could be applied to system-ca-certs as + * well) we'd have to scan the directory, parse the certificates and + * write a new certificate-list file to point to in the IWD config. + * This is going to create issues of where to store these files, for + * how long and with what permission bits. Fortunately this doesn't + * seem to be used by nm-connection-editor either. + * + * That file would also have to contain whatever the (phase2-)ca-cert + * propterty points to because IWD has only one CACert setting per + * phase. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The (phase2-)ca-path property is not supported"); + return FALSE; + } + + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* To support the blob scheme we'd have to either convert the + * certificate data into a PEM payload and embed the PEM file in + * the IWD config file, which is not supported by GKeyFile, or write + * it into a new file to point to in the IWD config. This is again + * is going to create issues of where to store these files, for how + * long and with what permission bits. Fortunately this scheme isn't + * used in nm-connection-editor either. + * + * PKCS#11 is not supported by IWD in any way so we don't need to + * support the PKCS#11 URI scheme. + * + * If scheme is unknown, assume no value is set. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)ca-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path(s_8021x) + : nm_setting_802_1x_get_ca_cert_path(s_8021x); + if (cert_path) + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "CACert"), + cert_path); + } + + if (client_cert_scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) + goto private_key_done; + + if (client_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)client-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_client_cert_path(s_8021x) + : nm_setting_802_1x_get_client_cert_path(s_8021x); + if (!cert_path) + goto private_key_done; + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientCert"), + cert_path); + + key_scheme = phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme(s_8021x) + : nm_setting_802_1x_get_private_key_scheme(s_8021x); + if (key_scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + key_path = phase2 ? nm_setting_802_1x_get_phase2_private_key_path(s_8021x) + : nm_setting_802_1x_get_private_key_path(s_8021x); + if (key_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH || !key_path) { + /* The same comments apply to writing the key into a temporary file + * as for the certificates (above), except this is even more + * sensitive. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)private-key property schemes other than file:// not supported"); + return FALSE; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKey"), + key_path); + + key_password = phase2 ? nm_setting_802_1x_get_phase2_private_key_password(s_8021x) + : nm_setting_802_1x_get_private_key_password(s_8021x); + key_password_flags = phase2 ? nm_setting_802_1x_get_phase2_private_key_password_flags(s_8021x) + : nm_setting_802_1x_get_private_key_password_flags(s_8021x); + if (!key_password || NM_FLAGS_ANY(key_password_flags, SECRETS_DONT_STORE_FLAGS)) { + g_key_file_set_comment( + file, + "Security", + setting_buf, + "ClientKeyPassphrase not to be saved, will be queried through the agent if needed", + NULL); + goto private_key_done; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKeyPassphrase"), + key_password); + +private_key_done: + if (phase2 ? nm_setting_802_1x_get_phase2_subject_match(s_8021x) + : nm_setting_802_1x_get_subject_match(s_8021x)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)subject-match not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + if (phase2 ? nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x) + : nm_setting_802_1x_get_num_altsubject_matches(s_8021x)) { + /* We could convert the "DNS:" entries into a ServerDomainMask but we'd + * have to leave out the "EMAIL:" and "URI:" types or report error. + * The interpretation still wouldn't be exactly the same as in + * wpa_supplicant. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)altsubject-matches not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + domain_suffix_match = phase2 ? nm_setting_802_1x_get_phase2_domain_suffix_match(s_8021x) + : nm_setting_802_1x_get_domain_suffix_match(s_8021x); + domain_match = phase2 ? nm_setting_802_1x_get_phase2_domain_match(s_8021x) + : nm_setting_802_1x_get_domain_match(s_8021x); + + if (domain_suffix_match || domain_match) { + GString * s = g_string_sized_new(128); + const char *ptr; + const char *end; + + for (ptr = domain_suffix_match; ptr; ptr = *end == ';' ? end + 1 : NULL) { + if (s->len) + g_string_append_c(s, ';'); + end = strchrnul(ptr, ';'); + /* Use *.<suffix> to get the suffix match effect */ + g_string_append(s, "*."); + g_string_append_len(s, ptr, end - ptr); + } + + /* domain-match can be appended as-is */ + if (domain_match) { + if (s->len) + g_string_append_c(s, ';'); + g_string_append(s, domain_match); + } + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ServerDomainMask"), + s->str); + g_string_free(s, TRUE); + } + + return TRUE; +} + +static void +eap_method_name_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *method) +{ + char setting_buf[128]; + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + method); +} + +static void +eap_optional_identity_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *identity) +{ + char setting_buf[128]; + + /* The identity is optional for some methods where an authenticator may + * in theory not ask for it. For our usage here we treat it as always + * optional because it can be omitted in the config file if the user + * wants IWD to query for it on every connection. + */ + if (identity) { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Identity"), + identity); + } else { + g_key_file_set_comment( + file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Identity not to be saved, will be queried through the agent if needed", + NULL); + } +} + +static gboolean +eap_optional_password_to_iwd_config(GKeyFile * file, + const char * iwd_prefix, + NMSetting8021x *s_8021x, + GError ** error) +{ + char setting_buf[128]; + const char * password = nm_setting_802_1x_get_password(s_8021x); + NMSettingSecretFlags flags = nm_setting_802_1x_get_password_flags(s_8021x); + + if (!password && nm_setting_802_1x_get_password_raw(s_8021x)) { + /* IWD doesn't support passwords that can't be encoded in the config + * file, i.e. containing NUL characters. Those that don't have NULs + * could in theory be written to the config file but GKeyFile may not + * like that if they're no UTF-8, and the password-raw property is + * not written by nm-connection-editor anyway. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-UTF-8 passwords are not supported, if the password is UTF-8 set " + "the \"password\" property"); + return FALSE; + } + if (!password || NM_FLAGS_ANY(flags, SECRETS_DONT_STORE_FLAGS)) { + return g_key_file_set_comment(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Password not to be saved, will be queried through the agent", + error); + } else { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Password"), + password); + return TRUE; + } +} + +static void +eap_phase1_identity_to_iwd_config(GKeyFile *file, const char *iwd_prefix, NMSetting8021x *s_8021x) +{ + const char *phase1_identity = nm_setting_802_1x_get_anonymous_identity(s_8021x); + + if (!phase1_identity) { + phase1_identity = nm_setting_802_1x_get_identity(s_8021x); + + if (phase1_identity) { + nm_log_info(LOGD_WIFI, + "IWD network config will send the same EAP Identity string in " + "plaintext in phase 1 as in phase 2 (encrypted) to mimic legacy " + "behavior, set [%s].%s=anonymous to prevent exposing the value", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } + } + + eap_optional_identity_to_iwd_config(file, iwd_prefix, phase1_identity); +} + +static gboolean +eap_method_config_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + gboolean phase2, + const char * method, + const char * iwd_prefix, + GError ** error) +{ + char prefix_buf[128]; + + if (nm_streq0(method, "tls")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "TLS"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + + return eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TLS-"), + error); + } else if (nm_streq0(method, "ttls") && !phase2) { + const char *noneap_method = nm_setting_802_1x_get_phase2_auth(s_8021x); + + eap_method_name_to_iwd_config(file, iwd_prefix, "TTLS"); + eap_phase1_identity_to_iwd_config(file, iwd_prefix, s_8021x); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-"), + error)) + return FALSE; + + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-Phase2-"); + + if (nm_setting_802_1x_get_phase2_autheap(s_8021x)) { + if (noneap_method) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Only one TTLS phase 2 method can be set"); + return FALSE; + } + return eap_method_config_to_iwd_config(file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_autheap(s_8021x), + prefix_buf, + error); + } + + if (NM_IN_STRSET(noneap_method, "chap", "mschap", "mschapv2", "pap")) { + const char *iwd_method; + + if (nm_streq0(noneap_method, "chap")) { + iwd_method = "Tunneled-CHAP"; + } else if (nm_streq0(noneap_method, "mschap")) { + iwd_method = "Tunneled-MSCHAP"; + } else if (nm_streq0(noneap_method, "mschapv2")) { + iwd_method = "Tunneled-MSCHAPv2"; + } else { + iwd_method = "Tunneled-PAP"; + } + + eap_method_name_to_iwd_config(file, prefix_buf, iwd_method); + eap_optional_identity_to_iwd_config(file, + prefix_buf, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, prefix_buf, s_8021x, error); + } + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unsupported TTLS non-EAP inner method"); + return FALSE; + } else if (nm_streq0(method, "peap") && !phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PEAP"); + eap_phase1_identity_to_iwd_config(file, iwd_prefix, s_8021x); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-"), + error)) + return FALSE; + + if (nm_setting_802_1x_get_phase1_peapver(s_8021x) + || nm_setting_802_1x_get_phase1_peaplabel(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the PEAP version and label properties " + "in the 802.1x setting (unsupported)"); + + if (!nm_setting_802_1x_get_phase2_auth(s_8021x)) { + /* Apparently PEAP can be used without a phase 2 but this is not + * supported by either NM or IWD. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "PEAP without an inner method is unsupported"); + return FALSE; + } + + return eap_method_config_to_iwd_config( + file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_auth(s_8021x), + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-Phase2-"), + error); + } else if (nm_streq0(method, "md5") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MD5"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "gtc") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "GTC"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "pwd")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PWD"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "mschapv2")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MSCHAPV2"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + /* In this case we can support password-raw but would have to + * MD4-hash it and set as <iwd_prefix>Password-Hash + */ + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "external")) { + /* This may be a connection created by NMIwdManager in whch case there + * may be no need to be convert it back to the IWD format. Ideally we + * would still rewrite the other sections/groups in the IWD settings + * file and preserve the [Security] group -- TODO. Possibly this should + * also not be reported as an error. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection contains no EAP method configuration"); + return FALSE; + } else { + /* Some methods are only allowed in phase 1 or only phase 2. + * OTP, LEAP and FAST are not supported by IWD at all. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + phase2 ? "Unsupported phase 2 EAP method" + : "Unsupported phase 1 EAP method"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_setting_to_iwd_config(GKeyFile *file, NMSetting8021x *s_8021x, GError **error) +{ + const char *method; + + if (!s_8021x || nm_setting_802_1x_get_num_eap_methods(s_8021x) == 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The 802.1x setting is missing or no EAP method set"); + return FALSE; + } + + if (!nm_setting_verify(NM_SETTING(s_8021x), NULL, error)) + return FALSE; + + method = nm_setting_802_1x_get_eap_method(s_8021x, 0); + + if (nm_setting_802_1x_get_num_eap_methods(s_8021x) > 1) + nm_log_info(LOGD_WIFI, + "IWD network config will only contain the first EAP method: %s", + method); + + if (nm_setting_802_1x_get_phase1_auth_flags(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the TLSv1.x-disable flags in the 802.1x " + "setting (unsupported)"); + + if (nm_setting_802_1x_get_auth_timeout(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the auth-timeout property in the 802.1x " + "setting (unsupported)"); + + return eap_method_config_to_iwd_config(file, s_8021x, FALSE, method, "EAP-", error); +} + +static gboolean +ip4_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + struct in_addr ip; + + /* These settings are not acutally used unless global + * [General].EnableNetworkConfiguration is true, which we don't support. + * We add them for sake of completness, although many NMSettingIPConfig + * configurations can't be mapped to IWD configs and we simply ignore + * them. If they were to be used we'd need to add a few warnings. + */ + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + /* It doesn't matter whether we add the DNS under [IPv4] or [IPv6] + * except that with method=auto the list will override the + * DNS addresses received over the DHCP version corresponing to + * v4 or v6. + * Note ignore-auto-dns=false isn't supported, this list always + * overrides the DHCP DNSes. + */ + g_key_file_set_string(file, "IPv4", "DNS", s->str); + } + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + return TRUE; + + num = nm_setting_ip_config_get_num_addresses(s_ip); + if (num) { + NMIPAddress *addr = nm_setting_ip_config_get_address(s_ip, 0); + guint prefix = nm_ip_address_get_prefix(addr); + in_addr_t netmask = _nm_utils_ip4_prefix_to_netmask(prefix); + char buf[INET_ADDRSTRLEN]; + + nm_ip_address_get_address_binary(addr, &ip); + g_key_file_set_string(file, "IPv4", "Address", nm_ip_address_get_address(addr)); + g_key_file_set_string(file, "IPv4", "Netmask", _nm_utils_inet4_ntop(netmask, buf)); + } else { + inet_pton(AF_INET, "10.42.0.100", &ip); + g_key_file_set_string(file, "IPv4", "Address", "10.42.0.100"); + } + + if (nm_setting_ip_config_get_gateway(s_ip)) { + g_key_file_set_string(file, "IPv4", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + } else { + uint32_t val; + char buf[INET_ADDRSTRLEN]; + + /* IWD won't enable static IP unless both Address and Gateway are + * set so generate a gateway address if not known. + */ + val = (ntohl(ip.s_addr) & 0xfffffff0) + 1; + if (val == ntohl(ip.s_addr)) + val += 1; + g_key_file_set_string(file, "IPv4", "Gateway", _nm_utils_inet4_ntop(htonl(val), buf)); + } + + return TRUE; +} + +static gboolean +ip6_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + NMIPAddress *addr; + char buf[INET6_ADDRSTRLEN + 10]; + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + g_key_file_set_string(file, "IPv6", "DNS", s->str); + } + + if (!NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip), + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + g_key_file_set_boolean(file, "IPv6", "Enabled", TRUE); + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + if (!nm_setting_ip_config_get_num_addresses(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "IP address required for IPv6 manual config"); + return FALSE; + } + + addr = nm_setting_ip_config_get_address(s_ip, 0); + g_key_file_set_string(file, + "IPv6", + "Address", + nm_sprintf_buf(buf, + "%s/%u", + nm_ip_address_get_address(addr), + nm_ip_address_get_prefix(addr))); + if (nm_setting_ip_config_get_gateway(s_ip)) + g_key_file_set_string(file, "IPv6", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + return TRUE; +} + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *connection, + char ** out_filename, + GError ** error) +{ + NMSettingConnection * s_conn = nm_connection_get_setting_connection(connection); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(connection); + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + NMIwdNetworkSecurity security; + const char * cloned_mac_addr; + gs_free char * comment = NULL; + nm_auto_unref_keyfile GKeyFile *file = NULL; + + if (!s_conn || !s_wifi + || !nm_streq(nm_setting_connection_get_connection_type(s_conn), + NM_SETTING_WIRELESS_SETTING_NAME)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection and/or wireless settings are missing"); + return NULL; + } + + if (!NM_IN_STRSET(nm_setting_wireless_get_mode(s_wifi), NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-infrastructure-mode connections don't have IWD profiles (or aren't supported)"); + return NULL; + } + + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + if (!ssid_data || ssid_len <= 0 || ssid_len > NM_IW_ESSID_MAX_SIZE + || !g_utf8_validate((const char *) ssid_data, ssid_len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Empty or non-UTF-8 SSIDs not supported by IWD"); + return NULL; + } + + if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection's security type unrecognised"); + return NULL; + } + + file = g_key_file_new(); + + comment = g_strdup_printf(" Auto-generated from NetworkManager connection \"%s\"\n" + " Changes to that connection overwrite this file when " + "enabled by NM's [%s].%s value", + nm_setting_connection_get_id(s_conn), + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH); + g_key_file_set_comment(file, NULL, NULL, comment, NULL); + + if (!nm_setting_connection_get_autoconnect(s_conn)) + g_key_file_set_boolean(file, "Settings", "AutoConnect", FALSE); + + if (nm_setting_wireless_get_hidden(s_wifi)) + g_key_file_set_boolean(file, "Settings", "Hidden", TRUE); + + /* Only effective if IWD's global [General].AddressRandomization is set + * to "network". "random" maps to [Settings].AlwaysRandomizeAddress=true, + * "stable" is the default, specific address maps to + * [Settings].AddressOverride set to that address. "permanent" is not + * supported and "preserve" can only be achieved using the global + * [General].AddressRandomization=disabled setting. We don't print + * warnings when we can't map the value here because we don't know what + * IWD's [General].AddressRandomization is set to. + */ + cloned_mac_addr = nm_setting_wireless_get_cloned_mac_address(s_wifi); + if (nm_streq0(cloned_mac_addr, NM_CLONED_MAC_RANDOM)) + g_key_file_set_boolean(file, "Settings", "AlwaysRandomizeAddress", TRUE); + else if (cloned_mac_addr && nm_utils_hwaddr_valid(cloned_mac_addr, ETH_ALEN)) + g_key_file_set_string(file, "Settings", "AddressOverride", cloned_mac_addr); + + if (!ip4_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)), + error)) + return NULL; + + if (!ip6_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip6_config(connection)), + error)) + return NULL; + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + break; + case NM_IWD_NETWORK_SECURITY_PSK: + if (!psk_setting_to_iwd_config(file, + nm_connection_get_setting_wireless_security(connection), + error)) + return NULL; + + break; + case NM_IWD_NETWORK_SECURITY_8021X: + if (!eap_setting_to_iwd_config(file, nm_connection_get_setting_802_1x(connection), error)) + return NULL; + + break; + default: + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection security type is not supported"); + return NULL; + } + + if (out_filename) + *out_filename = + nm_wifi_utils_get_iwd_config_filename((const char *) ssid_data, ssid_len, security); + + return g_steal_pointer(&file); +} diff --git a/src/core/devices/wifi/nm-wifi-utils.h b/src/core/devices/wifi/nm-wifi-utils.h index 474bea41..2664c03e 100644 --- a/src/core/devices/wifi/nm-wifi-utils.h +++ b/src/core/devices/wifi/nm-wifi-utils.h @@ -11,6 +11,7 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" +#include "libnm-base/nm-base.h" typedef enum { NM_IWD_NETWORK_SECURITY_OPEN, @@ -21,7 +22,7 @@ typedef enum { gboolean nm_wifi_utils_complete_connection(GBytes * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 ap_freq, guint32 flags, guint32 wpa_flags, @@ -35,5 +36,11 @@ gboolean nm_wifi_utils_is_manf_default_ssid(GBytes *ssid); gboolean nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, char ** ssid, NMIwdNetworkSecurity *security); +char * nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security); + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *conn, char **out_filename, GError **error); #endif /* __NM_WIFI_UTILS_H__ */ diff --git a/src/core/devices/wifi/tests/test-devices-wifi.c b/src/core/devices/wifi/tests/test-devices-wifi.c index bc0ba126..dc278c94 100644 --- a/src/core/devices/wifi/tests/test-devices-wifi.c +++ b/src/core/devices/wifi/tests/test-devices-wifi.c @@ -7,7 +7,7 @@ #include "devices/wifi/nm-wifi-utils.h" #include "devices/wifi/nm-device-wifi.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-test-utils-core.h" @@ -49,7 +49,7 @@ static gboolean complete_connection(const char * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, @@ -197,7 +197,7 @@ fill_8021x(NMConnection *connection, const KeyData items[]) } 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; @@ -217,9 +217,9 @@ create_basic(const char *ssid, const char *bssid, NM80211Mode mode) if (bssid) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - if (mode == NM_802_11_MODE_INFRA) + 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) + 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(); @@ -241,14 +241,14 @@ test_lock_bssid(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _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); + expected = create_basic(ssid, bssid, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -273,14 +273,14 @@ test_open_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _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); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -311,7 +311,7 @@ test_open_ap_leap_connection_1(gconstpointer add_wifi) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -345,7 +345,7 @@ test_open_ap_leap_connection_2(void) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -383,7 +383,7 @@ test_open_ap_wep_connection(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -427,7 +427,7 @@ test_ap_wpa_psk_connection_base(const char * key_mgmt, fill_wsec(src, both_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -553,7 +553,7 @@ test_ap_wpa_eap_connection_base(const char *key_mgmt, fill_8021x(src, src_empty); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -751,7 +751,7 @@ test_priv_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -760,7 +760,7 @@ test_priv_ap_empty_connection(void) &error); /* Static WEP connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -798,7 +798,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -809,7 +809,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) * 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); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -840,7 +840,7 @@ test_priv_ap_leap_connection_2(void) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -885,7 +885,7 @@ test_priv_ap_dynamic_wep_1(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -894,7 +894,7 @@ test_priv_ap_dynamic_wep_1(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + 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); @@ -933,7 +933,7 @@ test_priv_ap_dynamic_wep_2(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -942,7 +942,7 @@ test_priv_ap_dynamic_wep_2(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + 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); @@ -976,7 +976,7 @@ test_priv_ap_dynamic_wep_3(void) fill_8021x(src, src_8021x); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -1102,7 +1102,7 @@ test_wpa_ap_empty_connection(gconstpointer data) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1111,7 +1111,7 @@ test_wpa_ap_empty_connection(gconstpointer data) &error); /* WPA connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -1144,7 +1144,7 @@ test_wpa_ap_leap_connection_1(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1180,7 +1180,7 @@ test_wpa_ap_leap_connection_2(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1214,7 +1214,7 @@ test_wpa_ap_dynamic_wep_connection(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), diff --git a/src/core/devices/wwan/meson.build b/src/core/devices/wwan/meson.build index 87af0429..37ef738c 100644 --- a/src/core/devices/wwan/meson.build +++ b/src/core/devices/wwan/meson.build @@ -17,7 +17,6 @@ libnm_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_args: '-Wl,--version-script,@0@'.format(linker_script), link_depends: linker_script, install: true, @@ -51,7 +50,6 @@ libnm_device_plugin_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_with: libnm_wwan, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c index 3ea89d2c..4d892e6f 100644 --- a/src/core/devices/wwan/nm-device-modem.c +++ b/src/core/devices/wwan/nm-device-modem.c @@ -14,7 +14,7 @@ #include "settings/nm-settings-connection.h" #include "nm-modem-broadband.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceModem #include "devices/nm-device-logging.h" @@ -193,15 +193,20 @@ modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpoi 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); + if (!nm_device_activate_ip4_state_in_conf(device)) { + _LOGD(LOGD_MB | LOGD_IP4, + "retrieving IPv4 configuration while no longer in state IPv4 conf"); + return; + } 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); + return; } + + 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 @@ -218,7 +223,11 @@ modem_ip6_config_result(NMModem * modem, gs_unref_object NMIP6Config *ignored = NULL; gboolean got_config = !!config; - g_return_if_fail(nm_device_activate_ip6_state_in_conf(device) == TRUE); + if (!nm_device_activate_ip6_state_in_conf(device)) { + _LOGD(LOGD_MB | LOGD_IP6, + "retrieving IPv6 configuration while no longer in state IPv6 conf"); + return; + } if (error) { _LOGW(LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message); @@ -357,7 +366,6 @@ modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_d 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) { @@ -856,14 +864,13 @@ dispose(GObject *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("ModemCapabilities", + "u", + NM_DEVICE_MODEM_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("CurrentCapabilities", + "u", + NM_DEVICE_MODEM_CURRENT_CAPABILITIES), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceId", "s", NM_DEVICE_MODEM_DEVICE_ID), @@ -871,7 +878,6 @@ static const NMDBusInterfaceInfoExtended interface_info_device_modem = { "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 diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index 1297d964..0872a8a1 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -11,10 +11,10 @@ #include <arpa/inet.h> #include <libmm-glib.h> -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" diff --git a/src/core/devices/wwan/nm-modem-manager.c b/src/core/devices/wwan/nm-modem-manager.c index 598c6898..4fb9a378 100644 --- a/src/core/devices/wwan/nm-modem-manager.c +++ b/src/core/devices/wwan/nm-modem-manager.c @@ -17,7 +17,7 @@ #define sd_booted() FALSE #endif -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c index 21734cee..78ad7b68 100644 --- a/src/core/devices/wwan/nm-modem-ofono.c +++ b/src/core/devices/wwan/nm-modem-ofono.c @@ -7,10 +7,10 @@ #include "nm-modem-ofono.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device-private.h" #include "nm-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #define VARIANT_IS_OF_TYPE_BOOLEAN(v) \ @@ -316,10 +316,9 @@ handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpoint static void sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_sim_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -330,7 +329,7 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -370,9 +369,8 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_sim_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -477,10 +475,9 @@ handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gp static void connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_connman_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -491,7 +488,7 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -523,9 +520,8 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_connman_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -700,9 +696,8 @@ modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_d */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_modem_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -726,35 +721,30 @@ stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data) 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... - */ + if (!g_strstr_len(error->message, + NM_STRLEN(OFONO_ERROR_IN_PROGRESS), + OFONO_ERROR_IN_PROGRESS)) { + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); + } } } static void -context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +handle_settings(GVariant *v_dict, 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; + gboolean ret = FALSE; + 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); + //_LOGD("PropertyChanged: %s", property); /* * TODO: might be a good idea and re-factor this to mimic bluez-device, @@ -762,15 +752,6 @@ context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, g * 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)) { @@ -909,6 +890,28 @@ out: } } +static void +context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +{ + NMModemOfono * self = NM_MODEM_OFONO(user_data); + gs_unref_variant GVariant *v_dict = NULL; + + _LOGD("PropertyChanged: %s", property); + + if (g_strcmp0(property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value(v, 0); + if (!v_dict) { + _LOGW("ofono: (%s): error getting IPv4 Settings", nm_modem_get_uid(NM_MODEM(self))); + return; + } + + g_assert(g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)); + + handle_settings(v_dict, user_data); +} + static NMActStageReturn static_stage3_ip4_config_start(NMModem * modem, NMActRequest * req, @@ -936,6 +939,72 @@ static_stage3_ip4_config_start(NMModem * modem, } static void +context_properties_cb(GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *properties = NULL; + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant *v_dict = NULL; + gboolean active; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + properties = g_dbus_proxy_call_finish(proxy, result, &error); + + if (!properties) { + _LOGW("ofono: connection failed: no context properties returned %s", error->message); + g_clear_error(&error); + goto error; + } + + v_dict = g_variant_get_child_value(properties, 0); + if (!v_dict || !g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)) { + _LOGW("ofono: connection failed; could not read connection properties"); + goto error; + } + + if (!g_variant_lookup(v_dict, "Active", "b", &active)) { + _LOGW("ofono: connection failed; can not read 'Active' property"); + goto error; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect(priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(context_property_changed), + self); + + if (active) { + _LOGD("ofono: connection is already Active"); + + settings = g_variant_lookup_value(v_dict, "Settings", G_VARIANT_TYPE_VARDICT); + if (settings == NULL) { + _LOGW("ofono: connection failed; can not read 'Settings' property"); + goto error; + } + + handle_settings(settings, user_data); + } else { + g_dbus_proxy_call(priv->context_proxy, + "SetProperty", + g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) stage1_prepare_done, + self); + } + return; + +error: + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); +} + +static void context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { NMModemOfono * self; @@ -973,19 +1042,15 @@ context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) */ g_clear_object(&priv->ip4_config); - _nm_dbus_signal_connect(priv->context_proxy, - "PropertyChanged", - G_VARIANT_TYPE("(sv)"), - G_CALLBACK(context_property_changed), - self); - + /* We need to directly query ConnectionContextinteface to get the current + * property values */ g_dbus_proxy_call(priv->context_proxy, - "SetProperty", - g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + "GetProperties", + NULL, G_DBUS_CALL_FLAGS_NONE, 20000, - priv->context_proxy_cancellable, - stage1_prepare_done, + NULL, + (GAsyncReadyCallback) context_properties_cb, self); } @@ -1069,6 +1134,7 @@ modem_act_stage1_prepare(NMModem * modem, _LOGI("activating context %s", priv->context_path); + update_modem_state(self); if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) { do_context_activate(self); } else { diff --git a/src/core/devices/wwan/nm-modem-ofono.h b/src/core/devices/wwan/nm-modem-ofono.h index 260e3954..ebe21023 100644 --- a/src/core/devices/wwan/nm-modem-ofono.h +++ b/src/core/devices/wwan/nm-modem-ofono.h @@ -25,6 +25,8 @@ #define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" #define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" +#define OFONO_ERROR_IN_PROGRESS "org.ofono.Error.InProgress" + typedef struct _NMModemOfono NMModemOfono; typedef struct _NMModemOfonoClass NMModemOfonoClass; diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 0d334fa4..15baa677 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -10,10 +10,11 @@ #include <fcntl.h> #include <termios.h> +#include <linux/if.h> #include <linux/rtnetlink.h> -#include "nm-core-internal.h" -#include "platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" #include "nm-setting-connection.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" @@ -799,8 +800,10 @@ nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config) g_assert(address); if (address->plen == 32) - nm_platform_link_set_noarp(nm_device_get_platform(device), - nm_device_get_ip_ifindex(device)); + nm_platform_link_change_flags(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + IFF_NOARP, + TRUE); } } @@ -1199,7 +1202,7 @@ deactivate_cleanup(NMModem *self, NMDevice *device, gboolean stop_ppp_manager) 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_link_change_flags(platform, ifindex, IFF_UP, FALSE); } } } diff --git a/src/core/devices/wwan/nm-wwan-factory.c b/src/core/devices/wwan/nm-wwan-factory.c index 5d2ce2b3..0d802ae1 100644 --- a/src/core/devices/wwan/nm-wwan-factory.c +++ b/src/core/devices/wwan/nm-wwan-factory.c @@ -12,7 +12,7 @@ #include "nm-setting-cdma.h" #include "nm-modem-manager.h" #include "nm-device-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" /*****************************************************************************/ |