diff options
| author | Michael Biebl <biebl@debian.org> | 2026-02-22 00:40:03 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2026-02-22 00:40:03 +0100 |
| commit | ccdb9117cca7141ee709afca8b25c966ff4fa18e (patch) | |
| tree | 3b7377c95e1d4049c13dd9101ae923fee70ab91d /src/core/devices | |
| parent | d0ea10125cc04f55c1864451198d87fb801d1457 (diff) | |
| parent | 067fb576988f685e83ac8b0ae690334aff547c85 (diff) | |
Update upstream source from tag 'upstream/1.56.0'
Update to upstream version '1.56.0' with Debian dir 15fab61a7abf1fd4e2ba46785f96d935e87d32bb
Diffstat (limited to 'src/core/devices')
| -rw-r--r-- | src/core/devices/nm-device-bridge.c | 2 | ||||
| -rw-r--r-- | src/core/devices/nm-device-ethernet.c | 16 | ||||
| -rw-r--r-- | src/core/devices/nm-device-macsec.c | 13 | ||||
| -rw-r--r-- | src/core/devices/nm-device-private.h | 3 | ||||
| -rw-r--r-- | src/core/devices/nm-device-utils.c | 4 | ||||
| -rw-r--r-- | src/core/devices/nm-device-wireguard.c | 61 | ||||
| -rw-r--r-- | src/core/devices/nm-device.c | 122 | ||||
| -rw-r--r-- | src/core/devices/nm-device.h | 3 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-ovsdb.c | 105 | ||||
| -rw-r--r-- | src/core/devices/wifi/nm-device-wifi.c | 38 | ||||
| -rw-r--r-- | src/core/devices/wifi/nm-iwd-manager.c | 2 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem-broadband.c | 12 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem.c | 41 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem.h | 2 |
14 files changed, 313 insertions, 111 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index 45cdd83f..6ca3737f 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -1066,7 +1066,7 @@ attach_port(NMDevice *device, plat_vlans = setting_vlans_to_platform(vlans, &num_vlans); - /* Since the link was just enportd, there are no existing VLANs + /* Since the link was just attached, there are no existing VLANs * (except for the default one) and so there's no need to flush. */ if (plat_vlans diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index db1245b3..11f691de 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -15,7 +15,6 @@ #include <linux/if_ether.h> #include "NetworkManagerUtils.h" -#include "NetworkManagerUtils.h" #include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "libnm-glib-aux/nm-uuid.h" @@ -708,6 +707,9 @@ supplicant_iface_start(NMDeviceEthernet *self) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self); gs_unref_object NMSupplicantConfig *config = NULL; gs_free_error GError *error = NULL; + NMActRequest *request; + NMActiveConnection *controller_ac; + NMDevice *controller; config = build_supplicant_config(self, &error); if (!config) { @@ -722,6 +724,16 @@ supplicant_iface_start(NMDeviceEthernet *self) } nm_supplicant_interface_disconnect(priv->supplicant.iface); + + /* Tell the supplicant in which bridge the interface is */ + if ((request = nm_device_get_act_request(NM_DEVICE(self))) + && (controller_ac = nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(request))) + && (controller = nm_active_connection_get_device(controller_ac)) + && nm_device_get_device_type(controller) == NM_DEVICE_TYPE_BRIDGE) { + nm_supplicant_interface_set_bridge(priv->supplicant.iface, nm_device_get_iface(controller)); + } else + nm_supplicant_interface_set_bridge(priv->supplicant.iface, NULL); + nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self); return TRUE; } @@ -1901,7 +1913,7 @@ get_ip_method_auto(NMDevice *device, int addr_family) /* We cannot do DHCPv4 on a PPP link, instead we get "auto" IP addresses * by pppd. Return "manual" here, which has the suitable effect to a * (zero) manual addresses in addition. */ - return NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + return NM_SETTING_IP4_CONFIG_METHOD_MANUAL; } return NM_SETTING_IP6_CONFIG_METHOD_AUTO; diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c index 1659ea05..eb39cb2a 100644 --- a/src/core/devices/nm-device-macsec.c +++ b/src/core/devices/nm-device-macsec.c @@ -440,6 +440,9 @@ supplicant_iface_start(NMDeviceMacsec *self) NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self); gs_unref_object NMSupplicantConfig *config = NULL; gs_free_error GError *error = NULL; + NMActRequest *request; + NMActiveConnection *controller_ac; + NMDevice *controller; config = build_supplicant_config(self, &error); if (!config) { @@ -452,6 +455,16 @@ supplicant_iface_start(NMDeviceMacsec *self) } nm_supplicant_interface_disconnect(priv->supplicant.iface); + + /* Tell the supplicant in which bridge the interface is */ + if ((request = nm_device_get_act_request(NM_DEVICE(self))) + && (controller_ac = nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(request))) + && (controller = nm_active_connection_get_device(controller_ac)) + && nm_device_get_device_type(controller) == NM_DEVICE_TYPE_BRIDGE) { + nm_supplicant_interface_set_bridge(priv->supplicant.iface, nm_device_get_iface(controller)); + } else + nm_supplicant_interface_set_bridge(priv->supplicant.iface, NULL); + nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self); return TRUE; } diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index 2568d9f1..6d828597 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -115,9 +115,6 @@ gboolean nm_device_sysctl_ip_conf_set(NMDevice *self, NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source); -NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self, - NMConnection *connection); - void nm_device_ip_method_dhcp4_start(NMDevice *self); void nm_device_ip_method_autoconf6_start(NMDevice *self); diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c index 3e86e2e8..be1de3ea 100644 --- a/src/core/devices/nm-device-utils.c +++ b/src/core/devices/nm-device-utils.c @@ -143,7 +143,9 @@ NM_UTILS_LOOKUP_STR_DEFINE( NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS, "unmanaged-user-settings"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, "networking-off"), ); + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, "networking-off"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE, + "modem-no-operator-code"), ); NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string, NMDeviceMtuSource, diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index 299e3b30..d98059ba 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -1672,6 +1672,57 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) return ret; } +static gboolean +skip_peer_route(const NMIPAddr *peer_addr, + guint peer_addr_prefix, + int addr_family, + NMSettingIPConfig *s_ip) +{ + guint num_addresses; + guint i; + + /* + * If the allowed-ip subnet is already reachable on the interface via the + * prefix route of a static IP address, skip adding the peer route. + * We don't want to override the prefix route with a new one because the + * prefix route also specifies the correct source IP address. + * + * wg-quick does something similar here: + * https://git.zx2c4.com/wireguard-tools/tree/src/wg-quick/linux.bash?h=v1.0.20250521#n177 + * The condition in wg-quick is a bit different because it checks that no + * duplicate route exists on the interface. We can't do exactly the same + * because here we don't have visibility on all the platform routes. + */ + + if (!s_ip) + return FALSE; + + num_addresses = nm_setting_ip_config_get_num_addresses(s_ip); + for (i = 0; i < num_addresses; i++) { + NMIPAddr setting_addr; + NMIPAddr peer_addr_tmp; + guint setting_prefix; + NMIPAddress *a; + + peer_addr_tmp = *peer_addr; + + a = nm_setting_ip_config_get_address(s_ip, i); + nm_ip_address_get_address_binary(a, &setting_addr); + setting_prefix = nm_ip_address_get_prefix(a); + + if (setting_prefix > peer_addr_prefix) + continue; + + nm_ip_addr_clear_host_address(addr_family, &setting_addr, NULL, setting_prefix); + nm_ip_addr_clear_host_address(addr_family, &peer_addr_tmp, NULL, setting_prefix); + + if (nm_ip_addr_equal(addr_family, &peer_addr_tmp, &setting_addr)) + return TRUE; + } + + return FALSE; +} + static const NML3ConfigData * _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) { @@ -1738,6 +1789,7 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) n_aips = nm_wireguard_peer_get_allowed_ips_len(peer); for (j = 0; j < n_aips; j++) { + NMSettingIPConfig *s_ip; NMPlatformIPXRoute rt; NMIPAddr addrbin; const char *aip; @@ -1745,7 +1797,8 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) int prefix; guint32 rtable_coerced; - aip = nm_wireguard_peer_get_allowed_ip(peer, j, &valid); + aip = nm_wireguard_peer_get_allowed_ip(peer, j, &valid); + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); if (!valid || !nm_inet_parse_with_prefix_bin(addr_family, aip, NULL, &addrbin, &prefix)) continue; @@ -1754,9 +1807,6 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) prefix = (addr_family == AF_INET) ? 32 : 128; if (prefix == 0) { - NMSettingIPConfig *s_ip; - - s_ip = nm_connection_get_setting_ip_config(connection, addr_family); if (nm_setting_ip_config_get_never_default(s_ip)) continue; } @@ -1769,6 +1819,9 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) nm_ip_addr_clear_host_address(addr_family, &addrbin, NULL, prefix); + if (skip_peer_route(&addrbin, prefix, addr_family, s_ip)) + continue; + rtable_coerced = route_table_coerced; if (prefix == 0 && auto_default_route_enabled) { diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index b0a3f780..46fb2339 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -113,6 +113,19 @@ typedef enum { RELEASE_PORT_TYPE_CONFIG_FORCE, } ReleasePortType; +/** + * CleanupType: + * @CLEANUP_TYPE_KEEP: Cleanup internally but keep the real device's config. This is + * often used when moving a partially managed device to "unmanaged" (but not only). + * @CLEANUP_TYPE_REMOVED: The device suddently disappeared. Cleanup internally but don't + * make any action on the real device at all, as it no longer exists. + * @CLEANUP_TYPE_DECONFIGURE: Also deconfigure the real device. This is the typical + * action when a connection or device is set to "down", or fully managed devices + * moved to "unmanaged". + * @CLEANUP_TYPE_KEEP_REAPPLY: Like %CLEANUP_TYPE_KEEP, but indicating that it's a + * reapply. Some special actions can be done if we're doing a reapply, like keeping + * the existing DHCP lease, for example. + */ typedef enum { CLEANUP_TYPE_KEEP, CLEANUP_TYPE_REMOVED, @@ -265,11 +278,11 @@ typedef struct { NMDeviceIPState state; union { struct { - NMDnsMasqManager *dnsmasq_manager; - NMNetnsSharedIPHandle *shared_ip_handle; - NMFirewallConfig *firewall_config; - gulong dnsmasq_state_id; - const NML3ConfigData *l3cd; + NMDnsMasqManager *dnsmasq_manager; + NMNetnsIPReservation *ip_reservation; + NMFirewallConfig *firewall_config; + gulong dnsmasq_state_id; + const NML3ConfigData *l3cd; } v4; struct { } v6; @@ -1411,14 +1424,12 @@ _prop_get_ipvx_routed_dns(NMDevice *self, int addr_family) } static NMSettingConnectionMdns -_prop_get_connection_mdns(NMDevice *self) +_prop_get_connection_mdns(NMDevice *self, NMConnection *connection) { - NMConnection *connection; NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_MDNS_DEFAULT); - connection = nm_device_get_applied_connection(self); if (connection) mdns = nm_setting_connection_get_mdns(nm_connection_get_setting_connection(connection)); if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) @@ -1453,14 +1464,12 @@ _prop_get_sriov_preserve_on_down(NMDevice *self, NMSettingSriov *s_sriov) } static NMSettingConnectionLlmnr -_prop_get_connection_llmnr(NMDevice *self) +_prop_get_connection_llmnr(NMDevice *self, NMConnection *connection) { - NMConnection *connection; NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_LLMNR_DEFAULT); - connection = nm_device_get_applied_connection(self); if (connection) llmnr = nm_setting_connection_get_llmnr(nm_connection_get_setting_connection(connection)); if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) @@ -1475,14 +1484,12 @@ _prop_get_connection_llmnr(NMDevice *self) } static NMSettingConnectionDnsOverTls -_prop_get_connection_dns_over_tls(NMDevice *self) +_prop_get_connection_dns_over_tls(NMDevice *self, NMConnection *connection) { - NMConnection *connection; NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT; g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT); - connection = nm_device_get_applied_connection(self); if (connection) dns_over_tls = nm_setting_connection_get_dns_over_tls( nm_connection_get_setting_connection(connection)); @@ -1497,15 +1504,33 @@ _prop_get_connection_dns_over_tls(NMDevice *self) NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT); } +static NMSettingConnectionDnssec +_prop_get_connection_dnssec(NMDevice *self, NMConnection *connection) +{ + NMSettingConnectionDnssec dnssec = NM_SETTING_CONNECTION_DNSSEC_DEFAULT; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNSSEC_DEFAULT); + + if (connection) + dnssec = nm_setting_connection_get_dnssec(nm_connection_get_setting_connection(connection)); + if (dnssec != NM_SETTING_CONNECTION_DNSSEC_DEFAULT) + return dnssec; + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.dnssec"), + self, + NM_SETTING_CONNECTION_DNSSEC_NO, + NM_SETTING_CONNECTION_DNSSEC_YES, + NM_SETTING_CONNECTION_DNSSEC_DEFAULT); +} + static NMMptcpFlags -_prop_get_connection_mptcp_flags(NMDevice *self) +_prop_get_connection_mptcp_flags(NMDevice *self, NMConnection *connection) { - NMConnection *connection; - NMMptcpFlags mptcp_flags = NM_MPTCP_FLAGS_NONE; + NMMptcpFlags mptcp_flags = NM_MPTCP_FLAGS_NONE; g_return_val_if_fail(NM_IS_DEVICE(self), NM_MPTCP_FLAGS_DISABLED); - connection = nm_device_get_applied_connection(self); if (connection) { mptcp_flags = nm_setting_connection_get_mptcp_flags(nm_connection_get_setting_connection(connection)); @@ -2471,16 +2496,14 @@ _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config * } static NMSettingIP6ConfigPrivacy -_prop_get_ipv6_ip6_privacy(NMDevice *self) +_prop_get_ipv6_ip6_privacy(NMDevice *self, NMConnection *connection) { NMSettingIP6ConfigPrivacy ip6_privacy; - NMConnection *connection; g_return_val_if_fail(self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); /* 1.) First look at the per-connection setting. If it is not -1 (unknown), * use it. */ - connection = nm_device_get_applied_connection(self); if (connection) { NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection); @@ -3613,11 +3636,12 @@ nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *co l3cd = nm_l3_config_data_new_from_connection(nm_device_get_multi_index(self), ifindex, connection); - nm_l3_config_data_set_mdns(l3cd, _prop_get_connection_mdns(self)); - nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self)); - nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self)); - nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self)); - nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self)); + nm_l3_config_data_set_mdns(l3cd, _prop_get_connection_mdns(self, connection)); + nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self, connection)); + nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self, connection)); + nm_l3_config_data_set_dnssec(l3cd, _prop_get_connection_dnssec(self, connection)); + nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self, connection)); + nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self, connection)); return l3cd; } @@ -12974,7 +12998,7 @@ _dev_ipac6_start(NMDevice *self) .router_solicitations = router_solicitations, .router_solicitation_interval = router_solicitation_interval, .ra_timeout = ra_timeout, - .ip6_privacy = _prop_get_ipv6_ip6_privacy(self), + .ip6_privacy = _prop_get_ipv6_ip6_privacy(self, connection), }; priv->ipac6_data.ndisc = nm_lndp_ndisc_new(&config); @@ -13161,7 +13185,6 @@ _dev_addrgenmode6_set(NMDevice *self, guint8 addr_gen_mode) if (!priv->addrgenmode6_data.previous_mode_has) { priv->addrgenmode6_data.previous_mode_has = TRUE; priv->addrgenmode6_data.previous_mode_val = cur_addr_gen_mode; - nm_assert(priv->addrgenmode6_data.previous_mode_val == cur_addr_gen_mode); } _LOGD_ip(AF_INET6, @@ -13650,7 +13673,7 @@ _dev_ipsharedx_cleanup(NMDevice *self, int addr_family) nm_clear_pointer(&priv->ipshared_data_4.v4.firewall_config, nm_firewall_config_free); } - nm_clear_pointer(&priv->ipshared_data_4.v4.shared_ip_handle, nm_netns_shared_ip_release); + nm_clear_pointer(&priv->ipshared_data_4.v4.ip_reservation, nm_netns_ip_reservation_release); nm_clear_l3cd(&priv->ipshared_data_4.v4.l3cd); _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_SHARED_4, NULL, FALSE); @@ -13684,13 +13707,14 @@ _dev_ipshared4_new_l3cd(NMDevice *self, NMConnection *connection, NMPlatformIP4A nm_ip_address_get_address_binary(user, &a); nm_platform_ip4_address_set_addr(&address, a, nm_ip_address_get_prefix(user)); - nm_clear_pointer(&priv->ipshared_data_4.v4.shared_ip_handle, nm_netns_shared_ip_release); + nm_clear_pointer(&priv->ipshared_data_4.v4.ip_reservation, nm_netns_ip_reservation_release); } else { - if (!priv->ipshared_data_4.v4.shared_ip_handle) - priv->ipshared_data_4.v4.shared_ip_handle = - nm_netns_shared_ip_reserve(nm_device_get_netns(self)); + if (!priv->ipshared_data_4.v4.ip_reservation) + priv->ipshared_data_4.v4.ip_reservation = + nm_netns_ip_reservation_get(nm_device_get_netns(self), + NM_NETNS_IP_RESERVATION_TYPE_SHARED4); nm_platform_ip4_address_set_addr(&address, - priv->ipshared_data_4.v4.shared_ip_handle->addr, + priv->ipshared_data_4.v4.ip_reservation->addr, 24); } @@ -14283,6 +14307,7 @@ can_reapply_change(NMDevice *self, NM_SETTING_CONNECTION_MDNS, NM_SETTING_CONNECTION_LLMNR, NM_SETTING_CONNECTION_DNS_OVER_TLS, + NM_SETTING_CONNECTION_DNSSEC, NM_SETTING_CONNECTION_MPTCP_FLAGS, NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY); } @@ -14541,6 +14566,7 @@ check_and_reapply_connection(NMDevice *self, NM_SETTING_CONNECTION_MDNS, NM_SETTING_CONNECTION_LLMNR, NM_SETTING_CONNECTION_DNS_OVER_TLS, + NM_SETTING_CONNECTION_DNSSEC, NM_SETTING_CONNECTION_MPTCP_FLAGS)) { priv->ip_data_4.do_reapply = TRUE; priv->ip_data_6.do_reapply = TRUE; @@ -17285,6 +17311,25 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu /* controller: release ports */ nm_device_controller_release_ports_all(self); + /* port: detach from controller */ + if (priv->controller) { + nm_device_controller_release_port(priv->controller, + self, + RELEASE_PORT_TYPE_CONFIG, + reason); + } + } + + /* port: mark no longer attached */ + if (priv->controller && priv->ifindex > 0 + && nm_platform_link_get_controller(nm_device_get_platform(self), priv->ifindex) <= 0) { + nm_device_controller_release_port(priv->controller, + self, + RELEASE_PORT_TYPE_NO_CONFIG, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } + + if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) { /* Take out any entries in the routing table and any IP address the device had. */ if (ifindex > 0) { NMPlatform *platform = nm_device_get_platform(self); @@ -17308,15 +17353,6 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu if (ifindex > 0) nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), ifindex, NULL); - /* port: mark no longer attached */ - if (priv->controller && priv->ifindex > 0 - && nm_platform_link_get_controller(nm_device_get_platform(self), priv->ifindex) <= 0) { - nm_device_controller_release_port(priv->controller, - self, - RELEASE_PORT_TYPE_NO_CONFIG, - NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - } - lldp_setup(self, NM_TERNARY_FALSE); nm_device_update_metered(self); diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 8632944a..2f287953 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -853,4 +853,7 @@ void nm_routing_rules_sync(NMConnection *applied_connection, NMDevice *self, NMNetns *netns); +NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self, + NMConnection *connection); + #endif /* __NETWORKMANAGER_DEVICE_H__ */ diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 1c9484c4..cb67848e 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -1890,7 +1890,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) == -1) { /* This doesn't really have to be an error; the key might * be missing if there really are no bridges present. */ - _LOGD("Bad update: %s", json_error.text); + _LOGD("monitor: bad update: %s", json_error.text); } if (ovs) { @@ -1936,12 +1936,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) &unused)) continue; - _LOGT("obj[iface:%s]: removed an '%s' interface: %s%s%s", - key, - ovs_interface->type, + _LOGT("monitor: %s: interface removed: type=%s, obj[iface:%s]%s%s", ovs_interface->name, + ovs_interface->type, + key, NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid, - ", ", + ", connection=", ovs_interface->connection_uuid, "")); _signal_emit_device_removed(self, @@ -1989,17 +1989,18 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp1 = NULL; gs_free char *strtmp2 = NULL; - _LOGT("obj[iface:%s]: changed an '%s' interface: %s%s%s, external-ids=%s, " - "other-config=%s", - key, - type, - ovs_interface->name, - NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid, - ", ", - ovs_interface->connection_uuid, - ""), - (strtmp1 = _strdict_to_string(ovs_interface->external_ids)), - (strtmp2 = _strdict_to_string(ovs_interface->other_config))); + _LOGT( + "monitor: %s: interface changed: type=%s, obj[iface:%s]%s%s, external-ids=%s, " + "other-config=%s", + ovs_interface->name, + type, + key, + NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid, + ", connection=", + ovs_interface->connection_uuid, + ""), + (strtmp1 = _strdict_to_string(ovs_interface->external_ids)), + (strtmp2 = _strdict_to_string(ovs_interface->other_config))); } } else { gs_free char *strtmp1 = NULL; @@ -2015,17 +2016,17 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) .other_config = g_steal_pointer(&other_config_arr), }; g_hash_table_add(priv->interfaces, ovs_interface); - _LOGT( - "obj[iface:%s]: added an '%s' interface: %s%s%s, external-ids=%s, other-config=%s", - key, - ovs_interface->type, - ovs_interface->name, - NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid, - ", ", - ovs_interface->connection_uuid, - ""), - (strtmp1 = _strdict_to_string(ovs_interface->external_ids)), - (strtmp2 = _strdict_to_string(ovs_interface->other_config))); + _LOGT("monitor: %s: interface added: type=%s, obj[iface:%s]%s%s, external-ids=%s, " + "other-config=%s", + ovs_interface->name, + ovs_interface->type, + key, + NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid, + ", connection=", + ovs_interface->connection_uuid, + ""), + (strtmp1 = _strdict_to_string(ovs_interface->external_ids)), + (strtmp2 = _strdict_to_string(ovs_interface->other_config))); _signal_emit_device_added(self, ovs_interface->name, NM_DEVICE_TYPE_OVS_INTERFACE, @@ -2071,11 +2072,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) if (!g_hash_table_steal_extended(priv->ports, &key, (gpointer *) &ovs_port, &unused)) continue; - _LOGT("obj[port:%s]: removed a port: %s%s%s", - key, + _LOGT("monitor: %s: port removed: obj[port:%s]%s%s", ovs_port->name, + key, NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid, - ", ", + ", connection=", ovs_port->connection_uuid, "")); _signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL); @@ -2122,15 +2123,16 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp1 = NULL; gs_free char *strtmp2 = NULL; - _LOGT("obj[port:%s]: changed a port: %s%s%s, external-ids=%s, other-config=%s", - key, - ovs_port->name, - NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid, - ", ", - ovs_port->connection_uuid, - ""), - (strtmp1 = _strdict_to_string(ovs_port->external_ids)), - (strtmp2 = _strdict_to_string(ovs_port->other_config))); + _LOGT( + "monitor: %s: port changed: obj[port:%s]%s%s, external-ids=%s, other-config=%s", + ovs_port->name, + key, + NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid, + ", connection=", + ovs_port->connection_uuid, + ""), + (strtmp1 = _strdict_to_string(ovs_port->external_ids)), + (strtmp2 = _strdict_to_string(ovs_port->other_config))); } } else { gs_free char *strtmp1 = NULL; @@ -2146,11 +2148,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) .other_config = g_steal_pointer(&other_config_arr), }; g_hash_table_add(priv->ports, ovs_port); - _LOGT("obj[port:%s]: added a port: %s%s%s, external-ids=%s, other-config=%s", - key, + _LOGT("monitor: %s: port added: obj[port:%s]%s%s, external-ids=%s, other-config=%s", ovs_port->name, + key, NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid, - ", ", + ", connection=", ovs_port->connection_uuid, ""), (strtmp1 = _strdict_to_string(ovs_port->external_ids)), @@ -2192,11 +2194,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) &unused)) continue; - _LOGT("obj[bridge:%s]: removed a bridge: %s%s%s", - key, + _LOGT("monitor: %s: bridge removed: obj[bridge:%s]%s%s", ovs_bridge->name, + key, NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid, - ", ", + ", connection=", ovs_bridge->connection_uuid, "")); _signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL); @@ -2243,11 +2245,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp1 = NULL; gs_free char *strtmp2 = NULL; - _LOGT("obj[bridge:%s]: changed a bridge: %s%s%s, external-ids=%s, other-config=%s", - key, + _LOGT("monitor: %s: bridge changed: obj[bridge:%s]%s%s, external-ids=%s, " + "other-config=%s", ovs_bridge->name, + key, NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid, - ", ", + ", connection=", ovs_bridge->connection_uuid, ""), (strtmp1 = _strdict_to_string(ovs_bridge->external_ids)), @@ -2267,11 +2270,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) .other_config = g_steal_pointer(&other_config_arr), }; g_hash_table_add(priv->bridges, ovs_bridge); - _LOGT("obj[bridge:%s]: added a bridge: %s%s%s, external-ids=%s, other-config=%s", - key, + _LOGT("monitor: %s: bridge added: obj[bridge:%s]%s%s, external-ids=%s, other-config=%s", ovs_bridge->name, + key, NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid, - ", ", + ", connection=", ovs_bridge->connection_uuid, ""), (strtmp1 = _strdict_to_string(ovs_bridge->external_ids)), diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index 148caa11..b41ed5e1 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -191,6 +191,9 @@ static void supplicant_iface_notify_p2p_available(NMSupplicantInterface *iface, GParamSpec *pspec, NMDeviceWifi *self); +static void supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, + NMDeviceWifi *self); + static void periodic_update(NMDeviceWifi *self); static void ap_add_remove(NMDeviceWifi *self, @@ -624,6 +627,10 @@ supplicant_interface_acquire_cb(NMSupplicantManager *supplicant_manager, "notify::" NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE, G_CALLBACK(supplicant_iface_notify_p2p_available), self); + g_signal_connect(priv->sup_iface, + NM_SUPPLICANT_INTERFACE_PSK_MISMATCH, + G_CALLBACK(supplicant_iface_notify_wpa_psk_mismatch_cb), + self); _scan_notify_is_scanning(self); @@ -2398,6 +2405,9 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self, g_return_val_if_fail(new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE); + if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG) + return FALSE; + req = nm_device_get_act_request(NM_DEVICE(self)); g_return_val_if_fail(req != NULL, FALSE); @@ -2841,6 +2851,34 @@ handle_auth_or_fail(NMDeviceWifi *self, NMActRequest *req, gboolean new_secrets) return TRUE; } +static void +supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, NMDeviceWifi *self) +{ + NMDevice *device = NM_DEVICE(self); + NMActRequest *req; + const char *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + + if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG) + return; + + _LOGI(LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) psk mismatch reported by supplicant, asking for new key"); + + req = nm_device_get_act_request(NM_DEVICE(self)); + g_return_if_fail(req != NULL); + + nm_act_request_clear_secrets(req); + + cleanup_association_attempt(self, TRUE); + nm_device_state_changed(device, + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); + wifi_secrets_get_secrets(self, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); +} + /* * supplicant_connection_timeout_cb * diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index 76a342e2..bb2e056d 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -684,7 +684,7 @@ iwd_config_write(GKeyFile *config, * 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); + return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, NULL, error); } static const char * diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index 018e5306..4bd0a45c 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -508,8 +508,9 @@ find_gsm_apn_cb(const char *apn, static gboolean try_create_connect_properties(NMModemBroadband *self) { - NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); - ConnectContext *ctx = priv->ctx; + NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self); + ConnectContext *ctx = priv->ctx; + NMDeviceStateReason fail_reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; if (MODEM_CAPS_3GPP(ctx->caps)) { NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection); @@ -522,7 +523,7 @@ try_create_connect_properties(NMModemBroadband *self) if (s_gsm) network_id = nm_setting_gsm_get_network_id(s_gsm); if (!network_id) { - if (mm_modem_get_state(self->_priv.modem_iface) < MM_MODEM_STATE_REGISTERED) + if (mm_modem_get_state(self->_priv.modem_iface) != MM_MODEM_STATE_REGISTERED) return FALSE; modem_3gpp = mm_object_get_modem_3gpp(priv->modem_object); network_id = mm_modem_3gpp_get_operator_code(modem_3gpp); @@ -530,6 +531,7 @@ try_create_connect_properties(NMModemBroadband *self) if (!network_id) { _LOGW("failed to connect '%s': unable to determine the network id", nm_connection_get_id(ctx->connection)); + fail_reason = NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE; goto out; } @@ -558,7 +560,7 @@ try_create_connect_properties(NMModemBroadband *self) } out: - nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, fail_reason); connect_context_clear(self); return TRUE; } @@ -1649,6 +1651,8 @@ nm_modem_broadband_new(GObject *object, GError **error) driver, NM_MODEM_OPERATOR_CODE, operator_code, + NM_MODEM_DEVICE_UID, + mm_modem_get_device(modem_iface), NULL); } diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index c4852ea2..9d8f61c5 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -39,7 +39,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMModem, PROP_IP_TYPES, PROP_SIM_OPERATOR_ID, PROP_OPERATOR_CODE, - PROP_APN, ); + PROP_APN, + PROP_DEVICE_UID, ); enum { PPP_STATS, @@ -78,6 +79,7 @@ typedef struct _NMModemPrivate { char *sim_operator_id; char *operator_code; char *apn; + char *device_uid; NMPPPManager *ppp_manager; NMPppMgr *ppp_mgr; @@ -618,6 +620,12 @@ nm_modem_get_apn(NMModem *self) return NM_MODEM_GET_PRIVATE(self)->apn; } +const char * +nm_modem_get_device_uid(NMModem *self) +{ + return NM_MODEM_GET_PRIVATE(self)->device_uid; +} + /*****************************************************************************/ static void @@ -1121,6 +1129,22 @@ nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GE } } + str = nm_setting_gsm_get_device_uid(s_gsm); + if (str) { + if (!priv->device_uid) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "GSM profile has device-uid, device does not"); + return FALSE; + } + if (!nm_streq(str, priv->device_uid)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device has differing device-uid than GSM profile"); + return FALSE; + } + } + /* SIM properties may not be available before the SIM is unlocked, so * to ensure that autoconnect works, the connection's SIM properties * are only compared if present on the device. @@ -1644,6 +1668,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_APN: g_value_set_string(value, priv->apn); break; + case PROP_DEVICE_UID: + g_value_set_string(value, priv->device_uid); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1699,6 +1726,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /* construct-only */ priv->operator_code = g_value_dup_string(value); break; + case PROP_DEVICE_UID: + /* construct-only */ + priv->device_uid = g_value_dup_string(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1758,6 +1789,7 @@ finalize(GObject *object) g_free(priv->sim_operator_id); g_free(priv->operator_code); g_free(priv->apn); + g_free(priv->device_uid); G_OBJECT_CLASS(nm_modem_parent_class)->finalize(object); } @@ -1863,6 +1895,13 @@ nm_modem_class_init(NMModemClass *klass) obj_properties[PROP_APN] = g_param_spec_string(NM_MODEM_APN, "", "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DEVICE_UID] = + g_param_spec_string(NM_MODEM_DEVICE_UID, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[PPP_STATS] = g_signal_new(NM_MODEM_PPP_STATS, diff --git a/src/core/devices/wwan/nm-modem.h b/src/core/devices/wwan/nm-modem.h index 021d77b2..1f54b0b6 100644 --- a/src/core/devices/wwan/nm-modem.h +++ b/src/core/devices/wwan/nm-modem.h @@ -30,6 +30,7 @@ #define NM_MODEM_SIM_OPERATOR_ID "sim-operator-id" #define NM_MODEM_OPERATOR_CODE "operator-code" #define NM_MODEM_APN "apn" +#define NM_MODEM_DEVICE_UID "device-uid" /* Signals */ #define NM_MODEM_PPP_STATS "ppp-stats" @@ -154,6 +155,7 @@ const char *nm_modem_get_sim_id(NMModem *modem); const char *nm_modem_get_sim_operator_id(NMModem *modem); const char *nm_modem_get_operator_code(NMModem *modem); const char *nm_modem_get_apn(NMModem *modem); +const char *nm_modem_get_device_uid(NMModem *modem); gboolean nm_modem_set_data_port(NMModem *self, NMPlatform *platform, |