diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index 3f55b7e9b9..3dbfbbe06e 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -1004,21 +1004,21 @@ act_stage3_ip_config_start(NMDevice * device, gpointer * out_config, NMDeviceStateReason *out_failure_reason) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + gboolean autoip4 = FALSE; + NMActStageReturn ret; - nm_assert_addr_family(addr_family); + if (priv->connect_bt_type != NM_BT_CAPABILITY_DUN) + goto out_chain_up; - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start(priv->modem, - device, - NM_DEVICE_CLASS(nm_device_bt_parent_class), - out_failure_reason); - } else { - return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); - } - } + if (!NM_IS_IPv4(addr_family)) + return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); + ret = nm_modem_stage3_ip4_config_start(priv->modem, device, &autoip4, out_failure_reason); + if (ret != NM_ACT_STAGE_RETURN_SUCCESS || !autoip4) + return ret; + +out_chain_up: return NM_DEVICE_CLASS(nm_device_bt_parent_class) ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 8df245bb0f..04051bece5 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -93,28 +93,35 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin } static void -ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) +_ppp_ip4_config_handle(NMDevicePpp *self) { - NMDevice * device = NM_DEVICE(user_data); - NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevice * device = NM_DEVICE(self); NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - _LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); + if (!priv->ip4_config) + return; - if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) { - if (nm_device_activate_ip4_state_in_conf(device)) { - nm_device_activate_schedule_ip_config_result(device, - AF_INET, - NM_IP_CONFIG_CAST(config)); - return; - } - } else { - if (priv->ip4_config) - g_object_unref(priv->ip4_config); - priv->ip4_config = g_object_ref(config); + if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG + && nm_device_activate_ip4_state_in_conf(device)) { + nm_device_activate_schedule_ip_config_result( + device, + AF_INET, + NM_IP_CONFIG_CAST(g_steal_pointer(&priv->ip4_config))); + return; } } +static void +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) +{ + NMDevicePpp * self = NM_DEVICE_PPP(user_data); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + + _LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); + nm_g_object_ref_set(&priv->ip4_config, config); + _ppp_ip4_config_handle(self); +} + static gboolean check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { @@ -193,6 +200,15 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_POSTPONE; } +static gboolean +_schedule_ip_config_result(gpointer user_data) +{ + gs_unref_object NMDevicePpp *self = user_data; + + _ppp_ip4_config_handle(self); + return G_SOURCE_REMOVE; +} + static NMActStageReturn act_stage3_ip_config_start(NMDevice * device, int addr_family, @@ -203,13 +219,8 @@ act_stage3_ip_config_start(NMDevice * device, NMDevicePpp * self = NM_DEVICE_PPP(device); NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - if (priv->ip4_config) { - if (out_config) - *out_config = g_steal_pointer(&priv->ip4_config); - else - g_clear_object(&priv->ip4_config); - return NM_ACT_STAGE_RETURN_SUCCESS; - } + if (priv->ip4_config) + nm_g_idle_add(_schedule_ip_config_result, g_object_ref(self)); /* Wait IPCP termination */ return NM_ACT_STAGE_RETURN_POSTPONE; @@ -256,6 +267,8 @@ deactivate(NMDevice *device) nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); g_clear_object(&priv->ppp_manager); } + + g_clear_object(&priv->ip4_config); } static void diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 0a2cf101d1..264c583dda 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -2745,7 +2745,7 @@ nm_device_sysctl_ip_conf_get_int_checked(NMDevice * self, } static void -set_ipv6_token(NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) +set_ipv6_token(NMDevice *self, const NMUtilsIPv6IfaceId *iid, const char *token_str) { NMPlatform * platform; int ifindex; @@ -2761,7 +2761,7 @@ set_ipv6_token(NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) ifindex = nm_device_get_ip_ifindex(self); link = nm_platform_link_get(platform, ifindex); - if (link && link->inet6_token.id == iid.id) { + if (link && link->inet6_token.id == iid->id) { _LOGT(LOGD_DEVICE | LOGD_IP6, "token %s already set", token_str); return; } @@ -3145,8 +3145,9 @@ _set_ip_ifindex(NMDevice *self, int ifindex, const char *ifname) nm_platform_process_events_ensure_link(platform, priv->ip_ifindex, priv->ip_iface); - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - nm_platform_link_set_user_ipv6ll_enabled(platform, priv->ip_ifindex, TRUE); + nm_platform_link_set_inet6_addr_gen_mode(platform, + priv->ip_ifindex, + NM_IN6_ADDR_GEN_MODE_NONE); if (!nm_platform_link_is_up(platform, priv->ip_ifindex)) nm_platform_link_change_flags(platform, priv->ip_ifindex, IFF_UP, TRUE); @@ -6091,8 +6092,8 @@ realize_start_setup(NMDevice * self, if (priv->firmware_version) _notify(self, PROP_FIRMWARE_VERSION); - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled(platform, priv->ifindex); + priv->ipv6ll_handle = (nm_platform_link_get_inet6_addr_gen_mode(platform, priv->ifindex) + == NM_IN6_ADDR_GEN_MODE_NONE); if (nm_platform_link_supports_sriov(platform, priv->ifindex)) capabilities |= NM_DEVICE_CAP_SRIOV; @@ -7345,7 +7346,7 @@ nm_device_generate_connection(NMDevice *self, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64, NM_SETTING_IP6_CONFIG_TOKEN, - nm_utils_inet6_interface_identifier_to_token(pllink->inet6_token, sbuf), + nm_utils_inet6_interface_identifier_to_token(&pllink->inet6_token, sbuf), NULL); } } @@ -9258,7 +9259,7 @@ ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit) if (commit && priv->ndisc_started && ip6_addr_gen_token && nm_utils_ipv6_interface_identifier_get_from_token(&iid, ip6_addr_gen_token)) { - set_ipv6_token(self, iid, ip6_addr_gen_token); + set_ipv6_token(self, &iid, ip6_addr_gen_token); } } @@ -10332,12 +10333,12 @@ check_and_add_ipv6ll_addr(NMDevice *self) const char * stable_id; stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); - if (!nm_utils_ipv6_addr_set_stable_privacy(stable_type, - &lladdr, - nm_device_get_iface(self), - stable_id, - priv->linklocal6_dad_counter++, - &error)) { + if (!nm_utils_ipv6_addr_set_stable_privacy_may_fail(stable_type, + &lladdr, + nm_device_get_iface(self), + stable_id, + priv->linklocal6_dad_counter++, + &error)) { _LOGW(LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message); g_clear_error(&error); linklocal6_failed(self); @@ -10359,7 +10360,7 @@ check_and_add_ipv6ll_addr(NMDevice *self) _LOGW(LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); return; } - nm_utils_ipv6_addr_set_interface_identifier(&lladdr, iid); + nm_utils_ipv6_addr_set_interface_identifier(&lladdr, &iid); addr_type = "EUI-64"; } @@ -10828,58 +10829,48 @@ ndisc_config_changed(NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6); if (changed & NM_NDISC_CONFIG_ADDRESSES) { - guint8 plen; guint32 ifa_flags; /* Check, whether kernel is recent enough to help user space handling RA. * If it's not supported, we have no ipv6-privacy and must add autoconf * addresses as /128. The reason for the /128 is to prevent the kernel * from adding a prefix route for this address. */ - ifa_flags = 0; - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - ifa_flags |= IFA_F_NOPREFIXROUTE; - if (NM_IN_SET(priv->ndisc_use_tempaddr, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) - ifa_flags |= IFA_F_MANAGETEMPADDR; - plen = 64; - } else - plen = 128; + ifa_flags = IFA_F_NOPREFIXROUTE; + if (NM_IN_SET(priv->ndisc_use_tempaddr, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) + ifa_flags |= IFA_F_MANAGETEMPADDR; nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.orig, rdata->addresses, rdata->addresses_n, - plen, + 64, ifa_flags); if (priv->ac_ip6_config.current) { nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.current, rdata->addresses, rdata->addresses_n, - plen, + 64, ifa_flags); } } if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) { - nm_ip6_config_reset_routes_ndisc( - (NMIP6Config *) priv->ac_ip6_config.orig, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table(self, AF_INET6), - nm_device_get_route_metric(self, AF_INET6), - nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + nm_ip6_config_reset_routes_ndisc((NMIP6Config *) priv->ac_ip6_config.orig, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); if (priv->ac_ip6_config.current) { - nm_ip6_config_reset_routes_ndisc( - (NMIP6Config *) priv->ac_ip6_config.current, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table(self, AF_INET6), - nm_device_get_route_metric(self, AF_INET6), - nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + nm_ip6_config_reset_routes_ndisc((NMIP6Config *) priv->ac_ip6_config.current, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); } } @@ -11094,15 +11085,6 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) priv->ndisc_use_tempaddr = use_tempaddr; - if (NM_IN_SET(use_tempaddr, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) - && !nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - _LOGW(LOGD_IP6, - "The kernel does not support extended IFA_FLAGS needed by NM for " - "IPv6 private addresses. This feature is not available"); - } - /* ensure link local is ready... */ if (!linklocal6_start(self)) { /* wait for the LL address to show up */ @@ -11197,21 +11179,20 @@ set_nm_ipv6ll(NMDevice *self, gboolean enable) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); int ifindex = nm_device_get_ip_ifindex(self); - if (!nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - return; - priv->ipv6ll_handle = enable; if (ifindex > 0) { - const char *detail = enable ? "enable" : "disable"; - int r; + int r; - _LOGD(LOGD_IP6, "will %s userland IPv6LL", detail); - r = nm_platform_link_set_user_ipv6ll_enabled(nm_device_get_platform(self), ifindex, enable); + _LOGD(LOGD_IP6, "will %s userland IPv6LL", enable ? "enable" : "disable"); + r = nm_platform_link_set_inet6_addr_gen_mode(nm_device_get_platform(self), + ifindex, + enable ? NM_IN6_ADDR_GEN_MODE_NONE + : NM_IN6_ADDR_GEN_MODE_EUI64); if (r < 0) { _NMLOG(NM_IN_SET(r, -NME_PL_NOT_FOUND, -NME_PL_OPNOTSUPP) ? LOGL_DEBUG : LOGL_WARN, LOGD_IP6, "failed to %s userspace IPv6LL address handling (%s)", - detail, + enable ? "enable" : "disable", nm_strerror(r)); } @@ -11537,45 +11518,6 @@ nm_device_activate_stage3_ip_start(NMDevice *self, int addr_family) return TRUE; } -/* - * activate_stage3_ip_config_start - * - * Begin automatic/manual IP configuration - * - */ -static void -activate_stage3_ip_config_start(NMDevice *self) -{ - int ifindex; - - _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - - _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_LAYER2_READY); - - nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); - - /* Device should be up before we can do anything with it */ - if ((ifindex = nm_device_get_ip_ifindex(self)) > 0 - && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex)) - _LOGW(LOGD_DEVICE, - "interface %s not up for IP configuration", - nm_device_get_ip_iface(self)); - - if (nm_device_activate_ip4_state_in_wait(self) - && !nm_device_activate_stage3_ip_start(self, AF_INET)) - return; - - if (nm_device_activate_ip6_state_in_wait(self) - && !nm_device_activate_stage3_ip_start(self, AF_INET6)) - return; - - /* Proxy */ - nm_device_set_proxy_config(self, NULL); - - check_ip_state(self, TRUE, TRUE); -} - static void fw_change_zone_cb(NMFirewalldManager * firewalld_manager, NMFirewalldManagerCallId *call_id, @@ -11658,20 +11600,19 @@ fw_change_zone(NMDevice *self) } /* - * nm_device_activate_schedule_stage3_ip_config_start + * activate_stage3_ip_config_start + * + * Begin automatic/manual IP configuration * - * Schedule IP configuration start */ -void -nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) +static void +activate_stage3_ip_config_start(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); int ifindex; - g_return_if_fail(NM_IS_DEVICE(self)); - - priv = NM_DEVICE_GET_PRIVATE(self); g_return_if_fail(priv->act_request.obj); + ifindex = nm_device_get_ip_ifindex(self); /* Add the interface to the specified firewall zone */ @@ -11692,6 +11633,50 @@ nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) nm_assert(ifindex <= 0 || priv->fw_state == FIREWALL_STATE_INITIALIZED); + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); + + _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_LAYER2_READY); + + nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); + + /* Device should be up before we can do anything with it */ + if ((ifindex = nm_device_get_ip_ifindex(self)) > 0 + && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex)) + _LOGW(LOGD_DEVICE, + "interface %s not up for IP configuration", + nm_device_get_ip_iface(self)); + + if (nm_device_activate_ip4_state_in_wait(self) + && !nm_device_activate_stage3_ip_start(self, AF_INET)) + return; + + if (nm_device_activate_ip6_state_in_wait(self) + && !nm_device_activate_stage3_ip_start(self, AF_INET6)) + return; + + /* Proxy */ + nm_device_set_proxy_config(self, NULL); + + check_ip_state(self, TRUE, TRUE); +} + +/* + * nm_device_activate_schedule_stage3_ip_config_start + * + * Schedule IP configuration start + */ +void +nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) +{ + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + g_return_if_fail(priv->act_request.obj); + activation_source_schedule(self, activate_stage3_ip_config_start, AF_INET); } @@ -11744,22 +11729,23 @@ activate_stage4_ip_config_timeout_6(NMDevice *self) activate_stage4_ip_config_timeout_x(self, AF_INET6); } +#define activate_stage4_ip_config_timeout_x_fcn(addr_family) \ + (NM_IS_IPv4(addr_family) ? activate_stage4_ip_config_timeout_4 \ + : activate_stage4_ip_config_timeout_6) + void nm_device_activate_schedule_ip_config_timeout(NMDevice *self, int addr_family) { NMDevicePrivate *priv; - const int IS_IPv4 = NM_IS_IPv4(addr_family); g_return_if_fail(NM_IS_DEVICE(self)); - g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); priv = NM_DEVICE_GET_PRIVATE(self); g_return_if_fail(priv->act_request.obj); activation_source_schedule(self, - IS_IPv4 ? activate_stage4_ip_config_timeout_4 - : activate_stage4_ip_config_timeout_6, + activate_stage4_ip_config_timeout_x_fcn(addr_family), addr_family); } @@ -16064,7 +16050,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); - set_ipv6_token(self, iid, "::"); + set_ipv6_token(self, &iid, "::"); if (nm_device_get_applied_setting(self, NM_TYPE_SETTING_TC_CONFIG)) { nm_platform_tfilter_sync(platform, ifindex, NULL); diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c index 4d892e6f4e..1b28546937 100644 --- a/src/core/devices/wwan/nm-device-modem.c +++ b/src/core/devices/wwan/nm-device-modem.c @@ -616,18 +616,20 @@ act_stage3_ip_config_start(NMDevice * device, gpointer * out_config, NMDeviceStateReason *out_failure_reason) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + gboolean autoip4 = FALSE; + NMActStageReturn ret; - nm_assert_addr_family(addr_family); - - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start(priv->modem, - device, - NM_DEVICE_CLASS(nm_device_modem_parent_class), - out_failure_reason); - } else { + if (!NM_IS_IPv4(addr_family)) return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); - } + + ret = nm_modem_stage3_ip4_config_start(priv->modem, device, &autoip4, out_failure_reason); + + if (ret != NM_ACT_STAGE_RETURN_SUCCESS || !autoip4) + return ret; + + return NM_DEVICE_CLASS(nm_device_modem_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static void diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 15baa677ca..fee101a91a 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -727,7 +727,7 @@ ppp_stage3_ip_config_start(NMModem * self, NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem * self, NMDevice * device, - NMDeviceClass * device_class, + gboolean * out_autoip4, NMDeviceStateReason *out_failure_reason) { NMModemPrivate * priv; @@ -740,7 +740,7 @@ nm_modem_stage3_ip4_config_start(NMModem * self, g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail(NM_IS_DEVICE(device), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail(NM_IS_DEVICE_CLASS(device_class), NM_ACT_STAGE_RETURN_FAILURE); + nm_assert(out_autoip4 && !*out_autoip4); req = nm_device_get_act_request(device); g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); @@ -774,7 +774,8 @@ nm_modem_stage3_ip4_config_start(NMModem * self, break; case NM_MODEM_IP_METHOD_AUTO: _LOGD("MODEM_IP_METHOD_AUTO"); - ret = device_class->act_stage3_ip_config_start(device, AF_INET, NULL, out_failure_reason); + *out_autoip4 = TRUE; + ret = NM_ACT_STAGE_RETURN_SUCCESS; break; default: _LOGI("IPv4 configuration disabled"); diff --git a/src/core/devices/wwan/nm-modem.h b/src/core/devices/wwan/nm-modem.h index 87162cfca7..4bc81ff8dd 100644 --- a/src/core/devices/wwan/nm-modem.h +++ b/src/core/devices/wwan/nm-modem.h @@ -210,7 +210,7 @@ void nm_modem_act_stage2_config(NMModem *modem); NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem * modem, NMDevice * device, - NMDeviceClass * device_class, + gboolean * out_autoip4, NMDeviceStateReason *out_failure_reason); NMActStageReturn nm_modem_stage3_ip6_config_start(NMModem * modem, diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c index 80ab38b480..a40d7ce05b 100644 --- a/src/core/ndisc/nm-ndisc.c +++ b/src/core/ndisc/nm-ndisc.c @@ -476,12 +476,12 @@ complete_address(NMNDisc *ndisc, NMNDiscAddress *addr) priv = NM_NDISC_GET_PRIVATE(ndisc); if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { - if (!nm_utils_ipv6_addr_set_stable_privacy(priv->stable_type, - &addr->address, - priv->ifname, - priv->network_id, - addr->dad_counter++, - &error)) { + if (!nm_utils_ipv6_addr_set_stable_privacy_may_fail(priv->stable_type, + &addr->address, + priv->ifname, + priv->network_id, + addr->dad_counter++, + &error)) { _LOGW("complete-address: failed to generate an stable-privacy address: %s", error->message); g_clear_error(&error); @@ -498,7 +498,7 @@ complete_address(NMNDisc *ndisc, NMNDiscAddress *addr) if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) { _LOGD("complete-address: adding an EUI-64 address"); - nm_utils_ipv6_addr_set_interface_identifier(&addr->address, priv->iid); + nm_utils_ipv6_addr_set_interface_identifier(&addr->address, &priv->iid); return TRUE; } diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index dc7c0e460c..2e727e6a1f 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -3426,15 +3426,14 @@ _is_reserved_ipv6_iid(const guint8 *iid) return FALSE; } -static gboolean -_set_stable_privacy(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - const guint8 * host_id, - gsize host_id_len, - GError ** error) +void +nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + const guint8 * host_id, + gsize host_id_len) { nm_auto_free_checksum GChecksum *sum = NULL; guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA256]; @@ -3483,30 +3482,29 @@ _set_stable_privacy(NMUtilsStableType stable_type, } memcpy(addr->s6_addr + 8, &digest[0], 8); - return TRUE; } -gboolean -nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - guint8 * host_id, - gsize host_id_len, - GError ** error) +void +nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter) { - return _set_stable_privacy(stable_type, - addr, - ifname, - network_id, - dad_counter, - host_id, - host_id_len, - error); + const guint8 *host_id; + gsize host_id_len; + + nm_utils_host_id_get(&host_id, &host_id_len); + + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(stable_type, + addr, + ifname, + network_id, + dad_counter, + host_id, + host_id_len); } -#define RFC7217_IDGEN_RETRIES 3 /** * nm_utils_ipv6_addr_set_stable_privacy: * @@ -3516,19 +3514,16 @@ nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type, * Returns: %TRUE on success, %FALSE if the address could not be generated. */ gboolean -nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - GError ** error) +nm_utils_ipv6_addr_set_stable_privacy_may_fail(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + GError ** error) { - const guint8 *host_id; - gsize host_id_len; - g_return_val_if_fail(network_id, FALSE); - if (dad_counter >= RFC7217_IDGEN_RETRIES) { + if (dad_counter >= NM_STABLE_PRIVACY_RFC7217_IDGEN_RETRIES) { g_set_error_literal(error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -3536,16 +3531,8 @@ nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, return FALSE; } - nm_utils_host_id_get(&host_id, &host_id_len); - - return _set_stable_privacy(stable_type, - addr, - ifname, - network_id, - dad_counter, - host_id, - host_id_len, - error); + nm_utils_ipv6_addr_set_stable_privacy(stable_type, addr, ifname, network_id, dad_counter); + return TRUE; } /*****************************************************************************/ diff --git a/src/core/nm-core-utils.h b/src/core/nm-core-utils.h index a2b94e6711..a1fa8830e9 100644 --- a/src/core/nm-core-utils.h +++ b/src/core/nm-core-utils.h @@ -281,21 +281,28 @@ NMUtilsStableType nm_utils_stable_id_parse(const char *stable_id, char *nm_utils_stable_id_random(void); char *nm_utils_stable_id_generated_complete(const char *msg); -gboolean nm_utils_ipv6_addr_set_stable_privacy_impl(NMUtilsStableType stable_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - guint8 * host_id, - gsize host_id_len, - GError ** error); +#define NM_STABLE_PRIVACY_RFC7217_IDGEN_RETRIES 3 -gboolean nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType id_type, - struct in6_addr * addr, - const char * ifname, - const char * network_id, - guint32 dad_counter, - GError ** error); +void nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + const guint8 * host_id, + gsize host_id_len); + +void nm_utils_ipv6_addr_set_stable_privacy(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter); + +gboolean nm_utils_ipv6_addr_set_stable_privacy_may_fail(NMUtilsStableType stable_type, + struct in6_addr * addr, + const char * ifname, + const char * network_id, + guint32 dad_counter, + GError ** error); char *nm_utils_hw_addr_gen_random_eth(const char *current_mac_address, const char *generate_mac_address_mask); diff --git a/src/core/nm-iface-helper.c b/src/core/nm-iface-helper.c index 73000af099..607881e3bb 100644 --- a/src/core/nm-iface-helper.c +++ b/src/core/nm-iface-helper.c @@ -181,41 +181,33 @@ ndisc_config_changed(NMNDisc * ndisc, } if (changed & NM_NDISC_CONFIG_ADDRESSES) { - guint8 plen; guint32 ifa_flags; /* Check, whether kernel is recent enough to help user space handling RA. * If it's not supported, we have no ipv6-privacy and must add autoconf * addresses as /128. The reason for the /128 is to prevent the kernel * from adding a prefix route for this address. */ - ifa_flags = 0; - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - ifa_flags |= IFA_F_NOPREFIXROUTE; - if (NM_IN_SET(global_opt.tempaddr, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) - ifa_flags |= IFA_F_MANAGETEMPADDR; - plen = 64; - } else - plen = 128; + ifa_flags = IFA_F_NOPREFIXROUTE; + if (NM_IN_SET(global_opt.tempaddr, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) + ifa_flags |= IFA_F_MANAGETEMPADDR; nm_ip6_config_reset_addresses_ndisc(ndisc_config, rdata->addresses, rdata->addresses_n, - plen, + 64, ifa_flags); } if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) { - nm_ip6_config_reset_routes_ndisc( - ndisc_config, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - RT_TABLE_MAIN, - global_opt.priority_v6, - nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + nm_ip6_config_reset_routes_ndisc(ndisc_config, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + RT_TABLE_MAIN, + global_opt.priority_v6); } if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { @@ -702,7 +694,9 @@ main(int argc, char *argv[]) guint32 default_ra_timeout; int max_addresses; - nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, gl.ifindex, TRUE); + nm_platform_link_set_inet6_addr_gen_mode(NM_PLATFORM_GET, + gl.ifindex, + NM_IN6_ADDR_GEN_MODE_NONE); if (global_opt.stable_id && (global_opt.stable_id[0] >= '0' && global_opt.stable_id[0] <= '9') diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c index 65e8473749..5ec68bd28c 100644 --- a/src/core/nm-ip6-config.c +++ b/src/core/nm-ip6-config.c @@ -1678,8 +1678,7 @@ nm_ip6_config_reset_routes_ndisc(NMIP6Config * self, const NMNDiscRoute * routes, guint routes_n, guint32 route_table, - guint32 route_metric, - gboolean kernel_support_rta_pref) + guint32 route_metric) { NMIP6ConfigPrivate *priv; guint i; @@ -1735,7 +1734,6 @@ nm_ip6_config_reset_routes_ndisc(NMIP6Config * self, .table_coerced = nm_platform_route_table_coerce(route_table), .metric = route_metric, }; - const NMIcmpv6RouterPref first_pref = gateways[0].preference; for (i = 0; i < gateways_n; i++) { r.gateway = gateways[i].address; @@ -1753,13 +1751,6 @@ nm_ip6_config_reset_routes_ndisc(NMIP6Config * self, changed = TRUE; new_best_default_route = _nm_ip_config_best_default_route_find_better(new_best_default_route, obj_new); - - if (first_pref != gateways[i].preference && !kernel_support_rta_pref) { - /* We are unable to configure a router preference. Hence, we skip all gateways - * with a different preference from the first gateway. Note, that the gateways - * are sorted in order of highest to lowest preference. */ - break; - } } } diff --git a/src/core/nm-ip6-config.h b/src/core/nm-ip6-config.h index 8694ab0c0f..a54040fc59 100644 --- a/src/core/nm-ip6-config.h +++ b/src/core/nm-ip6-config.h @@ -198,8 +198,7 @@ void nm_ip6_config_reset_routes_ndisc(NMIP6Config * self, const struct _NMNDiscRoute * routes, guint routes_n, guint32 route_table, - guint32 route_metric, - gboolean kernel_support_rta_pref); + guint32 route_metric); void nm_ip6_config_update_routes_metric(NMIP6Config *self, gint64 metric); diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c index 51ea92f634..4af73b34e6 100644 --- a/src/core/nm-l3-config-data.c +++ b/src/core/nm-l3-config-data.c @@ -689,9 +689,11 @@ nm_l3_config_data_ref(const NML3ConfigData *self) const NML3ConfigData * nm_l3_config_data_ref_and_seal(const NML3ConfigData *self) { - nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); - ((NML3ConfigData *) self)->is_sealed = TRUE; - ((NML3ConfigData *) self)->ref_count++; + if (self) { + nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); + ((NML3ConfigData *) self)->is_sealed = TRUE; + ((NML3ConfigData *) self)->ref_count++; + } return self; } @@ -2373,11 +2375,7 @@ nm_l3_config_data_add_dependent_routes(NML3ConfigData *self, /*****************************************************************************/ static void -_init_from_connection_ip(NML3ConfigData *self, - int addr_family, - NMConnection * connection, - guint32 route_table, - guint32 route_metric) +_init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *connection) { const int IS_IPv4 = NM_IS_IPv4(addr_family); NMSettingIPConfig *s_ip; @@ -2409,17 +2407,17 @@ _init_from_connection_ip(NML3ConfigData *self, if (IS_IPv4) { r.r4 = (NMPlatformIP4Route){ - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .gateway = gateway_bin.addr4, - .table_coerced = nm_platform_route_table_coerce(route_table), - .metric = route_metric, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .gateway = gateway_bin.addr4, + .table_any = TRUE, + .metric_any = TRUE, }; } else { r.r6 = (NMPlatformIP6Route){ - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .gateway = gateway_bin.addr6, - .table_coerced = nm_platform_route_table_coerce(route_table), - .metric = route_metric, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .gateway = gateway_bin.addr6, + .table_any = TRUE, + .metric_any = TRUE, }; } @@ -2474,6 +2472,7 @@ _init_from_connection_ip(NML3ConfigData *self, NMIPAddr next_hop_bin; gint64 metric64; guint32 metric; + gboolean metric_any; guint plen; nm_assert(nm_ip_route_get_family(s_route) == addr_family); @@ -2482,11 +2481,14 @@ _init_from_connection_ip(NML3ConfigData *self, nm_ip_route_get_next_hop_binary(s_route, &next_hop_bin); metric64 = nm_ip_route_get_metric(s_route); - if (metric64 < 0) - metric = route_metric; - else - metric = metric64; - metric = nm_utils_ip_route_metric_normalize(addr_family, metric); + if (metric64 < 0) { + metric_any = TRUE; + metric = 0; + } else { + metric_any = FALSE; + metric = metric64; + metric = nm_utils_ip_route_metric_normalize(addr_family, metric); + } plen = nm_ip_route_get_prefix(s_route); @@ -2494,25 +2496,27 @@ _init_from_connection_ip(NML3ConfigData *self, if (IS_IPv4) { r.r4 = (NMPlatformIP4Route){ - .network = network_bin.addr4, - .plen = nm_ip_route_get_prefix(s_route), - .gateway = next_hop_bin.addr4, - .metric = metric, - .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = network_bin.addr4, + .plen = nm_ip_route_get_prefix(s_route), + .gateway = next_hop_bin.addr4, + .metric_any = metric_any, + .metric = metric, + .rt_source = NM_IP_CONFIG_SOURCE_USER, }; nm_assert(r.r4.plen <= 32); } else { r.r6 = (NMPlatformIP6Route){ - .network = network_bin.addr6, - .plen = nm_ip_route_get_prefix(s_route), - .gateway = next_hop_bin.addr6, - .metric = metric, - .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = network_bin.addr6, + .plen = nm_ip_route_get_prefix(s_route), + .gateway = next_hop_bin.addr6, + .metric_any = metric_any, + .metric = metric, + .rt_source = NM_IP_CONFIG_SOURCE_USER, }; nm_assert(r.r6.plen <= 128); } - nm_utils_ip_route_attribute_to_platform(addr_family, s_route, &r.rx, route_table); + nm_utils_ip_route_attribute_to_platform(addr_family, s_route, &r.rx, -1); nm_l3_config_data_add_route(self, addr_family, NULL, &r.rx); } @@ -2551,19 +2555,15 @@ _init_from_connection_ip(NML3ConfigData *self, NML3ConfigData * nm_l3_config_data_new_from_connection(NMDedupMultiIndex *multi_idx, int ifindex, - NMConnection * connection, - guint32 route_table_4, - guint32 route_table_6, - guint32 route_metric_4, - guint32 route_metric_6) + NMConnection * connection) { NML3ConfigData *self; NMSettingProxy *s_proxy; self = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_USER); - _init_from_connection_ip(self, AF_INET, connection, route_table_4, route_metric_4); - _init_from_connection_ip(self, AF_INET6, connection, route_table_6, route_metric_6); + _init_from_connection_ip(self, AF_INET, connection); + _init_from_connection_ip(self, AF_INET6, connection); s_proxy = _nm_connection_get_setting(connection, NM_TYPE_SETTING_PROXY); if (s_proxy) { @@ -2919,7 +2919,7 @@ nm_l3_config_data_new_clone(const NML3ConfigData *src, int ifindex) if (ifindex <= 0) ifindex = src->ifindex; - self = nm_l3_config_data_new(src->multi_idx, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN); + self = nm_l3_config_data_new(src->multi_idx, ifindex, src->source); nm_l3_config_data_merge(self, src, NM_L3_CONFIG_MERGE_FLAGS_CLONE, diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h index 9274d8896d..0ea5bd0e69 100644 --- a/src/core/nm-l3-config-data.h +++ b/src/core/nm-l3-config-data.h @@ -138,11 +138,7 @@ NML3ConfigData *nm_l3_config_data_new_clone(const NML3ConfigData *src, int ifind NML3ConfigData *nm_l3_config_data_new_from_connection(NMDedupMultiIndex *multi_idx, int ifindex, - NMConnection * connection, - guint32 route_table_4, - guint32 route_table_6, - guint32 route_metric_4, - guint32 route_metric_6); + NMConnection * connection); NML3ConfigData *nm_l3_config_data_new_from_platform(NMDedupMultiIndex * multi_idx, int ifindex, diff --git a/src/core/nm-l3-ipv4ll.c b/src/core/nm-l3-ipv4ll.c index fcec44baf3..2df87852bb 100644 --- a/src/core/nm-l3-ipv4ll.c +++ b/src/core/nm-l3-ipv4ll.c @@ -317,41 +317,10 @@ _acd_info_is_good(const NML3AcdAddrInfo *acd_info) /*****************************************************************************/ -static NMPlatformIP4Address * -_l3cd_config_plat_init_addr(NMPlatformIP4Address *a, int ifindex, in_addr_t addr) -{ - nm_assert(nm_utils_ip4_address_is_link_local(addr)); - - *a = (NMPlatformIP4Address){ - .ifindex = ifindex, - .address = addr, - .peer_address = addr, - .plen = ADDR_IPV4LL_PREFIX_LEN, - .addr_source = NM_IP_CONFIG_SOURCE_IP4LL, - }; - return a; -} - -static NMPlatformIP4Route * -_l3cd_config_plat_init_route(NMPlatformIP4Route *r, int ifindex) -{ - *r = (NMPlatformIP4Route){ - .ifindex = ifindex, - .network = htonl(0xE0000000u), - .plen = 4, - .rt_source = NM_IP_CONFIG_SOURCE_IP4LL, - .table_any = TRUE, - .metric_any = TRUE, - }; - return r; -} - static const NML3ConfigData * _l3cd_config_create(int ifindex, in_addr_t addr, NMDedupMultiIndex *multi_idx) { nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; - NMPlatformIP4Address a; - NMPlatformIP4Route r; nm_assert(nm_utils_ip4_address_is_link_local(addr)); nm_assert(ifindex > 0); @@ -359,8 +328,21 @@ _l3cd_config_create(int ifindex, in_addr_t addr, NMDedupMultiIndex *multi_idx) l3cd = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_IP4LL); - nm_l3_config_data_add_address_4(l3cd, _l3cd_config_plat_init_addr(&a, ifindex, addr)); - nm_l3_config_data_add_route_4(l3cd, _l3cd_config_plat_init_route(&r, ifindex)); + nm_l3_config_data_add_address_4( + l3cd, + NM_PLATFORM_IP4_ADDRESS_INIT(.ifindex = ifindex, + .address = addr, + .peer_address = addr, + .plen = ADDR_IPV4LL_PREFIX_LEN, + .addr_source = NM_IP_CONFIG_SOURCE_IP4LL)); + + nm_l3_config_data_add_route_4(l3cd, + NM_PLATFORM_IP4_ROUTE_INIT(.ifindex = ifindex, + .network = htonl(0xE0000000u), + .plen = 4, + .rt_source = NM_IP_CONFIG_SOURCE_IP4LL, + .table_any = TRUE, + .metric_any = TRUE)); return nm_l3_config_data_seal(g_steal_pointer(&l3cd)); } diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 2ea93677ea..4f661aa060 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -314,7 +314,7 @@ static NM_UTILS_ENUM2STR_DEFINE(_l3_acd_defend_type_to_string, NML3AcdDefendType, NM_UTILS_ENUM2STR(NM_L3_ACD_DEFEND_TYPE_ALWAYS, "always"), NM_UTILS_ENUM2STR(NM_L3_ACD_DEFEND_TYPE_NEVER, "never"), - NM_UTILS_ENUM2STR(NM_L3_ACD_DEFEND_TYPE_NONE, "none"), + NM_UTILS_ENUM2STR(_NM_L3_ACD_DEFEND_TYPE_NONE, "none"), NM_UTILS_ENUM2STR(NM_L3_ACD_DEFEND_TYPE_ONCE, "once"), ); static NM_UTILS_LOOKUP_DEFINE(_l3_acd_defend_type_to_nacd, @@ -1042,7 +1042,7 @@ _acd_data_collect_tracks_data(const AcdData * acd_data, guint32 * out_best_acd_timeout_msec, NML3AcdDefendType *out_best_acd_defend_type) { - NML3AcdDefendType best_acd_defend_type = NM_L3_ACD_DEFEND_TYPE_NONE; + NML3AcdDefendType best_acd_defend_type = _NM_L3_ACD_DEFEND_TYPE_NONE; guint32 best_acd_timeout_msec = G_MAXUINT32; guint n = 0; guint i; @@ -1061,7 +1061,7 @@ _acd_data_collect_tracks_data(const AcdData * acd_data, best_acd_defend_type = acd_track->_priv.acd_defend_type_track; } - nm_assert(n == 0 || best_acd_defend_type > NM_L3_ACD_DEFEND_TYPE_NONE); + nm_assert(n == 0 || best_acd_defend_type > _NM_L3_ACD_DEFEND_TYPE_NONE); nm_assert(best_acd_defend_type <= NM_L3_ACD_DEFEND_TYPE_ALWAYS); NM_SET_OUT(out_best_acd_timeout_msec, n > 0 ? best_acd_timeout_msec : 0u); @@ -1134,9 +1134,9 @@ _l3_acd_nacd_event_down_timeout_cb(gpointer user_data) static gboolean _l3_acd_nacd_event(int fd, GIOCondition condition, gpointer user_data) { - NML3Cfg *self = user_data; - gboolean success = FALSE; - int r; + gs_unref_object NML3Cfg *self = g_object_ref(user_data); + gboolean success = FALSE; + int r; nm_assert(NM_IS_L3CFG(self)); nm_assert(self->priv.p->nacd); @@ -1153,6 +1153,13 @@ _l3_acd_nacd_event(int fd, GIOCondition condition, gpointer user_data) AcdData * acd_data; NAcdEvent * event; + if (!self->priv.p->nacd) { + /* In the loop we emit signals, where *anything* might happen. + * Check that we still have the nacd instance. */ + success = TRUE; + goto out; + } + r = n_acd_pop_event(self->priv.p->nacd, &event); if (r) { _LOGT("acd: pop-event failed with error %d", r); @@ -1525,8 +1532,8 @@ _l3_acd_data_add(NML3Cfg * self, .n_track_infos_alloc = 0, .acd_event_notify_lst = C_LIST_INIT(acd_data->acd_event_notify_lst), .probing_timestamp_msec = 0, - .acd_defend_type_desired = NM_L3_ACD_DEFEND_TYPE_NONE, - .acd_defend_type_current = NM_L3_ACD_DEFEND_TYPE_NONE, + .acd_defend_type_desired = _NM_L3_ACD_DEFEND_TYPE_NONE, + .acd_defend_type_current = _NM_L3_ACD_DEFEND_TYPE_NONE, .acd_defend_type_is_active = FALSE, }; c_list_link_tail(&self->priv.p->acd_lst_head, &acd_data->acd_lst); @@ -2462,7 +2469,7 @@ handle_start_defending: ACD_STATE_CHANGE_MODE_INIT_REAPPLY, ACD_STATE_CHANGE_MODE_POST_COMMIT)); - nm_assert(acd_data->acd_defend_type_desired > NM_L3_ACD_DEFEND_TYPE_NONE); + nm_assert(acd_data->acd_defend_type_desired > _NM_L3_ACD_DEFEND_TYPE_NONE); nm_assert(acd_data->acd_defend_type_desired <= NM_L3_ACD_DEFEND_TYPE_ALWAYS); if (acd_data->acd_defend_type_desired != acd_data->acd_defend_type_current) { @@ -2595,6 +2602,14 @@ nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self) return TRUE; } +gboolean +nm_l3cfg_commit_on_idle_is_scheduled(NML3Cfg *self) +{ + nm_assert(NM_IS_L3CFG(self)); + + return !!(self->priv.p->commit_on_idle_source); +} + /*****************************************************************************/ #define _l3_config_datas_at(l3_config_datas, idx) \ diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index d4438cbe3a..63f786f99a 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -22,7 +22,7 @@ #define NM_L3CFG_SIGNAL_NOTIFY "l3cfg-notify" typedef enum _nm_packed { - NM_L3_ACD_DEFEND_TYPE_NONE, + _NM_L3_ACD_DEFEND_TYPE_NONE, NM_L3_ACD_DEFEND_TYPE_NEVER, NM_L3_ACD_DEFEND_TYPE_ONCE, NM_L3_ACD_DEFEND_TYPE_ALWAYS, @@ -334,6 +334,8 @@ void nm_l3cfg_commit(NML3Cfg *self, NML3CfgCommitType commit_type); gboolean nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self); +gboolean nm_l3cfg_commit_on_idle_is_scheduled(NML3Cfg *self); + /*****************************************************************************/ const NML3AcdAddrInfo *nm_l3cfg_get_acd_addr_info(NML3Cfg *self, in_addr_t addr); diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index 88049092da..394274daf3 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -602,28 +602,47 @@ test_bridge_addr(void) g_assert(plink); g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { - g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + if (nmtstp_is_root_test()) { + g_assert_cmpint(nm_platform_link_get_inet6_addr_gen_mode(NM_PLATFORM_GET, link.ifindex), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); + g_assert_cmpint(_nm_platform_link_get_inet6_addr_gen_mode(plink), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); g_assert(NMTST_NM_ERR_SUCCESS( - nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex, TRUE))); - g_assert(nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + nm_platform_link_set_inet6_addr_gen_mode(NM_PLATFORM_GET, + link.ifindex, + NM_IN6_ADDR_GEN_MODE_NONE))); + g_assert_cmpint(nm_platform_link_get_inet6_addr_gen_mode(NM_PLATFORM_GET, link.ifindex), + ==, + NM_IN6_ADDR_GEN_MODE_NONE); plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); g_assert(plink); g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); + g_assert_cmpint(_nm_platform_link_get_inet6_addr_gen_mode(plink), + ==, + NM_IN6_ADDR_GEN_MODE_NONE); g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE); g_assert(NMTST_NM_ERR_SUCCESS( - nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex, FALSE))); - g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + nm_platform_link_set_inet6_addr_gen_mode(NM_PLATFORM_GET, + link.ifindex, + NM_IN6_ADDR_GEN_MODE_EUI64))); + g_assert_cmpint(nm_platform_link_get_inet6_addr_gen_mode(NM_PLATFORM_GET, link.ifindex), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); g_assert(plink); g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); + g_assert_cmpint(_nm_platform_link_get_inet6_addr_gen_mode(plink), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); diff --git a/src/core/tests/test-utils.c b/src/core/tests/test-utils.c index 1d562bde09..59d5fd5331 100644 --- a/src/core/tests/test-utils.c +++ b/src/core/tests/test-utils.c @@ -16,60 +16,55 @@ test_stable_privacy(void) struct in6_addr addr1; inet_pton(AF_INET6, "1234::", &addr1); - nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID, - &addr1, - "eth666", - "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", - 0, - (guint8 *) "key", - 3, - NULL); + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID, + &addr1, + "eth666", + "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", + 0, + (guint8 *) "key", + 3); nmtst_assert_ip6_address(&addr1, "1234::4ceb:14cd:3d54:793f"); /* We get an address without the UUID. */ inet_pton(AF_INET6, "1::", &addr1); - nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID, - &addr1, - "eth666", - "", - 384, - (guint8 *) "key", - 3, - NULL); + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID, + &addr1, + "eth666", + "", + 384, + (guint8 *) "key", + 3); nmtst_assert_ip6_address(&addr1, "1::11aa:2530:9144:dafa"); /* We get a different address in a different network. */ inet_pton(AF_INET6, "2::", &addr1); - nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_UUID, - &addr1, - "eth666", - "", - 384, - (guint8 *) "key", - 3, - NULL); + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_UUID, + &addr1, + "eth666", + "", + 384, + (guint8 *) "key", + 3); nmtst_assert_ip6_address(&addr1, "2::338e:8d:c11:8726"); inet_pton(AF_INET6, "1234::", &addr1); - nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_STABLE_ID, - &addr1, - "eth666", - "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", - 0, - (guint8 *) "key", - 3, - NULL); + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_STABLE_ID, + &addr1, + "eth666", + "6b138152-9f3e-4b97-aaf7-e6e553f2a24e", + 0, + (guint8 *) "key", + 3); nmtst_assert_ip6_address(&addr1, "1234::ad4c:ae44:3d30:af1e"); inet_pton(AF_INET6, "1234::", &addr1); - nm_utils_ipv6_addr_set_stable_privacy_impl(NM_UTILS_STABLE_TYPE_STABLE_ID, - &addr1, - "eth666", - "stable-id-1", - 0, - (guint8 *) "key", - 3, - NULL); + nm_utils_ipv6_addr_set_stable_privacy_with_host_id(NM_UTILS_STABLE_TYPE_STABLE_ID, + &addr1, + "eth666", + "stable-id-1", + 0, + (guint8 *) "key", + 3); nmtst_assert_ip6_address(&addr1, "1234::4944:67b0:7a6c:1cf"); } diff --git a/src/libnm-client-impl/tests/test-nm-client.c b/src/libnm-client-impl/tests/test-nm-client.c index c1e3793af9..a3fc5847e3 100644 --- a/src/libnm-client-impl/tests/test-nm-client.c +++ b/src/libnm-client-impl/tests/test-nm-client.c @@ -948,7 +948,7 @@ _test_connection_invalid_find_connections(gpointer element, gpointer needle, gpo static void test_connection_invalid(void) { - NMTSTC_SERVICE_INFO_SETUP(my_sinfo) + NMTSTC_SERVICE_INFO_SETUP(my_sinfo); gs_unref_object NMConnection *connection = NULL; NMSettingConnection * s_con; gs_unref_object NMClient *client = NULL; diff --git a/src/libnm-client-test/nm-test-libnm-utils.h b/src/libnm-client-test/nm-test-libnm-utils.h index 58909304d0..4997ab33a5 100644 --- a/src/libnm-client-test/nm-test-libnm-utils.h +++ b/src/libnm-client-test/nm-test-libnm-utils.h @@ -28,17 +28,15 @@ _nmtstc_auto_service_cleanup(NMTstcServiceInfo **info) } #define nmtstc_auto_service_cleanup nm_auto(_nmtstc_auto_service_cleanup) -#define NMTSTC_SERVICE_INFO_SETUP(sinfo) \ - NM_PRAGMA_WARNING_DISABLE("-Wunused-variable") \ - nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = ({ \ - NMTstcServiceInfo *_sinfo; \ - \ - _sinfo = nmtstc_service_init(); \ - if (!nmtstc_service_available(_sinfo)) \ - return; \ - _sinfo; \ - }); \ - NM_PRAGMA_WARNING_REENABLE +#define NMTSTC_SERVICE_INFO_SETUP(sinfo) \ + _nm_unused nmtstc_auto_service_cleanup NMTstcServiceInfo *sinfo = ({ \ + NMTstcServiceInfo *_sinfo; \ + \ + _sinfo = nmtstc_service_init(); \ + if (!nmtstc_service_available(_sinfo)) \ + return; \ + _sinfo; \ + }) NMDevice *nmtstc_service_add_device(NMTstcServiceInfo *info, NMClient * client, diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 22354d17df..11636520c2 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -140,9 +140,9 @@ _nm_utils_inet6_is_token(const struct in6_addr *in6addr) * token. */ void -nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr *addr, const NMUtilsIPv6IfaceId iid) +nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr *addr, const NMUtilsIPv6IfaceId *iid) { - memcpy(addr->s6_addr + 8, &iid.id_u8, 8); + memcpy(addr->s6_addr + 8, &iid->id_u8, 8); } /** @@ -198,8 +198,8 @@ nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, const * Returns: the input buffer filled with the id as string. */ const char * -nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, - char buf[static INET6_ADDRSTRLEN]) +nm_utils_inet6_interface_identifier_to_token(const NMUtilsIPv6IfaceId *iid, + char buf[static INET6_ADDRSTRLEN]) { struct in6_addr i6_token = {.s6_addr = { 0, @@ -761,7 +761,7 @@ out: /*****************************************************************************/ -char _nm_utils_to_string_buffer[]; +_nm_thread_local char _nm_utils_to_string_buffer[] = {0}; void nm_utils_to_string_buffer_init(char **buf, gsize *len) diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 975897602d..9e299d57a9 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -371,8 +371,8 @@ typedef struct _NMUtilsIPv6IfaceId { } \ } -void nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr * addr, - const NMUtilsIPv6IfaceId iid); +void nm_utils_ipv6_addr_set_interface_identifier(struct in6_addr * addr, + const NMUtilsIPv6IfaceId *iid); void nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid, const struct in6_addr *addr); @@ -380,7 +380,7 @@ void nm_utils_ipv6_interface_identifier_get_from_addr(NMUtilsIPv6IfaceId * iid gboolean nm_utils_ipv6_interface_identifier_get_from_token(NMUtilsIPv6IfaceId *iid, const char * token); -const char *nm_utils_inet6_interface_identifier_to_token(NMUtilsIPv6IfaceId iid, +const char *nm_utils_inet6_interface_identifier_to_token(const NMUtilsIPv6IfaceId *iid, char buf[static INET6_ADDRSTRLEN]); gboolean nm_utils_get_ipv6_interface_identifier(NMLinkType link_type, @@ -1048,7 +1048,7 @@ int _nm_utils_ascii_str_to_bool(const char *str, int default_value); /*****************************************************************************/ -extern char _nm_utils_to_string_buffer[2096]; +_nm_thread_local extern char _nm_utils_to_string_buffer[2096]; void nm_utils_to_string_buffer_init(char **buf, gsize *len); gboolean nm_utils_to_string_buffer_init_null(gconstpointer obj, char **buf, gsize *len); diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index c0c57618f9..4af9bfbd64 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -1279,15 +1279,6 @@ _parse_af_inet6(NMPlatform * platform, token_valid = TRUE; } - /* Hack to detect support addrgenmode of the kernel. We only parse - * netlink messages that we receive from kernel, hence this check - * is valid. */ - if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { - /* IFLA_INET6_ADDR_GEN_MODE was added in kernel 3.17, dated 5 October, 2014. */ - _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL, - tb[IFLA_INET6_ADDR_GEN_MODE] ? 1 : -1); - } - if (tb[IFLA_INET6_ADDR_GEN_MODE]) { i6_addr_gen_mode_inv = _nm_platform_uint8_inv(nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE])); if (i6_addr_gen_mode_inv == 0) { @@ -3592,13 +3583,6 @@ rta_multipath_done:; obj->ip_route.lock_mtu = NM_FLAGS_HAS(lock, 1 << RTAX_MTU); if (!is_v4) { - if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)) { - /* Detect support for RTA_PREF by inspecting the netlink message. - * RTA_PREF was added in kernel 4.1, dated 21 June, 2015. */ - _nm_platform_kernel_support_init(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF, - tb[RTA_PREF] ? 1 : -1); - } - if (tb[RTA_PREF]) obj->ip6_route.rt_pref = nla_get_u8(tb[RTA_PREF]); } @@ -4084,7 +4068,7 @@ nmp_object_new_from_nl(NMPlatform * platform, /*****************************************************************************/ static gboolean -_nl_msg_new_link_set_afspec(struct nl_msg *msg, int addr_gen_mode, NMUtilsIPv6IfaceId *iid) +_nl_msg_new_link_set_afspec(struct nl_msg *msg, int addr_gen_mode, const NMUtilsIPv6IfaceId *iid) { struct nlattr *af_spec; struct nlattr *af_attr; @@ -4102,11 +4086,9 @@ _nl_msg_new_link_set_afspec(struct nl_msg *msg, int addr_gen_mode, NMUtilsIPv6If NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); if (iid) { - struct in6_addr i6_token = {.s6_addr = { - 0, - }}; + struct in6_addr i6_token = IN6ADDR_ANY_INIT; - nm_utils_ipv6_addr_set_interface_identifier(&i6_token, *iid); + nm_utils_ipv6_addr_set_interface_identifier(&i6_token, iid); NLA_PUT(msg, IFLA_INET6_TOKEN, sizeof(struct in6_addr), &i6_token); } @@ -6924,27 +6906,6 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events msghdr = nlmsg_hdr(msg); - if (!_nm_platform_kernel_support_detected(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) - && msghdr->nlmsg_type == RTM_NEWADDR) { - /* IFA_FLAGS is set for IPv4 and IPv6 addresses. It was added first to IPv6, - * but if we encounter an IPv4 address with IFA_FLAGS, we surely have support. */ - if (nlmsg_valid_hdr(msghdr, sizeof(struct ifaddrmsg)) - && NM_IN_SET(((struct ifaddrmsg *) nlmsg_data(msghdr))->ifa_family, - AF_INET, - AF_INET6)) { - /* see if the nl_msg contains the IFA_FLAGS attribute. If it does, - * we assume, that the kernel supports extended flags, IFA_F_MANAGETEMPADDR - * and IFA_F_NOPREFIXROUTE for IPv6. They were added together in kernel 3.14, - * dated 30 March, 2014. - * - * For IPv4, IFA_F_NOPREFIXROUTE was added later, but there is no easy - * way to detect kernel support. */ - _nm_platform_kernel_support_init( - NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS, - !!nlmsg_find_attr(msghdr, sizeof(struct ifaddrmsg), IFA_FLAGS) ? 1 : -1); - } - } - if (!handle_events) return; @@ -7507,19 +7468,14 @@ link_change_flags(NMPlatform *platform, int ifindex, unsigned flags_mask, unsign } static int -link_set_user_ipv6ll_enabled(NMPlatform *platform, int ifindex, gboolean enabled) +link_set_inet6_addr_gen_mode(NMPlatform *platform, int ifindex, guint8 mode) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - guint8 mode = enabled ? NM_IN6_ADDR_GEN_MODE_NONE : NM_IN6_ADDR_GEN_MODE_EUI64; + char sbuf[100]; _LOGD("link: change %d: user-ipv6ll: set IPv6 address generation mode to %s", ifindex, - nm_platform_link_inet6_addrgenmode2str(mode, NULL, 0)); - - if (!nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { - _LOGD("link: change %d: user-ipv6ll: not supported", ifindex); - return -NME_PL_OPNOTSUPP; - } + nm_platform_link_inet6_addrgenmode2str(mode, sbuf, sizeof(sbuf))); nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); if (!nlmsg || !_nl_msg_new_link_set_afspec(nlmsg, mode, NULL)) @@ -7529,7 +7485,7 @@ link_set_user_ipv6ll_enabled(NMPlatform *platform, int ifindex, gboolean enabled } static gboolean -link_set_token(NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +link_set_token(NMPlatform *platform, int ifindex, const NMUtilsIPv6IfaceId *iid) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; char sbuf[NM_UTILS_INET_ADDRSTRLEN]; @@ -7539,7 +7495,7 @@ link_set_token(NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) nm_utils_inet6_interface_identifier_to_token(iid, sbuf)); nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); - if (!nlmsg || !_nl_msg_new_link_set_afspec(nlmsg, -1, &iid)) + if (!nlmsg || !_nl_msg_new_link_set_afspec(nlmsg, -1, iid)) g_return_val_if_reached(FALSE); return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); @@ -9666,7 +9622,7 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass) platform_class->link_change_flags = link_change_flags; - platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_inet6_addr_gen_mode = link_set_inet6_addr_gen_mode; platform_class->link_set_token = link_set_token; platform_class->link_set_address = link_set_address; diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 1301121f4c..80cfe97b13 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -300,24 +300,6 @@ static const struct { const char *name; const char *desc; } _nm_platform_kernel_support_info[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = { - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS] = - { - .compile_time_default = TRUE, - .name = "EXTENDED_IFA_FLAGS", - .desc = "IPv6 temporary addresses support", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL] = - { - .compile_time_default = TRUE, - .name = "USER_IPV6LL", - .desc = "IFLA_INET6_ADDR_GEN_MODE support", - }, - [NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF] = - { - .compile_time_default = (RTA_MAX >= 20 /* RTA_PREF */), - .name = "RTA_PREF", - .desc = "ability to set router preference for IPv6 routes", - }, [NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV] = { .compile_time_default = (FRA_MAX >= 19 /* FRA_L3MDEV */), @@ -1618,7 +1600,7 @@ nm_platform_link_uses_arp(NMPlatform *self, int ifindex) * Returns: %TRUE a tokenized identifier was available */ gboolean -nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) +nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid) { _CHECK_SELF(self, klass, FALSE); @@ -1656,47 +1638,20 @@ nm_platform_link_get_udev_device(NMPlatform *self, int ifindex) return obj_cache ? obj_cache->_link.udev.device : NULL; } -/** - * nm_platform_link_get_user_ip6vll_enabled: - * @self: platform instance - * @ifindex: Interface index - * - * Check whether NM handles IPv6LL address creation for the link. If the - * platform or OS doesn't support changing the IPv6LL address mode, this call - * will fail and return %FALSE. - * - * Returns: %TRUE if NM handles the IPv6LL address for @ifindex - */ -gboolean -nm_platform_link_get_user_ipv6ll_enabled(NMPlatform *self, int ifindex) +int +nm_platform_link_get_inet6_addr_gen_mode(NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; - - pllink = nm_platform_link_get(self, ifindex); - if (pllink && pllink->inet6_addr_gen_mode_inv) - return _nm_platform_uint8_inv(pllink->inet6_addr_gen_mode_inv) == NM_IN6_ADDR_GEN_MODE_NONE; - return FALSE; + return _nm_platform_link_get_inet6_addr_gen_mode(nm_platform_link_get(self, ifindex)); } -/** - * nm_platform_link_set_user_ip6vll_enabled: - * @self: platform instance - * @ifindex: Interface index - * - * Set whether NM handles IPv6LL address creation for the link. If the - * platform or OS doesn't support changing the IPv6LL address mode, this call - * will fail and return %FALSE. - * - * Returns: the negative nm-error on failure. - */ int -nm_platform_link_set_user_ipv6ll_enabled(NMPlatform *self, int ifindex, gboolean enabled) +nm_platform_link_set_inet6_addr_gen_mode(NMPlatform *self, int ifindex, guint8 mode) { _CHECK_SELF(self, klass, -NME_BUG); g_return_val_if_fail(ifindex > 0, -NME_BUG); - return klass->link_set_user_ipv6ll_enabled(self, ifindex, enabled); + return klass->link_set_inet6_addr_gen_mode(self, ifindex, mode); } /** @@ -3947,7 +3902,6 @@ nm_platform_ip_address_sync(NMPlatform *self, gs_unref_hashtable GHashTable *known_addresses_idx = NULL; GPtrArray * plat_addresses; GHashTable * known_subnets = NULL; - guint32 ifa_flags; guint i_plat; guint i_know; guint i; @@ -4174,10 +4128,6 @@ next_plat:; if (IS_IPv4) ip4_addr_subnets_destroy_index(known_subnets, known_addresses); - ifa_flags = nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS) - ? IFA_F_NOPREFIXROUTE - : 0; - /* Add missing addresses. New addresses are added by kernel with top * priority. */ @@ -4212,7 +4162,7 @@ next_plat:; nm_platform_ip4_broadcast_address_from_addr(&known_address->a4), lifetime, preferred, - ifa_flags, + IFA_F_NOPREFIXROUTE, known_address->a4.label)) { /* ignore error, for unclear reasons. */ } @@ -4224,7 +4174,7 @@ next_plat:; known_address->a6.peer_address, lifetime, preferred, - ifa_flags | known_address->a6.n_ifa_flags)) + IFA_F_NOPREFIXROUTE | known_address->a6.n_ifa_flags)) return FALSE; } } @@ -5652,7 +5602,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) str_broadcast[0] ? str_broadcast : "", link->inet6_token.id ? " inet6token " : "", link->inet6_token.id - ? nm_utils_inet6_interface_identifier_to_token(link->inet6_token, str_inet6_token) + ? nm_utils_inet6_interface_identifier_to_token(&link->inet6_token, str_inet6_token) : "", link->driver ? " driver " : "", link->driver ?: "", diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index b20b18c4dd..22cfb092be 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -616,6 +616,10 @@ typedef union { #undef __NMPlatformIPRoute_COMMON +#define NM_PLATFORM_IP4_ROUTE_INIT(...) (&((const NMPlatformIP4Route){__VA_ARGS__})) + +#define NM_PLATFORM_IP6_ROUTE_INIT(...) (&((const NMPlatformIP6Route){__VA_ARGS__})) + typedef struct { /* struct fib_rule_uid_range */ guint32 start; @@ -1011,9 +1015,6 @@ typedef void (*NMPlatformAsyncCallback)(GError *error, gpointer user_data); /*****************************************************************************/ typedef enum { - NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL, - NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL, @@ -1109,8 +1110,8 @@ typedef struct { unsigned flags_mask, unsigned flags_set); - int (*link_set_user_ipv6ll_enabled)(NMPlatform *self, int ifindex, gboolean enabled); - gboolean (*link_set_token)(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); + int (*link_set_inet6_addr_gen_mode)(NMPlatform *self, int ifindex, guint8 enabled); + gboolean (*link_set_token)(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid); gboolean (*link_get_permanent_address_ethtool)(NMPlatform * self, int ifindex, @@ -1394,6 +1395,14 @@ _nm_platform_uint8_inv(guint8 scope) return (guint8) ~scope; } +static inline int +_nm_platform_link_get_inet6_addr_gen_mode(const NMPlatformLink *pllink) +{ + if (!pllink) + return -ENODEV; + return _nm_platform_uint8_inv(pllink->inet6_addr_gen_mode_inv); +} + /** * nm_platform_route_type_coerce: * @table: the route type, in its original value. @@ -1811,7 +1820,7 @@ gboolean nm_platform_link_is_up(NMPlatform *self, int ifindex); gboolean nm_platform_link_is_connected(NMPlatform *self, int ifindex); gboolean nm_platform_link_uses_arp(NMPlatform *self, int ifindex); guint32 nm_platform_link_get_mtu(NMPlatform *self, int ifindex); -gboolean nm_platform_link_get_user_ipv6ll_enabled(NMPlatform *self, int ifindex); +int nm_platform_link_get_inet6_addr_gen_mode(NMPlatform *self, int ifindex); gconstpointer nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length); @@ -1861,8 +1870,9 @@ const char *nm_platform_link_get_path(NMPlatform *self, int ifindex); struct udev_device *nm_platform_link_get_udev_device(NMPlatform *self, int ifindex); -int nm_platform_link_set_user_ipv6ll_enabled(NMPlatform *self, int ifindex, gboolean enabled); -gboolean nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); +int nm_platform_link_set_inet6_addr_gen_mode(NMPlatform *self, int ifindex, guint8 mode); +gboolean +nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid); gboolean nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, int ifindex, diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h index 021829db4b..bf789fb077 100644 --- a/src/libnm-platform/nmp-object.h +++ b/src/libnm-platform/nmp-object.h @@ -120,10 +120,10 @@ typedef enum { /*< skip >*/ * the index NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX with * matching v4/v6 and ifindex -- or maybe not at all if it isn't visible. * */ -typedef enum { /*< skip >*/ - NMP_CACHE_ID_TYPE_NONE, +typedef enum { + NMP_CACHE_ID_TYPE_NONE, - /* all the objects of a certain type. + /* all the objects of a certain type. * * This index is special. It is the only one that contains *all* object. * Other indexes may consider some object as non "partitionable", hence @@ -136,20 +136,20 @@ typedef enum { /*< skip >*/ * expose all links, even invisible ones. For addresses/routes, this * distinction doesn't exist, as all addresses/routes that are alive * are visible as well. */ - NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, - /* index for the link objects by ifname. */ - NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + /* index for the link objects by ifname. */ + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, - /* indices for the visible default-routes, ignoring ifindex. + /* indices for the visible default-routes, ignoring ifindex. * This index only contains two partitions: all visible default-routes, * separate for IPv4 and IPv6. */ - NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, + NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, - /* all the objects that have an ifindex (by object-type) for an ifindex. */ - NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + /* all the objects that have an ifindex (by object-type) for an ifindex. */ + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, - /* Consider all the destination fields of a route, that is, the ID without the ifindex + /* Consider all the destination fields of a route, that is, the ID without the ifindex * and gateway (meaning: network/plen,metric). * The reason for this is that `ip route change` can replace an existing route * and modify its ifindex/gateway. Effectively, that means it deletes an existing @@ -157,15 +157,15 @@ typedef enum { /*< skip >*/ * sends one RTM_NEWADDR notification without notifying about the deletion. We detect * that by having this index to contain overlapping routes which require special * cache-resync. */ - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, + NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - /* a filter for objects that track an explicit address family. + /* a filter for objects that track an explicit address family. * * Note that currently on NMPObjectRoutingRule is indexed by this filter. */ - NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, + NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, - __NMP_CACHE_ID_TYPE_MAX, - NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, + __NMP_CACHE_ID_TYPE_MAX, + NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, } NMPCacheIdType; typedef struct { @@ -625,6 +625,20 @@ nmp_object_unref(const NMPObject *obj) _changed; \ }) +#define nm_clear_nmp_object_up_cast(ptr) \ + ({ \ + typeof(ptr) _ptr = (ptr); \ + typeof(*_ptr) _pptr; \ + gboolean _changed = FALSE; \ + \ + if (_ptr && (_pptr = *_ptr)) { \ + *_ptr = NULL; \ + nmp_object_unref(NMP_OBJECT_UP_CAST(_pptr)); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + static inline gboolean nmp_object_ref_set(const NMPObject **pp, const NMPObject *obj) { @@ -643,6 +657,25 @@ nmp_object_ref_set(const NMPObject **pp, const NMPObject *obj) return _changed; } +static inline gboolean +nmp_object_ref_set_up_cast(gpointer pp, gconstpointer obj) +{ + gboolean _changed = FALSE; + const NMPObject *p; + gconstpointer * pp2 = pp; + + nm_assert(!pp2 || !*pp2 || NMP_OBJECT_IS_VALID(NMP_OBJECT_UP_CAST(*pp2))); + nm_assert(!obj || NMP_OBJECT_IS_VALID(NMP_OBJECT_UP_CAST(obj))); + + if (pp2 && ((p = *pp2) != obj)) { + nmp_object_ref(NMP_OBJECT_UP_CAST(obj)); + *pp2 = obj; + nmp_object_unref(NMP_OBJECT_UP_CAST(p)); + _changed = TRUE; + } + return _changed; +} + NMPObject *nmp_object_new(NMPObjectType obj_type, gconstpointer plobj); NMPObject *nmp_object_new_link(int ifindex); diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h index 1101dbc48f..a23c40e680 100644 --- a/src/libnm-std-aux/nm-std-aux.h +++ b/src/libnm-std-aux/nm-std-aux.h @@ -175,38 +175,40 @@ typedef uint64_t _nm_bitwise nm_be64_t; #if NM_MORE_ASSERTS #define nm_assert(cond) \ - do { \ + ({ \ _nm_assert_call(cond); \ - } while (0) + 1; \ + }) #define nm_assert_se(cond) \ - do { \ + ({ \ if (NM_LIKELY(cond)) { \ ; \ } else { \ _nm_assert_call(0 && (cond)); \ } \ - } while (0) + 1; \ + }) #define nm_assert_not_reached() \ - do { \ + ({ \ _nm_assert_call_not_reached(); \ - } while (0) + 1; \ + }) #else #define nm_assert(cond) \ - do { \ + ({ \ if (0) { \ if (cond) {} \ } \ - } while (0) + 1; \ + }) #define nm_assert_se(cond) \ - do { \ + ({ \ if (NM_LIKELY(cond)) { \ ; \ } \ - } while (0) -#define nm_assert_not_reached() \ - do { \ - ; \ - } while (0) + 1; \ + }) +#define nm_assert_not_reached() ({ 1; }) #endif /* This is similar nm_assert_not_reached(), but it's supposed to be used only during