diff options
| author | Michael Biebl <biebl@debian.org> | 2024-05-05 00:07:30 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2024-05-05 00:07:30 +0200 |
| commit | 34bb501be08aa2b313d88e67d6e0a7e0a3f9cfa6 (patch) | |
| tree | 4e6220877828be4c6f261de09ec0cb2d80e32389 /src/core/devices | |
| parent | bba2e4b4de668db525cbfdfc35292e5a0b51671a (diff) | |
New upstream version 1.47.90 upstream/1.47.90
Diffstat (limited to 'src/core/devices')
| -rw-r--r-- | src/core/devices/nm-device-bond.c | 4 | ||||
| -rw-r--r-- | src/core/devices/nm-device-bridge.c | 4 | ||||
| -rw-r--r-- | src/core/devices/nm-device-ethernet.c | 12 | ||||
| -rw-r--r-- | src/core/devices/nm-device-factory.c | 3 | ||||
| -rw-r--r-- | src/core/devices/nm-device-utils.c | 16 | ||||
| -rw-r--r-- | src/core/devices/nm-device-vrf.c | 2 | ||||
| -rw-r--r-- | src/core/devices/nm-device.c | 541 | ||||
| -rw-r--r-- | src/core/devices/nm-device.h | 15 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-bridge.c | 2 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-interface.c | 4 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-port.c | 4 | ||||
| -rw-r--r-- | src/core/devices/team/nm-device-team.c | 4 | ||||
| -rw-r--r-- | src/core/devices/wifi/nm-device-iwd.c | 4 | ||||
| -rw-r--r-- | src/core/devices/wifi/nm-device-wifi.c | 6 | ||||
| -rw-r--r-- | src/core/devices/wifi/nm-wifi-ap.c | 15 | ||||
| -rw-r--r-- | src/core/devices/wwan/meson.build | 3 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem-broadband.c | 64 |
17 files changed, 479 insertions, 224 deletions
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index a3467930..98670c8d 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -922,7 +922,7 @@ deactivate(NMDevice *device) static void nm_device_bond_init(NMDeviceBond *self) { - nm_assert(nm_device_is_master(NM_DEVICE(self))); + nm_assert(nm_device_is_controller(NM_DEVICE(self))); } static const NMDBusInterfaceInfoExtended interface_info_device_bond = { @@ -958,7 +958,7 @@ nm_device_bond_class_init(NMDeviceBondClass *klass) device_class->connection_type_check_compatible = NM_SETTING_BOND_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BOND); - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->get_generic_capabilities = get_generic_capabilities; device_class->complete_connection = complete_connection; diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index ab3a6be9..2405beea 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -1159,7 +1159,7 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne static void nm_device_bridge_init(NMDeviceBridge *self) { - nm_assert(nm_device_is_master(NM_DEVICE(self))); + nm_assert(nm_device_is_controller(NM_DEVICE(self))); } static const NMDBusInterfaceInfoExtended interface_info_device_bridge = { @@ -1194,7 +1194,7 @@ nm_device_bridge_class_init(NMDeviceBridgeClass *klass) device_class->connection_type_supported = NM_SETTING_BRIDGE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BRIDGE); - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->mtu_force_set = TRUE; device_class->get_generic_capabilities = get_generic_capabilities; device_class->check_connection_compatible = check_connection_compatible; diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 0f7f9d65..8c2a9643 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -370,7 +370,7 @@ check_connection_compatible(NMDevice *device, if (s_wired) { const char *mac, *perm_hw_addr; gboolean try_mac = TRUE; - const char *const *mac_blacklist; + const char *const *mac_denylist; int i; if (!match_subchans(self, s_wired, &try_mac)) { @@ -390,17 +390,17 @@ check_connection_compatible(NMDevice *device, return FALSE; } - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wired_get_mac_address_blacklist(s_wired); - for (i = 0; mac_blacklist[i]; i++) { - if (!nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)) { + /* Check for MAC address denylist */ + mac_denylist = nm_setting_wired_get_mac_address_denylist(s_wired); + for (i = 0; mac_denylist[i]; i++) { + if (!nm_utils_hwaddr_valid(mac_denylist[i], ETH_ALEN)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "invalid MAC in blacklist"); return FALSE; } - if (nm_utils_hwaddr_matches(mac_blacklist[i], -1, perm_hw_addr, -1)) { + if (nm_utils_hwaddr_matches(mac_denylist[i], -1, perm_hw_addr, -1)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "permanent MAC address of device blacklisted"); diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 69c2a38f..22c8fa5a 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -183,7 +183,8 @@ nm_device_factory_class_init(NMDeviceFactoryClass *klass) static GHashTable *factories_by_link = NULL; static GHashTable *factories_by_setting = NULL; -static void __attribute__((destructor)) _cleanup(void) +static void __attribute__((destructor)) +_cleanup(void) { nm_clear_pointer(&factories_by_link, g_hash_table_unref); nm_clear_pointer(&factories_by_setting, g_hash_table_unref); diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c index ed0a2738..80909805 100644 --- a/src/core/devices/nm-device-utils.c +++ b/src/core/devices/nm-device-utils.c @@ -128,8 +128,20 @@ NM_UTILS_LOOKUP_STR_DEFINE( 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_ITEM(NM_DEVICE_STATE_REASON_DEVICE_HANDLER_FAILED, - "device-handler-failed"), ); + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEVICE_HANDLER_FAILED, "device-handler-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_BY_DEFAULT, "unmanaged-by-default"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN, + "unmanaged-external-down"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT, + "unmanaged-link-not-init"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING, "unmanaged-quitting"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING, "unmanaged-sleeping"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF, "unmanaged-user-conf"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT, + "unmanaged-user-explicit"), + 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_DEFINE(nm_device_mtu_source_to_string, NMDeviceMtuSource, diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index a13de1cb..6c7adc6c 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -329,7 +329,7 @@ nm_device_vrf_class_init(NMDeviceVrfClass *klass) device_class->connection_type_supported = NM_SETTING_VRF_SETTING_NAME; device_class->connection_type_check_compatible = NM_SETTING_VRF_SETTING_NAME; - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_VRF); device_class->attach_port = attach_port; diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 34022efb..5b377529 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -95,6 +95,9 @@ #define CARRIER_WAIT_TIME_MS 6000 #define CARRIER_WAIT_TIME_AFTER_MTU_MSEC 10000 +#define SECONDS_PER_WEEK 604800 +#define SECONDS_PER_DAY 86400 + #define NM_DEVICE_AUTH_RETRIES_UNSET -1 #define NM_DEVICE_AUTH_RETRIES_INFINITY -2 #define NM_DEVICE_AUTH_RETRIES_DEFAULT 3 @@ -371,7 +374,6 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, PROP_IFINDEX, PROP_AVAILABLE_CONNECTIONS, PROP_PHYSICAL_PORT_ID, - PROP_MASTER, PROP_PARENT, PROP_HW_ADDRESS, PROP_PERM_HW_ADDRESS, @@ -386,7 +388,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, PROP_IP4_CONNECTIVITY, PROP_IP6_CONNECTIVITY, PROP_INTERFACE_FLAGS, - PROP_PORTS, ); + PROP_PORTS, + PROP_CONTROLLER, ); typedef struct _NMDevicePrivate { guint device_link_changed_id; @@ -707,10 +710,10 @@ typedef struct _NMDevicePrivate { NMPlatformLinkChangeFlags flags; } link_props_state; - /* master interface for bridge/bond/team slave */ - NMDevice *master; - gulong master_ready_id; - int master_ifindex; + /* controller interface for bridge/bond/team slave */ + NMDevice *controller; + gulong controller_ready_id; + int controller_ifindex; /* slave management */ CList slaves; /* list of SlaveInfo */ @@ -1523,11 +1526,12 @@ _prop_get_ipvx_route_table(NMDevice *self, int addr_family) if (route_table == 0u && connection && (s_con = nm_connection_get_setting_connection(connection)) && (nm_streq0(nm_setting_connection_get_port_type(s_con), NM_SETTING_VRF_SETTING_NAME) - && priv->master && nm_device_get_device_type(priv->master) == NM_DEVICE_TYPE_VRF)) { + && priv->controller + && nm_device_get_device_type(priv->controller) == NM_DEVICE_TYPE_VRF)) { const NMPlatformLnkVrf *lnk; lnk = nm_platform_link_get_lnk_vrf(nm_device_get_platform(self), - nm_device_get_ifindex(priv->master), + nm_device_get_ifindex(priv->controller), NULL); if (lnk) @@ -2269,6 +2273,7 @@ _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config * static NMSettingIP6ConfigPrivacy _prop_get_ipv6_ip6_privacy(NMDevice *self) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMSettingIP6ConfigPrivacy ip6_privacy; NMConnection *connection; @@ -2302,16 +2307,100 @@ _prop_get_ipv6_ip6_privacy(NMDevice *self) if (!nm_device_get_ip_ifindex(self)) return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - /* 3.) No valid default-value configured. Fallback to reading sysctl. - * - * Instead of reading static config files in /etc, just read the current sysctl value. - * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves - * the "default" entry untouched. */ - ip6_privacy = nm_platform_sysctl_get_int32( - nm_device_get_platform(self), - NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv6/conf/default/use_tempaddr"), - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - return _ip6_privacy_clamp(ip6_privacy); + /* 3.) No valid default value configured. Fall back to the original value + * from before NM started. */ + return _ip6_privacy_clamp(_nm_utils_ascii_str_to_int64( + g_hash_table_lookup(priv->ip6_saved_properties, "use_tempaddr"), + 10, + G_MININT32, + G_MAXINT32, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN)); +} + +static gint32 +_prop_get_ipv6_temp_valid_lifetime(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gint32 temp_valid_lifetime; + NMConnection *connection; + + g_return_val_if_fail(self, 0); + + /* 1.) First look at the per-connection setting. If it is not 0 (unknown), use it. */ + connection = nm_device_get_applied_connection(self); + if (connection) { + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection); + + if (s_ip6) { + temp_valid_lifetime = + nm_setting_ip6_config_get_temp_valid_lifetime(NM_SETTING_IP6_CONFIG(s_ip6)); + if (temp_valid_lifetime) + return temp_valid_lifetime; + } + } + + /* 2.) Use the default value from the configuration. */ + temp_valid_lifetime = + nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.temp-valid-lifetime"), + self, + 0, + G_MAXINT32, + 0); + if (temp_valid_lifetime) + return temp_valid_lifetime; + + /* 3.) No valid default value configured. Fall back to the original value + * from before NM started. */ + return _nm_utils_ascii_str_to_int64( + g_hash_table_lookup(priv->ip6_saved_properties, "temp_valid_lft"), + 10, + 0, + G_MAXINT32, + SECONDS_PER_WEEK /* final hardcoded fallback: 1 week */); +} + +static gint32 +_prop_get_ipv6_temp_preferred_lifetime(NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gint32 temp_preferred_lifetime; + NMConnection *connection; + + g_return_val_if_fail(self, 0); + + /* 1.) First look at the per-connection setting. If it is not 0 (unknown), use it. */ + connection = nm_device_get_applied_connection(self); + if (connection) { + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection); + + if (s_ip6) { + temp_preferred_lifetime = + nm_setting_ip6_config_get_temp_preferred_lifetime(NM_SETTING_IP6_CONFIG(s_ip6)); + if (temp_preferred_lifetime) + return temp_preferred_lifetime; + } + } + + /* 2.) Use the default value from the configuration. */ + temp_preferred_lifetime = + nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.temp-preferred-lifetime"), + self, + 0, + G_MAXINT32, + 0); + if (temp_preferred_lifetime) + return temp_preferred_lifetime; + + /* 3.) No valid default value configured. Fall back to the original value + * from before NM started. */ + return _nm_utils_ascii_str_to_int64( + g_hash_table_lookup(priv->ip6_saved_properties, "temp_prefered_lft"), + 10, + 0, + G_MAXINT32, + SECONDS_PER_DAY /* final hardcoded fallback: 1 day */); } static NMSettingIP6ConfigAddrGenMode @@ -2359,11 +2448,16 @@ _prop_get_ipv6_addr_gen_mode(NMDevice *self) } static const char * -_prop_get_x_cloned_mac_address(NMDevice *self, NMConnection *connection, gboolean is_wifi) +_prop_get_x_cloned_mac_address(NMDevice *self, + NMConnection *connection, + gboolean is_wifi, + gboolean *out_is_default_special) { NMSetting *setting; const char *addr = NULL; + NM_SET_OUT(out_is_default_special, FALSE); + setting = nm_connection_get_setting(connection, is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); if (setting) { @@ -2394,11 +2488,17 @@ _prop_get_x_cloned_mac_address(NMDevice *self, NMConnection *connection, gboolea NM_SETTING_MAC_RANDOMIZATION_DEFAULT, NM_SETTING_MAC_RANDOMIZATION_ALWAYS, NM_SETTING_MAC_RANDOMIZATION_DEFAULT); - if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) + if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) { addr = NM_CLONED_MAC_RANDOM; + NM_SET_OUT(out_is_default_special, TRUE); + } } - } else if (NM_CLONED_MAC_IS_SPECIAL(a, is_wifi) || nm_utils_hwaddr_valid(a, ETH_ALEN)) + } else if (NM_CLONED_MAC_IS_SPECIAL(a, is_wifi)) { + addr = a; + NM_SET_OUT(out_is_default_special, TRUE); + } else if (nm_utils_hwaddr_valid(a, ETH_ALEN)) { addr = a; + } } return addr; @@ -3726,7 +3826,7 @@ _dev_ip_state_check(NMDevice *self, int addr_family) } if (priv->ip_data_x[IS_IPv4].state == NM_DEVICE_IP_STATE_PENDING - && nm_active_connection_get_master(NM_ACTIVE_CONNECTION(priv->act_request.obj)) + && nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(priv->act_request.obj)) && !priv->is_enslaved) { /* Don't progress into IP_CHECK or SECONDARIES if we're waiting for the * master to enslave us. */ @@ -6676,14 +6776,14 @@ nm_device_master_enslave_slave(NMDevice *self, NMDevice *slave, NMConnection *co static void detach_port_cb(NMDevice *self, GError *error, gpointer user_data) { - nm_auto_unref_object NMDevice *slave = user_data; - NMDevicePrivate *slave_priv = NM_DEVICE_GET_PRIVATE(slave); + nm_auto_unref_object NMDevice *slave = user_data; + NMDevicePrivate *port_priv = NM_DEVICE_GET_PRIVATE(slave); - nm_assert(slave_priv->port_detach_count > 0); + nm_assert(port_priv->port_detach_count > 0); - if (--slave_priv->port_detach_count == 0) { - if (slave_priv->state == NM_DEVICE_STATE_DEACTIVATING) { - deactivate_ready(slave, slave_priv->port_detach_reason); + if (--port_priv->port_detach_count == 0) { + if (port_priv->state == NM_DEVICE_STATE_DEACTIVATING) { + deactivate_ready(slave, port_priv->port_detach_reason); } } } @@ -6708,7 +6808,7 @@ nm_device_master_release_slave(NMDevice *self, NMDeviceStateReason reason) { NMDevicePrivate *priv; - NMDevicePrivate *slave_priv; + NMDevicePrivate *port_priv; SlaveInfo *info; gs_unref_object NMDevice *self_free = NULL; gs_unref_object NMDevice *slave_free = NULL; @@ -6735,10 +6835,10 @@ nm_device_master_release_slave(NMDevice *self, if (!info) g_return_if_reached(); - priv = NM_DEVICE_GET_PRIVATE(self); - slave_priv = NM_DEVICE_GET_PRIVATE(slave); + priv = NM_DEVICE_GET_PRIVATE(self); + port_priv = NM_DEVICE_GET_PRIVATE(slave); - g_return_if_fail(self == slave_priv->master); + g_return_if_fail(self == port_priv->controller); nm_assert(slave == info->slave); nm_clear_g_cancellable(&info->cancellable); @@ -6754,8 +6854,8 @@ nm_device_master_release_slave(NMDevice *self, detach_port_cb, g_object_ref(slave)); if (ret == NM_TERNARY_DEFAULT) { - slave_priv->port_detach_count++; - slave_priv->port_detach_reason = reason; + port_priv->port_detach_count++; + port_priv->port_detach_reason = reason; } } @@ -6763,9 +6863,9 @@ nm_device_master_release_slave(NMDevice *self, nm_device_slave_notify_release(slave, reason, release_type); /* keep both alive until the end of the function. - * Transfers ownership from slave_priv->master. */ - nm_assert(self == slave_priv->master); - self_free = g_steal_pointer(&slave_priv->master); + * Transfers ownership from port_priv->controller. */ + nm_assert(self == port_priv->controller); + self_free = g_steal_pointer(&port_priv->controller); nm_assert(slave == info->slave); slave_free = g_steal_pointer(&info->slave); @@ -6900,7 +7000,7 @@ carrier_changed(NMDevice *self, gboolean carrier) if (priv->ignore_carrier && !carrier) return; - if (nm_device_is_master(self)) { + if (nm_device_is_controller(self)) { if (carrier) { /* If needed, also resume IP configuration that is * waiting for carrier. */ @@ -7069,7 +7169,7 @@ device_recheck_slave_status(NMDevice *self, const NMPlatformLink *plink) plink_master = nm_platform_link_get(nm_device_get_platform(self), plink->master); plink_master_keep_alive = nmp_object_ref(NMP_OBJECT_UP_CAST(plink_master)); } else { - if (priv->master_ifindex == 0) + if (priv->controller_ifindex == 0) goto out; master = NULL; plink_master = NULL; @@ -7082,17 +7182,17 @@ device_recheck_slave_status(NMDevice *self, const NMPlatformLink *plink) goto out; } - priv->master_ifindex = plink->master; + priv->controller_ifindex = plink->master; - if (priv->master) { - if (plink->master > 0 && plink->master == nm_device_get_ifindex(priv->master)) { + if (priv->controller) { + if (plink->master > 0 && plink->master == nm_device_get_ifindex(priv->controller)) { /* call add-slave again. We expect @self already to be added to * the master, but this also triggers a recheck-assume. */ - nm_device_master_add_slave(priv->master, self, FALSE); + nm_device_master_add_slave(priv->controller, self, FALSE); goto out; } - nm_device_master_release_slave(priv->master, + nm_device_master_release_slave(priv->controller, self, RELEASE_SLAVE_TYPE_NO_CONFIG, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); @@ -7133,9 +7233,9 @@ device_ifindex_changed_cb(NMManager *manager, NMDevice *device_changed, NMDevice { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - g_return_if_fail(priv->master_ifindex > 0); + g_return_if_fail(priv->controller_ifindex > 0); - if (priv->master_ifindex != nm_device_get_ifindex(device_changed)) + if (priv->controller_ifindex != nm_device_get_ifindex(device_changed)) return; _LOGD(LOGD_DEVICE, @@ -8157,7 +8257,7 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error) if (nm_clear_g_free(&priv->ip_iface_)) update_prop_ip_iface(self); - priv->master_ifindex = 0; + priv->controller_ifindex = 0; _set_mtu(self, 0); @@ -8394,7 +8494,7 @@ static gboolean nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure) { NMDevicePrivate *priv; - NMDevicePrivate *slave_priv; + NMDevicePrivate *port_priv; SlaveInfo *info; gboolean changed = FALSE; @@ -8402,8 +8502,8 @@ nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure) g_return_val_if_fail(NM_IS_DEVICE(slave), FALSE); g_return_val_if_fail(NM_DEVICE_GET_CLASS(self)->attach_port, FALSE); - priv = NM_DEVICE_GET_PRIVATE(self); - slave_priv = NM_DEVICE_GET_PRIVATE(slave); + priv = NM_DEVICE_GET_PRIVATE(self); + port_priv = NM_DEVICE_GET_PRIVATE(slave); info = find_slave_info(self, slave); @@ -8417,8 +8517,8 @@ nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure) g_return_val_if_fail(nm_device_get_state(slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); if (!info) { - g_return_val_if_fail(!slave_priv->master, FALSE); - g_return_val_if_fail(!slave_priv->is_enslaved, FALSE); + g_return_val_if_fail(!port_priv->controller, FALSE); + g_return_val_if_fail(!port_priv->is_enslaved, FALSE); info = g_slice_new0(SlaveInfo); info->slave = g_object_ref(slave); @@ -8426,25 +8526,25 @@ nm_device_master_add_slave(NMDevice *self, NMDevice *slave, gboolean configure) info->watch_id = g_signal_connect(slave, NM_DEVICE_STATE_CHANGED, G_CALLBACK(slave_state_changed), self); c_list_link_tail(&priv->slaves, &info->lst_slave); - slave_priv->master = g_object_ref(self); + port_priv->controller = g_object_ref(self); _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES); /* no need to emit * - * _notify (slave, PROP_MASTER); + * _notify (slave, PROP_CONTROLLER); * - * because slave_priv->is_enslaved is not true, thus the value + * because port_priv->is_enslaved is not true, thus the value * didn't change yet. */ - g_warn_if_fail(!NM_FLAGS_HAS(slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE)); + g_warn_if_fail(!NM_FLAGS_HAS(port_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE)); nm_device_set_unmanaged_by_flags(slave, NM_UNMANAGED_IS_SLAVE, NM_UNMAN_FLAG_OP_SET_MANAGED, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); changed = TRUE; } else - g_return_val_if_fail(slave_priv->master == self, FALSE); + g_return_val_if_fail(port_priv->controller == self, FALSE); nm_device_queue_recheck_assume(self); nm_device_queue_recheck_assume(slave); @@ -8525,38 +8625,40 @@ nm_device_master_release_slaves_all(NMDevice *self) } /** - * nm_device_is_master: + * nm_device_is_controller: * @self: the device * - * Returns: %TRUE if the device can have slaves + * Returns: %TRUE if the device can have ports */ gboolean -nm_device_is_master(NMDevice *self) +nm_device_is_controller(NMDevice *self) { g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); - return NM_DEVICE_GET_CLASS(self)->is_master; + return NM_DEVICE_GET_CLASS(self)->is_controller; } /** - * nm_device_get_master: + * nm_device_get_controller: * @self: the device * - * If @self has been enslaved by another device, this returns that + * If @self has been set as port by another device, this returns that * device. Otherwise, it returns %NULL. (In particular, note that if - * @self is in the process of activating as a slave, but has not yet - * been enslaved by its master, this will return %NULL.) + * @self is in the process of activating as a port, but has not yet + * been set as port by its controller, this will return %NULL.) + * + * Returns: (transfer none): @self's controller, or %NULL * - * Returns: (transfer none): @self's master, or %NULL + * Since: 1.48 */ NMDevice * -nm_device_get_master(NMDevice *self) +nm_device_get_controller(NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); if (priv->is_enslaved) { - g_return_val_if_fail(priv->master, NULL); - return priv->master; + g_return_val_if_fail(priv->controller, NULL); + return priv->controller; } return NULL; } @@ -8576,7 +8678,7 @@ nm_device_slave_notify_enslave(NMDevice *self, gboolean success) NMConnection *connection = nm_device_get_applied_connection(self); gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); - g_return_if_fail(priv->master); + g_return_if_fail(priv->controller); if (!priv->is_enslaved) { if (success) { @@ -8585,14 +8687,15 @@ nm_device_slave_notify_enslave(NMDevice *self, gboolean success) "Activation: connection '%s' enslaved, continuing activation", nm_connection_get_id(connection)); } else - _LOGI(LOGD_DEVICE, "enslaved to %s", nm_device_get_iface(priv->master)); + _LOGI(LOGD_DEVICE, "enslaved to %s", nm_device_get_iface(priv->controller)); priv->is_enslaved = TRUE; - _notify(self, PROP_MASTER); + _notify(priv->controller, PROP_CONTROLLER); - nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->master)->ports_variant, g_variant_unref); - nm_gobject_notify_together(priv->master, PROP_PORTS, PROP_SLAVES); + nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->controller)->ports_variant, + g_variant_unref); + nm_gobject_notify_together(priv->controller, PROP_PORTS, PROP_SLAVES); } else if (activating) { _LOGW(LOGD_DEVICE, "Activation: connection '%s' could not be enslaved", @@ -8629,7 +8732,7 @@ nm_device_slave_notify_release(NMDevice *self, NMConnection *connection = nm_device_get_applied_connection(self); const char *master_status; - g_return_if_fail(priv->master); + g_return_if_fail(priv->controller); if (!priv->is_enslaved && release_type == RELEASE_SLAVE_TYPE_NO_CONFIG) return; @@ -8661,14 +8764,14 @@ nm_device_slave_notify_release(NMDevice *self, _cancel_activation(self); nm_device_queue_state(self, NM_DEVICE_STATE_DEACTIVATING, reason); } else - _LOGI(LOGD_DEVICE, "released from master device %s", nm_device_get_iface(priv->master)); + _LOGI(LOGD_DEVICE, "released from master device %s", nm_device_get_iface(priv->controller)); priv->is_enslaved = FALSE; - _notify(self, PROP_MASTER); + _notify(priv->controller, PROP_CONTROLLER); - nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->master)->ports_variant, g_variant_unref); - nm_gobject_notify_together(priv->master, PROP_PORTS, PROP_SLAVES); + nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->controller)->ports_variant, g_variant_unref); + nm_gobject_notify_together(priv->controller, PROP_PORTS, PROP_SLAVES); } /** @@ -8692,10 +8795,10 @@ nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config) _dev_ipdhcpx_cleanup(self, AF_INET6, TRUE, FALSE); priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->master) { + if (priv->controller) { /* this is called when something externally messes with the slave or during shut-down. * Release the slave from master, but don't touch the device. */ - nm_device_master_release_slave(priv->master, + nm_device_master_release_slave(priv->controller, self, RELEASE_SLAVE_TYPE_NO_CONFIG, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); @@ -8728,7 +8831,7 @@ is_available(NMDevice *self, NMDeviceCheckDevAvailableFlags flags) return TRUE; /* master types are always available even without carrier. */ - if (nm_device_is_master(self)) + if (nm_device_is_controller(self)) return TRUE; return FALSE; @@ -8768,7 +8871,7 @@ gboolean nm_device_ignore_carrier_by_default(NMDevice *self) { /* master types ignore-carrier by default. */ - return nm_device_is_master(self); + return nm_device_is_controller(self); } gboolean @@ -9207,7 +9310,7 @@ nm_device_generate_connection(NMDevice *self, && NM_IN_STRSET(ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NM_SETTING_IP6_CONFIG_METHOD_DISABLED) - && !nm_setting_connection_get_master(NM_SETTING_CONNECTION(s_con)) + && !nm_setting_connection_get_controller(NM_SETTING_CONNECTION(s_con)) && c_list_is_empty(&priv->slaves)) { NM_SET_OUT(out_maybe_later, TRUE); g_set_error_literal( @@ -9223,7 +9326,7 @@ nm_device_generate_connection(NMDevice *self, */ if (nm_streq0(ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) && nm_streq0(ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) - && !nm_setting_connection_get_master(NM_SETTING_CONNECTION(s_con)) + && !nm_setting_connection_get_controller(NM_SETTING_CONNECTION(s_con)) && c_list_is_empty(&priv->slaves) && !nm_config_data_get_assume_ipv6ll_only(NM_CONFIG_GET_DATA, self)) { _LOGD(LOGD_DEVICE, @@ -9492,7 +9595,7 @@ nm_device_check_slave_connection_compatible(NMDevice *self, NMConnection *slave) g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); g_return_val_if_fail(NM_IS_CONNECTION(slave), FALSE); - if (!nm_device_is_master(self)) + if (!nm_device_is_controller(self)) return FALSE; /* All masters should have connection type set */ @@ -9508,6 +9611,17 @@ nm_device_check_slave_connection_compatible(NMDevice *self, NMConnection *slave) return nm_streq(connection_type, slave_type); } +gboolean +nm_device_can_be_parent(NMDevice *self) +{ + NMDeviceType device_type = nm_device_get_device_type(self); + + if ((device_type == NM_DEVICE_TYPE_OVS_BRIDGE) || (device_type == NM_DEVICE_TYPE_OVS_PORT)) + return FALSE; + else + return TRUE; +} + /** * nm_device_can_assume_connections: * @self: #NMDevice instance @@ -9790,17 +9904,17 @@ master_ready(NMDevice *self, NMActiveConnection *active) NMActiveConnection *master_connection; NMDevice *master; - /* Notify a master device that it has a new slave */ - nm_assert(nm_active_connection_get_master_ready(active)); + /* Notify a controller device that it has a new port */ + nm_assert(nm_active_connection_get_controller_ready(active)); - master_connection = nm_active_connection_get_master(active); + master_connection = nm_active_connection_get_controller(active); master = nm_active_connection_get_device(master_connection); _LOGD(LOGD_DEVICE, "master connection ready; master device %s", nm_device_get_iface(master)); - if (priv->master && priv->master != master) - nm_device_master_release_slave(priv->master, + if (priv->controller && priv->controller != master) + nm_device_master_release_slave(priv->controller, self, RELEASE_SLAVE_TYPE_NO_CONFIG, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); @@ -9816,7 +9930,7 @@ master_ready_cb(NMActiveConnection *active, GParamSpec *pspec, NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_assert(nm_active_connection_get_master_ready(active)); + nm_assert(nm_active_connection_get_controller_ready(active)); if (priv->state == NM_DEVICE_STATE_PREPARE) nm_device_activate_schedule_stage1_device_prepare(self, FALSE); @@ -10063,7 +10177,7 @@ activate_stage1_device_prepare(NMDevice *self) } active = NM_ACTIVE_CONNECTION(priv->act_request.obj); - master = nm_active_connection_get_master(active); + master = nm_active_connection_get_controller(active); if (master) { if (nm_active_connection_get_state(master) >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { NMDevice *master_device = nm_active_connection_get_device(master); @@ -10078,24 +10192,24 @@ activate_stage1_device_prepare(NMDevice *self) nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, failure_reason); return; } - /* If the master connection is ready for slaves, attach ourselves */ - if (!nm_active_connection_get_master_ready(active)) { - if (priv->master_ready_id == 0) { - _LOGD(LOGD_DEVICE, "waiting for master connection to become ready"); - priv->master_ready_id = + /* If the controller connection is ready for ports, attach ourselves */ + if (!nm_active_connection_get_controller_ready(active)) { + if (priv->controller_ready_id == 0) { + _LOGD(LOGD_DEVICE, "waiting for controller connection to become ready"); + priv->controller_ready_id = g_signal_connect(active, - "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, + "notify::" NM_ACTIVE_CONNECTION_INT_CONTROLLER_READY, G_CALLBACK(master_ready_cb), self); } return; } } - nm_clear_g_signal_handler(priv->act_request.obj, &priv->master_ready_id); + nm_clear_g_signal_handler(priv->act_request.obj, &priv->controller_ready_id); if (master) master_ready(self, active); - else if (priv->master) { - nm_device_master_release_slave(priv->master, + else if (priv->controller) { + nm_device_master_release_slave(priv->controller, self, RELEASE_SLAVE_TYPE_CONFIG_FORCE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); @@ -10804,13 +10918,40 @@ _dev_ipdhcpx_set_state(NMDevice *self, int addr_family, NMDeviceIPState state) } static void -_dev_ipdhcpx_cleanup(NMDevice *self, int addr_family, gboolean full_cleanup, gboolean release) +_dev_ipdhcpx_cleanup(NMDevice *self, int addr_family, gboolean full_cleanup, gboolean force_release) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMSettingIPConfig *s_ip4 = NULL; + NMSettingIPConfig *s_ip6 = NULL; + gboolean release; _dev_ipdhcpx_set_state(self, addr_family, NM_DEVICE_IP_STATE_NONE); + if (IS_IPv4) + s_ip4 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG); + else + s_ip6 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG); + + if ((IS_IPv4 && s_ip4) || (!IS_IPv4 && s_ip6)) { + if (nm_setting_ip_config_get_dhcp_send_release(IS_IPv4 ? s_ip4 : s_ip6) + == NM_TERNARY_DEFAULT) + release = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-send-release") + : NM_CON_DEFAULT("ipv6.dhcp-send-release"), + self, + NM_TERNARY_FALSE, + NM_TERNARY_TRUE, + NM_TERNARY_FALSE); + else + release = nm_setting_ip_config_get_dhcp_send_release(IS_IPv4 ? s_ip4 : s_ip6); + + release = force_release || (release && full_cleanup); + } else { + release = force_release; + } + if (full_cleanup && !IS_IPv4) { priv->ipdhcp_data_6.v6.mode = NM_NDISC_DHCP_LEVEL_NONE; priv->ipdhcp_data_6.v6.needed_prefixes = 0; @@ -11306,7 +11447,7 @@ connection_requires_carrier(NMConnection *connection) /* We can progress to IP_CONFIG now, so that we're enslaved. * That may actually cause carrier to go up and thus continue activation. */ s_con = nm_connection_get_setting_connection(connection); - if (nm_setting_connection_get_master(s_con)) + if (nm_setting_connection_get_controller(s_con)) return FALSE; ip4_carrier_wanted = connection_ip_method_requires_carrier(connection, AF_INET, &ip4_used); @@ -11373,25 +11514,32 @@ nm_device_needs_ip6_subnet(NMDevice *self) void nm_device_use_ip6_subnet(NMDevice *self, const NMPlatformIP6Address *subnet) { - nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; - char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; - NMPlatformIP6Address address; + NMConnection *connection = nm_device_get_applied_connection(self); - l3cd = nm_device_create_l3_config_data(self, NM_IP_CONFIG_SOURCE_SHARED); + if (connection) { + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection); - /* Assign a ::1 address in the subnet for us. */ - address = *subnet; - address.address.s6_addr32[3] |= htonl(1); + if (nm_streq(nm_setting_ip_config_get_method(s_ip6), NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; + char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; + NMPlatformIP6Address address; + l3cd = nm_device_create_l3_config_data(self, NM_IP_CONFIG_SOURCE_SHARED); - nm_l3_config_data_add_address_6(l3cd, &address); + /* Assign a ::1 address in the subnet for us. */ + address = *subnet; + address.address.s6_addr32[3] |= htonl(1); - _LOGD(LOGD_IP6, - "ipv6-pd: using %s", - nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf))); + nm_l3_config_data_add_address_6(l3cd, &address); - _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_PD_6, l3cd, FALSE); - _dev_l3_cfg_commit(self, TRUE); - _dev_ipac6_ndisc_set_router_config(self); + _LOGD(LOGD_IP6, + "ipv6-pd: using %s", + nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf))); + + _dev_l3_register_l3cds_set_one(self, L3_CONFIG_DATA_TYPE_PD_6, l3cd, FALSE); + _dev_l3_cfg_commit(self, TRUE); + _dev_ipac6_ndisc_set_router_config(self); + } + } } /* @@ -11768,12 +11916,12 @@ _set_mtu(NMDevice *self, guint32 mtu) priv->mtu = mtu; _notify(self, PROP_MTU); - if (priv->master) { + if (priv->controller) { /* changing the MTU of a slave, might require the master to reset * its MTU. Note that the master usually cannot set a MTU larger * then the slave's. Hence, when the slave increases the MTU, * master might want to retry setting the MTU. */ - nm_device_commit_mtu(priv->master); + nm_device_commit_mtu(priv->controller); } } @@ -12377,6 +12525,8 @@ _dev_sysctl_save_ip6_properties(NMDevice *self) "disable_ipv6", "hop_limit", "use_tempaddr", + "temp_valid_lft", + "temp_prefered_lft", }; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMPlatform *platform = nm_device_get_platform(self); @@ -12476,6 +12626,17 @@ _dev_addrgenmode6_set(NMDevice *self, guint8 addr_gen_mode) } } + nm_device_sysctl_ip_conf_set( + self, + AF_INET6, + "temp_valid_lft", + nm_sprintf_buf(sbuf, "%u", (unsigned) _prop_get_ipv6_temp_valid_lifetime(self))); + nm_device_sysctl_ip_conf_set( + self, + AF_INET6, + "temp_prefered_lft", + nm_sprintf_buf(sbuf, "%u", (unsigned) _prop_get_ipv6_temp_preferred_lifetime(self))); + if (addr_gen_mode == NM_IN6_ADDR_GEN_MODE_NONE) { gs_free char *value = NULL; @@ -12536,7 +12697,7 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const ip_ifindex = nm_device_get_ip_ifindex(self); if (connection_ip_method_requires_carrier(connection, addr_family, NULL) - && nm_device_is_master(self) && !priv->carrier) { + && nm_device_is_controller(self) && !priv->carrier) { if (!priv->ip_data_x[IS_IPv4].wait_for_carrier) { _LOGT_ip(addr_family, "waiting until carrier is on"); priv->ip_data_x[IS_IPv4].wait_for_carrier = TRUE; @@ -12548,7 +12709,7 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const priv->ip_data_x[IS_IPv4].wait_for_carrier = FALSE; } - if (nm_device_is_master(self) && ip_requires_slaves(self, addr_family)) { + if (nm_device_is_controller(self) && ip_requires_slaves(self, addr_family)) { /* If the master has no ready slaves, and depends on slaves for * a successful IP configuration attempt, then postpone IP addressing. */ @@ -12595,7 +12756,7 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { if (!priv->ip_data_x[IS_IPv4].is_ignore) { priv->ip_data_x[IS_IPv4].is_ignore = TRUE; - if (priv->master) { + if (priv->controller) { /* If a device only has an IPv6 link-local address, * we don't generate an assumed connection. Therefore, * when a new slave connection (without IP configuration) @@ -14959,8 +15120,39 @@ _unmanaged_flags2str(NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, g return buf; } +static NMDeviceStateReason +unmanaged_flags_to_reason(NMUnmanagedFlags flags) +{ + /* Even if there are multiple flags, we can only return one reason. + * Return the most important reason. + */ + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_SLEEPING)) + return NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_QUITTING)) + return NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_SETTINGS)) + return NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_PLATFORM_INIT)) + return NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_UDEV)) + return NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_EXPLICIT)) + return NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_CONF)) + return NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_BY_DEFAULT)) + return NM_DEVICE_STATE_REASON_UNMANAGED_BY_DEFAULT; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_EXTERNAL_DOWN)) + return NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN; + + return NM_DEVICE_STATE_REASON_NOW_UNMANAGED; +} + static gboolean -_get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean for_user_request) +_get_managed_by_flags(NMUnmanagedFlags flags, + NMUnmanagedFlags mask, + gboolean for_user_request, + NMDeviceStateReason *unmanaged_reason) { /* Evaluate the managed state based on the unmanaged flags. * @@ -14979,7 +15171,7 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo * * Effectively, this check is redundant, as the code below already * already ensures that. Still, express this invariant explicitly here. */ - if (_get_managed_by_flags(flags, mask, FALSE)) + if (_get_managed_by_flags(flags, mask, FALSE, unmanaged_reason)) return TRUE; /* A for-user-request, is effectively the same as pretending @@ -15022,7 +15214,12 @@ _get_managed_by_flags(NMUnmanagedFlags flags, NMUnmanagedFlags mask, gboolean fo | NM_UNMANAGED_EXTERNAL_DOWN); } - return flags == NM_UNMANAGED_NONE; + if (flags == NM_UNMANAGED_NONE) { + return TRUE; + } else { + NM_SET_OUT(unmanaged_reason, unmanaged_flags_to_reason(flags)); + return FALSE; + } } /** @@ -15051,7 +15248,10 @@ nm_device_get_managed(NMDevice *self, gboolean for_user_request) priv = NM_DEVICE_GET_PRIVATE(self); - return _get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, for_user_request); + return _get_managed_by_flags(priv->unmanaged_flags, + priv->unmanaged_mask, + for_user_request, + NULL); } /** @@ -15190,9 +15390,9 @@ _set_unmanaged_flags(NMDevice *self, (priv->unmanaged_flags | priv->unmanaged_mask) ? "=" : "", (guint) priv->unmanaged_flags, (guint) priv->unmanaged_mask, - (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, FALSE) + (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, FALSE, NULL) ? "managed" - : (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, TRUE) + : (_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, TRUE, NULL) ? "manageable" : "unmanaged")), priv->real ? "" : "/unrealized", @@ -15211,6 +15411,9 @@ _set_unmanaged_flags(NMDevice *self, if (transition_state) { new_state = was_managed ? NM_DEVICE_STATE_UNMANAGED : NM_DEVICE_STATE_UNAVAILABLE; if (new_state == NM_DEVICE_STATE_UNMANAGED) { + /* In state UNMANAGED, the reason always depends on current flags, not on what + * the caller passed. */ + _get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, FALSE, &reason); _cancel_activation(self); } else { /* The assume check should happen before the device transitions to @@ -15225,6 +15428,13 @@ _set_unmanaged_flags(NMDevice *self, nm_device_state_changed(self, new_state, reason); else nm_device_queue_state(self, new_state, reason); + } else { + /* No state change, but possibly update the reason in UNMANAGED */ + if (!_get_managed_by_flags(priv->unmanaged_flags, priv->unmanaged_mask, FALSE, &reason) + && reason != priv->state_reason) { + priv->state_reason = reason; + _notify(self, PROP_STATE_REASON); + } } } @@ -15483,7 +15693,7 @@ nm_device_update_firewall_zone(NMDevice *self) void nm_device_update_metered(NMDevice *self) { -#define NM_METERED_INVALID ((NMMetered) -1) +#define NM_METERED_INVALID ((NMMetered) - 1) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMSettingConnection *setting; NMMetered conn_value, value = NM_METERED_INVALID; @@ -15773,7 +15983,7 @@ check_connection_available(NMDevice *self, return TRUE; } - if (nm_device_is_master(self)) { + if (nm_device_is_controller(self)) { /* master types are always available even without carrier. * Making connection non-available would un-enslave slaves which * is not desired. */ @@ -16164,12 +16374,12 @@ _cleanup_generic_post(NMDevice *self, NMDeviceStateReason reason, CleanupType cl nm_active_connection_set_default(NM_ACTIVE_CONNECTION(priv->act_request.obj), AF_INET, FALSE); - nm_clear_g_signal_handler(priv->act_request.obj, &priv->master_ready_id); + nm_clear_g_signal_handler(priv->act_request.obj, &priv->controller_ready_id); act_request_set(self, NULL); } if (cleanup_type == CLEANUP_TYPE_DECONFIGURE - && ((reason == NM_DEVICE_STATE_REASON_CARRIER && nm_device_is_master(self)) + && ((reason == NM_DEVICE_STATE_REASON_CARRIER && nm_device_is_controller(self)) || !NM_IN_SET(reason, NM_DEVICE_STATE_REASON_NOW_MANAGED, NM_DEVICE_STATE_REASON_CARRIER))) { @@ -16253,9 +16463,9 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), ifindex, NULL); /* slave: mark no longer enslaved */ - if (priv->master && priv->ifindex > 0 + if (priv->controller && priv->ifindex > 0 && nm_platform_link_get_master(nm_device_get_platform(self), priv->ifindex) <= 0) { - nm_device_master_release_slave(priv->master, + nm_device_master_release_slave(priv->controller, self, RELEASE_SLAVE_TYPE_NO_CONFIG, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); @@ -16666,6 +16876,10 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE, FALSE); } break; + case NM_DEVICE_STATE_DEACTIVATING: + /* If we are now deactivating we should enforce IP cleanup. */ + _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_DECONFIGURE, FALSE); + _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE, FALSE); default: break; } @@ -17431,6 +17645,8 @@ nm_device_hw_addr_set(NMDevice *self, const char *addr, const char *detail, gboo * @hwaddr: (out): the cloned MAC address to set on interface * @hwaddr_type: (out): the type of address to set * @hwaddr_detail: (out): the detail (origin) of address to set + * @is_default_special (out): if %TRUE, the cloned MAC comes from + * global default configuration and is a special keyword * @error: on return, an error or %NULL * * Computes the MAC to be set on a interface. On success, one of the @@ -17451,6 +17667,7 @@ _hw_addr_get_cloned(NMDevice *self, char **hwaddr, HwAddrType *hwaddr_type, const char **hwaddr_detail, + gboolean *is_default_special, GError **error) { NMDevicePrivate *priv; @@ -17469,7 +17686,7 @@ _hw_addr_get_cloned(NMDevice *self, if (!connection) g_return_val_if_reached(FALSE); - addr_setting = _prop_get_x_cloned_mac_address(self, connection, is_wifi); + addr_setting = _prop_get_x_cloned_mac_address(self, connection, is_wifi, is_default_special); addr = addr_setting; @@ -17605,7 +17822,7 @@ nm_device_hw_addr_get_cloned(NMDevice *self, gboolean *preserve, GError **error) { - if (!_hw_addr_get_cloned(self, connection, is_wifi, preserve, hwaddr, NULL, NULL, error)) + if (!_hw_addr_get_cloned(self, connection, is_wifi, preserve, hwaddr, NULL, NULL, NULL, error)) return FALSE; return TRUE; @@ -17615,11 +17832,13 @@ gboolean nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean is_wifi) { NMDevicePrivate *priv; - gboolean preserve = FALSE; - gs_free char *hwaddr = NULL; - const char *detail = NULL; - HwAddrType type = HW_ADDR_TYPE_UNSET; - gs_free_error GError *error = NULL; + gboolean preserve = FALSE; + gs_free char *hwaddr = NULL; + const char *detail = NULL; + HwAddrType type = HW_ADDR_TYPE_UNSET; + gs_free_error GError *error = NULL; + gboolean is_default_special = FALSE; + gboolean ret; g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); priv = NM_DEVICE_GET_PRIVATE(self); @@ -17631,6 +17850,7 @@ nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean &hwaddr, &type, &detail, + &is_default_special, &error)) { _LOGW(LOGD_DEVICE, "set-hw-addr: %s", error->message); return FALSE; @@ -17640,8 +17860,22 @@ nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean return nm_device_hw_addr_reset(self, detail); if (hwaddr) { + ret = _hw_addr_set(self, hwaddr, "set-cloned", detail); + if (!ret && is_default_special) { + /* If the distro sets a global special value for the cloned MAC (for + * example, "stable-ssid") and the driver doesn't support changing the + * MAC, all activations will fail on the interface unless users know + * that they need to change the cloned MAC. Be more tolerant to errors + * in case the MAC is global and special. + */ + _LOGE(LOGD_DEVICE, + "ignore error changing the MAC address to globally configured value \"%s\"," + "the device does not support it", + detail); + return TRUE; + } priv->hw_addr_type = type; - return _hw_addr_set(self, hwaddr, "set-cloned", detail); + return ret; } return TRUE; @@ -18283,8 +18517,8 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_PHYSICAL_PORT_ID: g_value_set_string(value, priv->physical_port_id); break; - case PROP_MASTER: - g_value_set_object(value, nm_device_get_master(self)); + case PROP_CONTROLLER: + g_value_set_object(value, nm_device_get_controller(self)); break; case PROP_PARENT: g_value_set_string(value, nm_dbus_track_obj_path_get(&priv->parent_device)); @@ -18602,7 +18836,7 @@ dispose(GObject *object) _cleanup_generic_post(self, NM_DEVICE_STATE_REASON_NONE, CLEANUP_TYPE_KEEP); - nm_assert(priv->master_ready_id == 0); + nm_assert(priv->controller_ready_id == 0); g_hash_table_remove_all(priv->ip6_saved_properties); @@ -19052,11 +19286,12 @@ nm_device_class_init(NMDeviceClass *klass) "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_MASTER] = g_param_spec_object(NM_DEVICE_MASTER, - "", - "", - NM_TYPE_DEVICE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_CONTROLLER] = + g_param_spec_object(NM_DEVICE_CONTROLLER, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_PARENT] = g_param_spec_string(NM_DEVICE_PARENT, "", "", diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index b096d23a..ffe6b1af 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -66,7 +66,7 @@ #define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ #define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ -#define NM_DEVICE_MASTER "master" /* Internal only */ +#define NM_DEVICE_CONTROLLER "controller" /* Internal only */ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ @@ -186,9 +186,9 @@ typedef struct _NMDeviceClass { * a delta in the MTU allowed value due the encapsulation overhead */ guint16 mtu_parent_delta; - /* Whether the device type is a master-type. This depends purely on the + /* Whether the device type is a controller-type. This depends purely on the * type (NMDeviceClass), not the actual device instance. */ - bool is_master : 1; + bool is_controller : 1; /* Force setting the MTU actually means first setting the MTU * to (desired_MTU-1) and then setting the desired_MTU @@ -502,11 +502,11 @@ gboolean nm_device_parent_notify_changed(NMDevice *self, const char *nm_device_parent_find_for_connection(NMDevice *self, const char *current_setting_parent); -/* Master */ -gboolean nm_device_is_master(NMDevice *dev); +/* Controller */ +gboolean nm_device_is_controller(NMDevice *dev); -/* Slave */ -NMDevice *nm_device_get_master(NMDevice *dev); +/* Port */ +NMDevice *nm_device_get_controller(NMDevice *dev); NMActRequest *nm_device_get_act_request(NMDevice *dev); NMSettingsConnection *nm_device_get_settings_connection(NMDevice *dev); @@ -550,6 +550,7 @@ gboolean nm_device_check_connection_compatible(NMDevice *device, GError **error); gboolean nm_device_check_slave_connection_compatible(NMDevice *device, NMConnection *connection); +gboolean nm_device_can_be_parent(NMDevice *device); gboolean nm_device_can_assume_connections(NMDevice *self); gboolean nm_device_unmanage_on_quit(NMDevice *self); diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c index 3bc03ac1..27d04003 100644 --- a/src/core/devices/ovs/nm-device-ovs-bridge.c +++ b/src/core/devices/ovs/nm-device-ovs-bridge.c @@ -171,7 +171,7 @@ nm_device_ovs_bridge_class_init(NMDeviceOvsBridgeClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_BRIDGE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->unrealize = unrealize; diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 17eb2c2d..778f230b 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -355,12 +355,12 @@ ovs_interface_is_netdev_datapath(NMDeviceOvsInterface *self) return FALSE; /* get ovs-port active-connection */ - ac = nm_active_connection_get_master(ac); + ac = nm_active_connection_get_controller(ac); if (!ac) return FALSE; /* get ovs-bridge active-connection */ - ac = nm_active_connection_get_master(ac); + ac = nm_active_connection_get_controller(ac); if (!ac) return FALSE; diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index 258c72f2..e1020280 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -160,7 +160,7 @@ attach_port(NMDevice *device, return TRUE; ac_port = NM_ACTIVE_CONNECTION(nm_device_get_act_request(device)); - ac_bridge = nm_active_connection_get_master(ac_port); + ac_bridge = nm_active_connection_get_controller(ac_port); if (!ac_bridge) { _LOGW(LOGD_DEVICE, "can't attach %s: bridge active-connection not found", @@ -285,7 +285,7 @@ nm_device_ovs_port_class_init(NMDeviceOvsPortClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_PORT_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index d8c3c2c2..1f70537f 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -1006,7 +1006,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static void nm_device_team_init(NMDeviceTeam *self) { - nm_assert(nm_device_is_master(NM_DEVICE(self))); + nm_assert(nm_device_is_controller(NM_DEVICE(self))); } static void @@ -1127,7 +1127,7 @@ nm_device_team_class_init(NMDeviceTeamClass *klass) device_class->connection_type_check_compatible = NM_SETTING_TEAM_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_TEAM); - device_class->is_master = TRUE; + device_class->is_controller = TRUE; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; device_class->complete_connection = complete_connection; diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 47407a1e..89444640 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -774,8 +774,8 @@ check_connection_compatible(NMDevice *device, return FALSE; } - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless); + /* Check for MAC address denylist */ + mac_blacklist = nm_setting_wireless_get_mac_address_denylist(s_wireless); for (i = 0; mac_blacklist[i]; i++) { nm_assert(nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)); diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index 2cd41b27..206113e4 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -1013,8 +1013,8 @@ check_connection_compatible(NMDevice *device, return FALSE; } - /* Check for MAC address blacklist */ - mac_blacklist = nm_setting_wireless_get_mac_address_blacklist(s_wireless); + /* Check for MAC address denylist */ + mac_blacklist = nm_setting_wireless_get_mac_address_denylist(s_wireless); for (i = 0; mac_blacklist[i]; i++) { if (!nm_utils_hwaddr_valid(mac_blacklist[i], ETH_ALEN)) { g_warn_if_reached(); @@ -3374,7 +3374,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) /* Tell the supplicant in which bridge the interface is */ if ((request = nm_device_get_act_request(device)) - && (master_ac = nm_active_connection_get_master(NM_ACTIVE_CONNECTION(request))) + && (master_ac = nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(request))) && (master = nm_active_connection_get_device(master_ac)) && nm_device_get_device_type(master) == NM_DEVICE_TYPE_BRIDGE) { nm_supplicant_interface_set_bridge(priv->sup_iface, nm_device_get_iface(master)); diff --git a/src/core/devices/wifi/nm-wifi-ap.c b/src/core/devices/wifi/nm-wifi-ap.c index d4d3815e..ceb954b7 100644 --- a/src/core/devices/wifi/nm-wifi-ap.c +++ b/src/core/devices/wifi/nm-wifi-ap.c @@ -719,13 +719,14 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) g_value_set_uchar(value, priv->strength); break; case PROP_LAST_SEEN: - g_value_set_int(value, - priv->last_seen_msec != G_MININT64 ? (int) NM_MAX( - nm_utils_monotonic_timestamp_as_boottime(priv->last_seen_msec, - NM_UTILS_NSEC_PER_MSEC) - / 1000, - 1) - : -1); + g_value_set_int( + value, + priv->last_seen_msec != G_MININT64 + ? (int) NM_MAX(nm_utils_monotonic_timestamp_as_boottime(priv->last_seen_msec, + NM_UTILS_NSEC_PER_MSEC) + / 1000, + 1) + : -1); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); diff --git a/src/core/devices/wwan/meson.build b/src/core/devices/wwan/meson.build index 37ef738c..acccb5fd 100644 --- a/src/core/devices/wwan/meson.build +++ b/src/core/devices/wwan/meson.build @@ -4,7 +4,7 @@ wwan_inc = include_directories('.') linker_script = join_paths(meson.current_source_dir(), 'libnm-wwan.ver') -libnm_wwan = shared_module( +libnm_wwan = shared_library( 'nm-wwan', sources: files( 'nm-service-providers.c', @@ -21,6 +21,7 @@ libnm_wwan = shared_module( link_depends: linker_script, install: true, install_dir: nm_plugindir, + override_options: ['b_lundef=false'], ) libnm_wwan_dep = declare_dependency( diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index a150040f..c03446b9 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -1155,6 +1155,8 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho #endif } else { NMPlatformIP6Address address; + NMPlatformIP6Address gw; + const char *gw_string; address_string = mm_bearer_ip_config_get_address(self->_priv.ipv6_config); if (!address_string) { @@ -1165,20 +1167,8 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IPv6 configuration failed: no address given", nm_modem_get_uid(NM_MODEM(self))); + goto out; } - goto out; - } - - address = (NMPlatformIP6Address){}; - - if (!inet_pton(AF_INET6, address_string, &address.address)) { - g_set_error(&error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", - nm_modem_get_uid(NM_MODEM(self)), - address_string); - goto out; } data_port = mm_bearer_get_interface(self->_priv.bearer); @@ -1202,43 +1192,57 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho NM_IP_CONFIG_SOURCE_WWAN); do_auto = TRUE; - address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config); - if (address.plen <= 128) { - if (IN6_IS_ADDR_LINKLOCAL(&address.address)) { - nm_utils_ipv6_interface_identifier_get_from_addr(&iid_data, &address.address); - iid = &iid_data; - } else - do_auto = FALSE; - nm_l3_config_data_add_address_6(l3cd, &address); + if (address_string) { + address = (NMPlatformIP6Address){}; + + if (!inet_pton(AF_INET6, address_string, &address.address)) { + g_set_error(&error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", + nm_modem_get_uid(NM_MODEM(self)), + address_string); + goto out; + } + + address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config); + if (address.plen <= 128) { + if (IN6_IS_ADDR_LINKLOCAL(&address.address)) { + nm_utils_ipv6_interface_identifier_get_from_addr(&iid_data, &address.address); + iid = &iid_data; + } else + do_auto = FALSE; + nm_l3_config_data_add_address_6(l3cd, &address); + } + + _LOGI(" address %s", nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf))); } - _LOGI(" address %s (slaac %s)", - nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf)), - do_auto ? "enabled" : "disabled"); + _LOGI(" slaac %s", do_auto ? "enabled" : "disabled"); - address_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config); - if (address_string) { - if (inet_pton(AF_INET6, address_string, &address.address) != 1) { + gw_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config); + if (gw_string) { + if (inet_pton(AF_INET6, gw_string, &gw.address) != 1) { g_set_error(&error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", nm_modem_get_uid(NM_MODEM(self)), - address_string); + gw_string); goto out; } { const NMPlatformIP6Route r = { .rt_source = NM_IP_CONFIG_SOURCE_WWAN, - .gateway = address.address, + .gateway = gw.address, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, .metric = 0, }; - _LOGI(" gateway %s", address_string); + _LOGI(" gateway %s", gw_string); nm_l3_config_data_add_route_6(l3cd, &r); } } else if (ip_method == NM_MODEM_IP_METHOD_STATIC) { |