diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index cc39be25bd..7834462f50 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -858,7 +858,7 @@ GPtrArray * _nm_utils_copy_array(const GPtrArray *array, NMUtilsCopyFunc copy_func, GDestroyNotify free_func) { GPtrArray *copy; - int i; + guint i; if (!array) return g_ptr_array_new_with_free_func(free_func); @@ -1276,7 +1276,8 @@ nm_utils_security_valid(NMUtilsSecurityType type, gboolean nm_utils_wep_key_valid(const char *key, NMWepKeyType wep_type) { - int keylen, i; + gsize keylen; + gsize i; if (!key) return FALSE; @@ -1321,7 +1322,8 @@ nm_utils_wep_key_valid(const char *key, NMWepKeyType wep_type) gboolean nm_utils_wpa_psk_valid(const char *psk) { - int psklen, i; + gsize psklen; + gsize i; if (!psk) return FALSE; @@ -1354,7 +1356,7 @@ GVariant * nm_utils_ip4_dns_to_variant(char **dns) { GVariantBuilder builder; - int i; + gsize i; g_variant_builder_init(&builder, G_VARIANT_TYPE("au")); @@ -1385,13 +1387,12 @@ nm_utils_ip4_dns_from_variant(GVariant *value) const guint32 *array; gsize length; char ** dns; - int i; + gsize i; g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("au")), NULL); array = g_variant_get_fixed_array(value, &length, sizeof(guint32)); - dns = g_new(char *, length + 1); - + dns = g_new(char *, length + 1u); for (i = 0; i < length; i++) dns[i] = nm_utils_inet4_ntop_dup(array[i]); dns[i] = NULL; @@ -1416,7 +1417,7 @@ GVariant * nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init(&builder, G_VARIANT_TYPE("aau")); @@ -1424,16 +1425,23 @@ nm_utils_ip4_addresses_to_variant(GPtrArray *addresses, const char *gateway) for (i = 0; i < addresses->len; i++) { NMIPAddress *addr = addresses->pdata[i]; guint32 array[3]; + in_addr_t gw; if (nm_ip_address_get_family(addr) != AF_INET) continue; + gw = 0u; + if (gateway) { + in_addr_t a; + + if (inet_pton(AF_INET, gateway, &a) == 1) + gw = a; + gateway = NULL; + } + nm_ip_address_get_address_binary(addr, &array[0]); array[1] = nm_ip_address_get_prefix(addr); - if (i == 0 && gateway) - inet_pton(AF_INET, gateway, &array[2]); - else - array[2] = 0; + array[2] = gw; g_variant_builder_add( &builder, @@ -1519,7 +1527,7 @@ GVariant * nm_utils_ip4_routes_to_variant(GPtrArray *routes) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init(&builder, G_VARIANT_TYPE("aau")); @@ -1655,28 +1663,26 @@ nm_utils_ip4_get_default_prefix(guint32 ip) * Utility function to convert an array of IP address strings int a #GVariant of * type 'aay' representing an array of IPv6 addresses. * + * If a string cannot be parsed, it will be silently ignored. + * * Returns: (transfer none): a new floating #GVariant representing @dns. **/ GVariant * nm_utils_ip6_dns_to_variant(char **dns) { GVariantBuilder builder; - int i; + gsize i; g_variant_builder_init(&builder, G_VARIANT_TYPE("aay")); - if (dns) { for (i = 0; dns[i]; i++) { struct in6_addr ip; - inet_pton(AF_INET6, dns[i], &ip); - g_variant_builder_add( - &builder, - "@ay", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &ip, sizeof(ip), 1)); + if (inet_pton(AF_INET6, dns[i], &ip) != 1) + continue; + g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&ip)); } } - return g_variant_builder_end(&builder); } @@ -1697,7 +1703,7 @@ nm_utils_ip6_dns_from_variant(GVariant *value) GVariantIter iter; GVariant * ip_var; char ** dns; - int i; + gsize i; g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aay")), NULL); @@ -1737,32 +1743,34 @@ GVariant * nm_utils_ip6_addresses_to_variant(GPtrArray *addresses, const char *gateway) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ayuay)")); if (addresses) { for (i = 0; i < addresses->len; i++) { - NMIPAddress * addr = addresses->pdata[i]; - struct in6_addr ip_bytes, gateway_bytes; - GVariant * ip_var, *gateway_var; - guint32 prefix; + NMIPAddress * addr = addresses->pdata[i]; + struct in6_addr address_bin; + struct in6_addr gateway_bin_data; + const struct in6_addr *gateway_bin; if (nm_ip_address_get_family(addr) != AF_INET6) continue; - nm_ip_address_get_address_binary(addr, &ip_bytes); - ip_var = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &ip_bytes, 16, 1); + nm_ip_address_get_address_binary(addr, &address_bin); - prefix = nm_ip_address_get_prefix(addr); + gateway_bin = &in6addr_any; + if (gateway) { + if (inet_pton(AF_INET6, gateway, &gateway_bin_data) == 1) + gateway_bin = &gateway_bin_data; + gateway = NULL; + } - if (i == 0 && gateway) - inet_pton(AF_INET6, gateway, &gateway_bytes); - else - memset(&gateway_bytes, 0, sizeof(gateway_bytes)); - gateway_var = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &gateway_bytes, 16, 1); - - g_variant_builder_add(&builder, "(@ayu@ay)", ip_var, prefix, gateway_var); + g_variant_builder_add(&builder, + "(@ayu@ay)", + nm_g_variant_new_ay_in6addr(&address_bin), + (guint32) nm_ip_address_get_prefix(addr), + nm_g_variant_new_ay_in6addr(gateway_bin)); } } @@ -1860,29 +1868,32 @@ GVariant * nm_utils_ip6_routes_to_variant(GPtrArray *routes) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init(&builder, G_VARIANT_TYPE("a(ayuayu)")); if (routes) { for (i = 0; i < routes->len; i++) { NMIPRoute * route = routes->pdata[i]; - struct in6_addr dest_bytes, next_hop_bytes; - GVariant * dest, *next_hop; - guint32 prefix, metric; + struct in6_addr dest_bytes; + struct in6_addr next_hop_bytes; + guint32 metric; if (nm_ip_route_get_family(route) != AF_INET6) continue; nm_ip_route_get_dest_binary(route, &dest_bytes); - dest = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &dest_bytes, 16, 1); - prefix = nm_ip_route_get_prefix(route); nm_ip_route_get_next_hop_binary(route, &next_hop_bytes); - next_hop = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &next_hop_bytes, 16, 1); - /* The old routes format uses "0" for default, not "-1" */ - metric = MAX(0, nm_ip_route_get_metric(route)); - g_variant_builder_add(&builder, "(@ayu@ayu)", dest, prefix, next_hop, metric); + /* The old routes format uses "0" for default, not "-1" */ + metric = NM_MAX(0, nm_ip_route_get_metric(route)); + + g_variant_builder_add(&builder, + "(@ayu@ayu)", + nm_g_variant_new_ay_in6addr(&dest_bytes), + (guint32) nm_ip_route_get_prefix(route), + nm_g_variant_new_ay_in6addr(&next_hop_bytes), + metric); } } @@ -2088,7 +2099,7 @@ GVariant * nm_utils_ip_routes_to_variant(GPtrArray *routes) { GVariantBuilder builder; - int i; + guint i; g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); @@ -3147,7 +3158,7 @@ nm_utils_uuid_is_null(const NMUuid *uuid) if (!uuid) return TRUE; - for (i = 0; i < G_N_ELEMENTS(uuid->uuid); i++) { + for (i = 0; i < (int) G_N_ELEMENTS(uuid->uuid); i++) { if (uuid->uuid[i]) return FALSE; } @@ -3334,7 +3345,7 @@ static gboolean file_has_extension(const char *filename, const char *extensions[]) { const char *ext; - int i; + gsize i; ext = strrchr(filename, '.'); if (!ext) @@ -3833,7 +3844,7 @@ nm_utils_wifi_is_channel_valid(guint32 channel, const char *band) G_STATIC_ASSERT(G_N_ELEMENTS(table) > 0); \ G_STATIC_ASSERT(G_N_ELEMENTS(table) == G_N_ELEMENTS(table_freqs)); \ \ - for (i = 0; i < G_N_ELEMENTS(table); i++) { \ + for (i = 0; i < (int) G_N_ELEMENTS(table); i++) { \ nm_assert((i == G_N_ELEMENTS(table) - 1) == (table[i].chan == 0)); \ nm_assert((i == G_N_ELEMENTS(table) - 1) == (table[i].freq == 0)); \ nm_assert(table[i].freq == table_freqs[i]); \ diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 06bf9dd049..e8aba6104c 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -1219,6 +1219,27 @@ nm_g_variant_is_of_type(GVariant *value, const GVariantType *type) return value && g_variant_is_of_type(value, type); } +static inline GVariant * +nm_g_variant_new_ay_inaddr(int addr_family, gconstpointer addr) +{ + return g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, + addr ?: &nm_ip_addr_zero, + nm_utils_addr_family_to_size(addr_family), + 1); +} + +static inline GVariant * +nm_g_variant_new_ay_in4addr(in_addr_t addr) +{ + return nm_g_variant_new_ay_inaddr(AF_INET, &addr); +} + +static inline GVariant * +nm_g_variant_new_ay_in6addr(const struct in6_addr *addr) +{ + return nm_g_variant_new_ay_inaddr(AF_INET6, addr); +} + static inline void nm_g_variant_builder_add_sv(GVariantBuilder *builder, const char *key, GVariant *val) { diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 3d1b3a4489..0e2e97b65b 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1495,15 +1495,12 @@ nm_utils_ip_addresses_to_dbus(int addr_family, g_variant_builder_add( &builder_legacy, "(@ayu@ay)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &address->a6.address, 16, 1), + nm_g_variant_new_ay_in6addr(&address->a6.address), address->a6.plen, - g_variant_new_fixed_array( - G_VARIANT_TYPE_BYTE, + nm_g_variant_new_ay_in6addr( (i == 0 && best_default_route) ? &NMP_OBJECT_CAST_IP6_ROUTE(best_default_route)->gateway - : &in6addr_any, - 16, - 1)); + : &in6addr_any)); } } } @@ -1622,13 +1619,12 @@ nm_utils_ip_routes_to_dbus(int addr_family, 4, sizeof(guint32))); } else { - g_variant_builder_add( - &builder_legacy, - "(@ayu@ayu)", - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &r->r6.network, 16, 1), - (guint32) r->r6.plen, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &r->r6.gateway, 16, 1), - (guint32) r->r6.metric); + g_variant_builder_add(&builder_legacy, + "(@ayu@ayu)", + nm_g_variant_new_ay_in6addr(&r->r6.network), + (guint32) r->r6.plen, + nm_g_variant_new_ay_in6addr(&r->r6.gateway), + (guint32) r->r6.metric); } } } diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 5f8eff183b..054197e0c3 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -58,6 +58,14 @@ gboolean nm_device_activate_stage3_ip4_start(NMDevice *self); gboolean nm_device_activate_stage3_ip6_start(NMDevice *self); +static inline gboolean +nm_device_activate_stage3_ip_start(NMDevice *self, int addr_family) +{ + if (NM_IS_IPv4(addr_family)) + return nm_device_activate_stage3_ip4_start(self); + return nm_device_activate_stage3_ip6_start(self); +} + gboolean nm_device_bring_up(NMDevice *self, gboolean wait, gboolean *no_firmware); void nm_device_take_down(NMDevice *self, gboolean block); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index bb6fdc05de..8a743d1e62 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -117,7 +117,7 @@ parent_hwaddr_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_d */ s_ip6 = nm_connection_get_setting_ip6_config(connection); if (s_ip6) - nm_device_reactivate_ip6_config(device, s_ip6, s_ip6); + nm_device_reactivate_ip_config(device, AF_INET6, s_ip6, s_ip6); } } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index a30e42df41..bd08de9e19 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12262,55 +12262,86 @@ _nm_device_hash_check_invalid_keys(GHashTable * hash, } void -nm_device_reactivate_ip4_config(NMDevice * self, - NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new) +nm_device_reactivate_ip_config(NMDevice * self, + int addr_family, + NMSettingIPConfig *s_ip_old, + NMSettingIPConfig *s_ip_new) { + const int IS_IPv4 = NM_IS_IPv4(addr_family); NMDevicePrivate *priv; - const char * method_old, *method_new; + const char * method_old; + const char * method_new; g_return_if_fail(NM_IS_DEVICE(self)); + priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->ip_state_4 != NM_DEVICE_IP_STATE_NONE) { - g_clear_object(&priv->con_ip_config_4); - g_clear_object(&priv->ext_ip_config_4); + if (priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_NONE) + return; + + g_clear_object(&priv->con_ip_config_x[IS_IPv4]); + g_clear_object(&priv->ext_ip_config_x[IS_IPv4]); + if (IS_IPv4) { g_clear_object(&priv->dev_ip_config_4.current); - g_clear_object(&priv->dev2_ip_config_4.current); - priv->con_ip_config_4 = nm_device_ip4_config_new(self); + } else { + g_clear_object(&priv->ac_ip6_config.current); + g_clear_object(&priv->dhcp6.ip6_config.current); + } + g_clear_object(&priv->dev2_ip_config_x[IS_IPv4].current); + + if (!IS_IPv4) { + if (priv->ipv6ll_handle && !IN6_IS_ADDR_UNSPECIFIED(&priv->ipv6ll_addr)) + priv->ipv6ll_has = TRUE; + } + + priv->con_ip_config_x[IS_IPv4] = nm_device_ip_config_new(self, addr_family); + + if (IS_IPv4) { nm_ip4_config_merge_setting(priv->con_ip_config_4, - s_ip4_new, + s_ip_new, _prop_get_connection_mdns(self), _prop_get_connection_llmnr(self), nm_device_get_route_table(self, AF_INET), nm_device_get_route_metric(self, AF_INET)); + } else { + nm_ip6_config_merge_setting(priv->con_ip_config_6, + s_ip_new, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); + } - method_old = s_ip4_old ? nm_setting_ip_config_get_method(s_ip4_old) - : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - method_new = s_ip4_new ? nm_setting_ip_config_get_method(s_ip4_new) - : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + method_old = nm_setting_ip_config_get_method(s_ip_old) + ?: (IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + method_new = nm_setting_ip_config_get_method(s_ip_new) + ?: (IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - if (!nm_streq0(method_old, method_new)) { - _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_DECONFIGURE); - _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - if (!nm_device_activate_stage3_ip4_start(self)) - _LOGW(LOGD_IP4, "Failed to apply IPv4 configuration"); - return; + if (!nm_streq0(method_old, method_new)) { + _cleanup_ip_pre(self, addr_family, CLEANUP_TYPE_DECONFIGURE); + _set_ip_state(self, addr_family, NM_DEVICE_IP_STATE_WAIT); + if (!nm_device_activate_stage3_ip_start(self, addr_family)) { + _LOGW(LOGD_IP4, + "Failed to apply IPv%c configuration", + nm_utils_addr_family_to_char(addr_family)); } + return; + } - if (s_ip4_old && s_ip4_new) { - gint64 metric_old, metric_new; + if (s_ip_old && s_ip_new) { + gint64 metric_old, metric_new; - /* For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is - * set at activation/renewal time using the value from static - * configuration. To support runtime change we need to update the - * dynamic configuration in place and tell the DHCP client the new - * value to use for future renewals. - */ - metric_old = nm_setting_ip_config_get_route_metric(s_ip4_old); - metric_new = nm_setting_ip_config_get_route_metric(s_ip4_new); + /* For dynamic IP methods (DHCP, IPv4LL, WWAN) the route metric is + * set at activation/renewal time using the value from static + * configuration. To support runtime change we need to update the + * dynamic configuration in place and tell the DHCP client the new + * value to use for future renewals. + */ + metric_old = nm_setting_ip_config_get_route_metric(s_ip_old); + metric_new = nm_setting_ip_config_get_route_metric(s_ip_new); - if (metric_old != metric_new) { + if (metric_old != metric_new) { + if (IS_IPv4) { if (priv->dev_ip_config_4.orig) { nm_ip4_config_update_routes_metric((NMIP4Config *) priv->dev_ip_config_4.orig, nm_device_get_route_metric(self, AF_INET)); @@ -12323,60 +12354,7 @@ nm_device_reactivate_ip4_config(NMDevice * self, nm_dhcp_client_set_route_metric(priv->dhcp_data_4.client, nm_device_get_route_metric(self, AF_INET)); } - } - } - - if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, AF_INET, TRUE)) - _LOGW(LOGD_IP4, "Failed to reapply IPv4 configuration"); - } -} - -void -nm_device_reactivate_ip6_config(NMDevice * self, - NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new) -{ - NMDevicePrivate *priv; - const char * method_old, *method_new; - - g_return_if_fail(NM_IS_DEVICE(self)); - priv = NM_DEVICE_GET_PRIVATE(self); - - if (priv->ip_state_6 != NM_DEVICE_IP_STATE_NONE) { - g_clear_object(&priv->con_ip_config_6); - g_clear_object(&priv->ext_ip_config_6); - g_clear_object(&priv->ac_ip6_config.current); - g_clear_object(&priv->dhcp6.ip6_config.current); - g_clear_object(&priv->dev2_ip_config_6.current); - if (priv->ipv6ll_handle && !IN6_IS_ADDR_UNSPECIFIED(&priv->ipv6ll_addr)) - priv->ipv6ll_has = TRUE; - priv->con_ip_config_6 = nm_device_ip6_config_new(self); - nm_ip6_config_merge_setting(priv->con_ip_config_6, - s_ip6_new, - nm_device_get_route_table(self, AF_INET6), - nm_device_get_route_metric(self, AF_INET6)); - - method_old = s_ip6_old ? nm_setting_ip_config_get_method(s_ip6_old) - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - method_new = s_ip6_new ? nm_setting_ip_config_get_method(s_ip6_new) - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - - if (!nm_streq0(method_old, method_new)) { - _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE); - _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - if (!nm_device_activate_stage3_ip6_start(self)) - _LOGW(LOGD_IP6, "Failed to apply IPv6 configuration"); - return; - } - - if (s_ip6_old && s_ip6_new) { - gint64 metric_old, metric_new; - - /* See comment in nm_device_reactivate_ip4_config() */ - metric_old = nm_setting_ip_config_get_route_metric(s_ip6_old); - metric_new = nm_setting_ip_config_get_route_metric(s_ip6_new); - - if (metric_old != metric_new) { + } else { if (priv->ac_ip6_config.orig) { nm_ip6_config_update_routes_metric((NMIP6Config *) priv->ac_ip6_config.orig, nm_device_get_route_metric(self, AF_INET6)); @@ -12395,9 +12373,12 @@ nm_device_reactivate_ip6_config(NMDevice * self, } } } + } - if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, AF_INET6, TRUE)) - _LOGW(LOGD_IP4, "Failed to reapply IPv6 configuration"); + if (nm_device_get_ip_ifindex(self) > 0 && !ip_config_merge_and_apply(self, addr_family, TRUE)) { + _LOGW(LOGD_IP_from_af(addr_family), + "Failed to reapply IPv%c configuration", + nm_utils_addr_family_to_char(addr_family)); } } @@ -12652,8 +12633,8 @@ check_and_reapply_connection(NMDevice * self, /* Allow reapply of MTU */ priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; - nm_device_reactivate_ip4_config(self, s_ip4_old, s_ip4_new); - nm_device_reactivate_ip6_config(self, s_ip6_old, s_ip6_new); + nm_device_reactivate_ip_config(self, AF_INET, s_ip4_old, s_ip4_new); + nm_device_reactivate_ip_config(self, AF_INET6, s_ip6_old, s_ip6_new); _routing_rules_sync(self, NM_TERNARY_TRUE); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 13782417e3..008b69324b 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -789,12 +789,10 @@ void nm_device_reapply_settings_immediately(NMDevice *self); void nm_device_update_firewall_zone(NMDevice *self); void nm_device_update_metered(NMDevice *self); -void nm_device_reactivate_ip4_config(NMDevice * device, - NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new); -void nm_device_reactivate_ip6_config(NMDevice * device, - NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new); +void nm_device_reactivate_ip_config(NMDevice * device, + int addr_family, + NMSettingIPConfig *s_ip_old, + NMSettingIPConfig *s_ip_new); gboolean nm_device_update_hw_address(NMDevice *self); void nm_device_update_initial_hw_address(NMDevice *self); diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index feab265dbb..3b0763d11e 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -167,140 +167,131 @@ dump_proxy_to_props(NMProxyConfig *proxy, GVariantBuilder *builder) } static void -dump_ip4_to_props(NMIP4Config *ip4, GVariantBuilder *builder) +dump_ip_to_props(NMIPConfig *ip, GVariantBuilder *builder) { - GVariantBuilder int_builder; - NMDedupMultiIter ipconf_iter; - gboolean first; - guint n, i; - const NMPlatformIP4Address *addr; - const NMPlatformIP4Route * route; - guint32 array[4]; + const int addr_family = nm_ip_config_get_addr_family(ip); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + const NMPObject *obj; + GVariantBuilder int_builder; + NMDedupMultiIter ipconf_iter; + GVariant * var1; + GVariant * var2; + guint n; + guint i; + const NMPObject *default_route; - /* Addresses */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau")); - first = TRUE; - nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr) { - const NMPObject *default_route; + if (IS_IPv4) + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau")); + else + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuay)")); + default_route = nm_ip_config_best_default_route_get(ip); + if (IS_IPv4) + nm_ip_config_iter_ip4_address_init(&ipconf_iter, NM_IP4_CONFIG(ip)); + else + nm_ip_config_iter_ip6_address_init(&ipconf_iter, NM_IP6_CONFIG(ip)); + while (nm_platform_dedup_multi_iter_next_obj(&ipconf_iter, + &obj, + NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4))) { + const NMPlatformIPXAddress *addr = NMP_OBJECT_CAST_IPX_ADDRESS(obj); - array[0] = addr->address; - array[1] = addr->plen; - array[2] = (first && (default_route = nm_ip4_config_best_default_route_get(ip4))) - ? NMP_OBJECT_CAST_IP4_ROUTE(default_route)->gateway - : (guint32) 0; - g_variant_builder_add( - &int_builder, - "@au", - g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 3, sizeof(guint32))); - first = FALSE; + if (IS_IPv4) { + guint32 array[3]; + in_addr_t gw; + + gw = 0u; + if (default_route) { + gw = NMP_OBJECT_CAST_IP4_ROUTE(default_route)->gateway; + default_route = NULL; + } + array[0] = addr->a4.address; + array[1] = addr->a4.plen; + array[2] = gw; + g_variant_builder_add( + &int_builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 3, sizeof(guint32))); + } else { + const struct in6_addr *gw = &in6addr_any; + + if (default_route) { + gw = &NMP_OBJECT_CAST_IP6_ROUTE(default_route)->gateway; + default_route = NULL; + } + var1 = nm_g_variant_new_ay_in6addr(&addr->a6.address); + var2 = nm_g_variant_new_ay_in6addr(gw); + g_variant_builder_add(&int_builder, "(@ayu@ay)", var1, addr->a6.plen, var2); + } } g_variant_builder_add(builder, "{sv}", "addresses", g_variant_builder_end(&int_builder)); - /* DNS servers */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); - n = nm_ip4_config_get_num_nameservers(ip4); - for (i = 0; i < n; i++) - g_variant_builder_add(&int_builder, "u", nm_ip4_config_get_nameserver(ip4, i)); - g_variant_builder_add(builder, "{sv}", "nameservers", g_variant_builder_end(&int_builder)); - - /* Search domains */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("as")); - n = nm_ip4_config_get_num_domains(ip4); - for (i = 0; i < n; i++) - g_variant_builder_add(&int_builder, "s", nm_ip4_config_get_domain(ip4, i)); - g_variant_builder_add(builder, "{sv}", "domains", g_variant_builder_end(&int_builder)); - - /* WINS servers */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); - n = nm_ip4_config_get_num_wins(ip4); - for (i = 0; i < n; i++) - g_variant_builder_add(&int_builder, "u", nm_ip4_config_get_wins(ip4, i)); - g_variant_builder_add(builder, "{sv}", "wins-servers", g_variant_builder_end(&int_builder)); - - /* Static routes */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau")); - nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) { - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) - continue; - array[0] = route->network; - array[1] = route->plen; - array[2] = route->gateway; - array[3] = route->metric; - g_variant_builder_add( - &int_builder, - "@au", - g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 4, sizeof(guint32))); - } - g_variant_builder_add(builder, "{sv}", "routes", g_variant_builder_end(&int_builder)); -} - -static void -dump_ip6_to_props(NMIP6Config *ip6, GVariantBuilder *builder) -{ - GVariantBuilder int_builder; - NMDedupMultiIter ipconf_iter; - guint n, i; - gboolean first; - const NMPlatformIP6Address *addr; - const NMPlatformIP6Route * route; - GVariant * ip, *gw; - - /* Addresses */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuay)")); - - first = TRUE; - nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr) { - const NMPObject *default_route; - - ip = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, - &addr->address, - sizeof(struct in6_addr), - 1); - gw = g_variant_new_fixed_array( - G_VARIANT_TYPE_BYTE, - (first && (default_route = nm_ip6_config_best_default_route_get(ip6))) - ? &NMP_OBJECT_CAST_IP6_ROUTE(default_route)->gateway - : &in6addr_any, - sizeof(struct in6_addr), - 1); - g_variant_builder_add(&int_builder, "(@ayu@ay)", ip, addr->plen, gw); - first = FALSE; - } - g_variant_builder_add(builder, "{sv}", "addresses", g_variant_builder_end(&int_builder)); - - /* DNS servers */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aay")); - n = nm_ip6_config_get_num_nameservers(ip6); + if (IS_IPv4) + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); + else + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aay")); + n = nm_ip_config_get_num_nameservers(ip); for (i = 0; i < n; i++) { - ip = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, - nm_ip6_config_get_nameserver(ip6, i), - sizeof(struct in6_addr), - 1); - g_variant_builder_add(&int_builder, "@ay", ip); + if (IS_IPv4) { + g_variant_builder_add(&int_builder, + "u", + nm_ip4_config_get_nameserver(NM_IP4_CONFIG(ip), i)); + } else { + var1 = nm_g_variant_new_ay_in6addr(nm_ip6_config_get_nameserver(NM_IP6_CONFIG(ip), i)); + g_variant_builder_add(&int_builder, "@ay", var1); + } } g_variant_builder_add(builder, "{sv}", "nameservers", g_variant_builder_end(&int_builder)); - /* Search domains */ g_variant_builder_init(&int_builder, G_VARIANT_TYPE("as")); - n = nm_ip6_config_get_num_domains(ip6); + n = nm_ip_config_get_num_domains(ip); for (i = 0; i < n; i++) - g_variant_builder_add(&int_builder, "s", nm_ip6_config_get_domain(ip6, i)); + g_variant_builder_add(&int_builder, "s", nm_ip_config_get_domain(ip, i)); g_variant_builder_add(builder, "{sv}", "domains", g_variant_builder_end(&int_builder)); - /* Static routes */ - g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuayu)")); - nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) { + if (IS_IPv4) { + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); + n = nm_ip4_config_get_num_wins(NM_IP4_CONFIG(ip)); + for (i = 0; i < n; i++) + g_variant_builder_add(&int_builder, "u", nm_ip4_config_get_wins(NM_IP4_CONFIG(ip), i)); + g_variant_builder_add(builder, "{sv}", "wins-servers", g_variant_builder_end(&int_builder)); + } + + if (IS_IPv4) + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("aau")); + else + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("a(ayuayu)")); + if (IS_IPv4) + nm_ip_config_iter_ip4_route_init(&ipconf_iter, NM_IP4_CONFIG(ip)); + else + nm_ip_config_iter_ip6_route_init(&ipconf_iter, NM_IP6_CONFIG(ip)); + while (nm_platform_dedup_multi_iter_next_obj(&ipconf_iter, + &obj, + NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))) { + const NMPlatformIPXRoute *route = NMP_OBJECT_CAST_IPX_ROUTE(obj); + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) continue; - ip = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, - &route->network, - sizeof(struct in6_addr), - 1); - gw = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, - &route->gateway, - sizeof(struct in6_addr), - 1); - g_variant_builder_add(&int_builder, "(@ayu@ayu)", ip, route->plen, gw, route->metric); + + if (IS_IPv4) { + guint32 array[4]; + + array[0] = route->r4.network; + array[1] = route->r4.plen; + array[2] = route->r4.gateway; + array[3] = route->r4.metric; + g_variant_builder_add( + &int_builder, + "@au", + g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, array, 4, sizeof(guint32))); + } else { + var1 = nm_g_variant_new_ay_in6addr(&route->r6.network); + var2 = nm_g_variant_new_ay_in6addr(&route->r6.gateway); + g_variant_builder_add(&int_builder, + "(@ayu@ayu)", + var1, + route->r6.plen, + var2, + route->r6.metric); + } } g_variant_builder_add(builder, "{sv}", "routes", g_variant_builder_end(&int_builder)); } @@ -350,11 +341,11 @@ fill_device_props(NMDevice * device, ip4_config = nm_device_get_ip4_config(device); if (ip4_config) - dump_ip4_to_props(ip4_config, ip4_builder); + dump_ip_to_props(NM_IP_CONFIG(ip4_config), ip4_builder); ip6_config = nm_device_get_ip6_config(device); if (ip6_config) - dump_ip6_to_props(ip6_config, ip6_builder); + dump_ip_to_props(NM_IP_CONFIG(ip6_config), ip6_builder); dhcp_config = nm_device_get_dhcp_config(device, AF_INET); if (dhcp_config) @@ -376,9 +367,9 @@ fill_vpn_props(NMProxyConfig * proxy_config, if (proxy_config) dump_proxy_to_props(proxy_config, proxy_builder); if (ip4_config) - dump_ip4_to_props(ip4_config, ip4_builder); + dump_ip_to_props(NM_IP_CONFIG(ip4_config), ip4_builder); if (ip6_config) - dump_ip6_to_props(ip6_config, ip6_builder); + dump_ip_to_props(NM_IP_CONFIG(ip6_config), ip6_builder); } static const char * diff --git a/src/nm-l3-config-data.c b/src/nm-l3-config-data.c index 3f6db67c61..c02cb78cb3 100644 --- a/src/nm-l3-config-data.c +++ b/src/nm-l3-config-data.c @@ -2666,8 +2666,7 @@ nm_l3_config_data_merge(NML3ConfigData * self, if (self->llmnr == NM_SETTING_CONNECTION_LLMNR_DEFAULT) self->llmnr = src->llmnr; - if (self->metered == NM_TERNARY_DEFAULT) - self->metered = src->metered; + self->metered = NM_MAX((NMTernary) self->metered, (NMTernary) src->metered); if (self->ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) self->ip6_privacy = src->ip6_privacy;