From d06c46b80fb180dfc70398a66cd9d0c1129e5b4f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 27 Sep 2017 11:54:51 +0200 Subject: [PATCH 1/3] libnm: make index variable i unsigned for iterating array GArray's and GPtrArray's plen argument is unsigned. The index variable to iterate the list, should not have a smaller range (or different data type). Also, assert against negative idx argument. --- libnm-core/nm-core-internal.h | 2 +- libnm-core/nm-setting-ip-config.c | 54 +++++++++++++++---------------- libnm-core/nm-utils.c | 4 +-- libnm-core/tests/test-general.c | 18 +++++------ 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 4ad3dfe385..5d81d059d2 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -336,7 +336,7 @@ extern const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[]; gboolean _nm_utils_dns_option_validate (const char *option, char **out_name, long *out_value, gboolean ipv6, const NMUtilsDNSOptionDesc *option_descs); -int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option); +gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option); /*****************************************************************************/ diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 20c8ba4072..8678edfe03 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -1453,7 +1453,7 @@ nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, int idx) g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (idx < priv->dns->len, NULL); + g_return_val_if_fail (idx >= 0 && idx < priv->dns->len, NULL); return priv->dns->pdata[idx]; } @@ -1473,7 +1473,7 @@ nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, const char *dns) { NMSettingIPConfigPrivate *priv; char *dns_canonical; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (dns != NULL, FALSE); @@ -1509,7 +1509,7 @@ nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, int idx) g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (idx < priv->dns->len); + g_return_if_fail (idx >= 0 && idx < priv->dns->len); g_ptr_array_remove_index (priv->dns, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); @@ -1529,7 +1529,7 @@ nm_setting_ip_config_remove_dns_by_value (NMSettingIPConfig *setting, const char { NMSettingIPConfigPrivate *priv; char *dns_canonical; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (dns != NULL, FALSE); @@ -1597,7 +1597,7 @@ nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, int idx) g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (idx < priv->dns_search->len, NULL); + g_return_val_if_fail (idx >= 0 && idx < priv->dns_search->len, NULL); return priv->dns_search->pdata[idx]; } @@ -1617,7 +1617,7 @@ nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting, const char *dns_search) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (dns_search != NULL, FALSE); @@ -1649,7 +1649,7 @@ nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int idx) g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (idx < priv->dns_search->len); + g_return_if_fail (idx >= 0 && idx < priv->dns_search->len); g_ptr_array_remove_index (priv->dns_search, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); @@ -1671,7 +1671,7 @@ nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting, const char *dns_search) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (dns_search != NULL, FALSE); @@ -1856,7 +1856,7 @@ nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, int idx) priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); g_return_if_fail (priv->dns_options); - g_return_if_fail (idx < priv->dns_options->len); + g_return_if_fail (idx >= 0 && idx < priv->dns_options->len); g_ptr_array_remove_index (priv->dns_options, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS); @@ -1878,7 +1878,7 @@ nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting, const char *dns_option) { NMSettingIPConfigPrivate *priv; - int i; + gssize i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (dns_option != NULL, FALSE); @@ -1978,7 +1978,7 @@ nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int idx) g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (idx < priv->addresses->len, NULL); + g_return_val_if_fail (idx >= 0 && idx < priv->addresses->len, NULL); return priv->addresses->pdata[idx]; } @@ -1999,7 +1999,7 @@ nm_setting_ip_config_add_address (NMSettingIPConfig *setting, NMIPAddress *address) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (address != NULL, FALSE); @@ -2032,7 +2032,7 @@ nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, int idx) g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (idx < priv->addresses->len); + g_return_if_fail (idx >= 0 && idx < priv->addresses->len); g_ptr_array_remove_index (priv->addresses, idx); @@ -2053,7 +2053,7 @@ nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig *setting, NMIPAddress *address) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (address != NULL, FALSE); @@ -2130,7 +2130,7 @@ nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int idx) g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (idx < priv->routes->len, NULL); + g_return_val_if_fail (idx >= 0 && idx < priv->routes->len, NULL); return priv->routes->pdata[idx]; } @@ -2150,7 +2150,7 @@ nm_setting_ip_config_add_route (NMSettingIPConfig *setting, NMIPRoute *route) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (route != NULL, FALSE); @@ -2182,7 +2182,7 @@ nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int idx) g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - g_return_if_fail (idx < priv->routes->len); + g_return_if_fail (idx >= 0 && idx < priv->routes->len); g_ptr_array_remove_index (priv->routes, idx); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); @@ -2199,10 +2199,10 @@ nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int idx) **/ gboolean nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, - NMIPRoute *route) + NMIPRoute *route) { NMSettingIPConfigPrivate *priv; - int i; + guint i; g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); g_return_val_if_fail (route != NULL, FALSE); @@ -2444,7 +2444,7 @@ static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); - int i; + guint i; if (!priv->method) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, @@ -2469,7 +2469,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. DNS server address is invalid"), - i+1); + (int) (i + 1)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_DNS); return FALSE; } @@ -2485,7 +2485,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. IP address is invalid"), - i+1); + (int) (i + 1)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); return FALSE; } @@ -2497,7 +2497,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. IP address has 'label' property with invalid type"), - i+1); + (int) (i + 1)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); return FALSE; } @@ -2506,7 +2506,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. IP address has invalid label '%s'"), - i+1, g_variant_get_string (label, NULL)); + (int) (i + 1), g_variant_get_string (label, NULL)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); return FALSE; } @@ -2554,7 +2554,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. route is invalid"), - i+1); + (int) (i + 1)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES); return FALSE; } @@ -2563,7 +2563,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d. route cannot be a default route"), - i+1); + (int) (i + 1)); g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES); return FALSE; } @@ -2665,7 +2665,7 @@ set_property (GObject *object, guint prop_id, NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); const char *gateway; char **strv; - int i; + guint i; switch (prop_id) { case PROP_METHOD: diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 0ef64ff392..4a46681c47 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4191,11 +4191,11 @@ out: * Returns: the index of the option in the array or -1 if was not * found. */ -int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) +gssize _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) { gboolean ret; char *option_name, *tmp_name; - int i; + guint i; if (!_nm_utils_dns_option_validate (option, &option_name, NULL, FALSE, NULL)) return -1; diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 67d530e820..08d55555be 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3485,7 +3485,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip4, "11.22.0.0")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->dns->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->dns->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip4, 1)); g_test_assert_expected_messages (); @@ -3495,7 +3495,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->dns_search->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->dns_search->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 1)); g_test_assert_expected_messages (); @@ -3507,7 +3507,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip4, addr)); ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->addresses->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->addresses->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip4, 1)); g_test_assert_expected_messages (); @@ -3520,7 +3520,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip4, route)); ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->routes->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->routes->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip4, 1)); g_test_assert_expected_messages (); @@ -3530,7 +3530,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns_option (s_ip4, "debug")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns_option (s_ip4, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->dns_options->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->dns_options->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_option (s_ip4, 1)); g_test_assert_expected_messages (); @@ -3561,7 +3561,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->dns->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->dns->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip6, 1)); g_test_assert_expected_messages (); @@ -3571,7 +3571,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com")); ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->dns_search->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->dns_search->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 1)); g_test_assert_expected_messages (); @@ -3584,7 +3584,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip6, addr)); ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->addresses->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->addresses->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip6, 1)); g_test_assert_expected_messages (); @@ -3597,7 +3597,7 @@ test_setting_ip6_changed_signal (void) ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip6, route)); ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip6, 0)); - g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx < priv->routes->len)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, NMTST_G_RETURN_MSG (idx >= 0 && idx < priv->routes->len)); ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip6, 1)); g_test_assert_expected_messages (); From f05ebc426142090628b196438fb0a293fcd53c2e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 27 Sep 2017 12:05:39 +0200 Subject: [PATCH 2/3] libnm: don't skip routes in nm_setting_ip_config_add_route() that only differ by attributes For kernel and NetworkManager's core, route identity is a complicated topic (see NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID). For example, a route without explity table is treated identical to "table 254" or "table 0". It would be complicated to have nm_setting_ip_config_add_route() implement that logic, especially since libnm offers not public API to expose kernel's logic. However, previously nm_setting_ip_config_add_route() would only consider dest/prefix,next_hop,metric when comparing for equality. Hence, with nmcli connection modify "$CON" +ipv4.routes '192.168.5.0/24' nmcli connection modify "$CON" +ipv4.routes '192.168.5.0/24 table=42' the second route was not actually added, although it is a very different route. Fix that, and consider attributes too. Note that this allows the user to add two routes that look different to libnm, but are actually idential: nmcli connection modify "$CON" +ipv4.routes '192.168.5.0/24' nmcli connection modify "$CON" +ipv4.routes '192.168.5.0/24 table=254' In the above example, the route instances look different, but sementically they are both the same route in the main table (254). This also allows the user to add routes that are semantically different, but are treated as the same route by kernel: nmcli connection modify "$CON" +ipv6.routes 'a:b:c::/120' nmcli connection modify "$CON" +ipv6.routes 'a:b:c::/120 mtu=600' I think libnm should allow to add routes as long as they look different to libnm. Regardless how kernel and NetworkManager-core thinks about route identity. This changes API of nm_setting_ip_config_add_route(). However, I think the previous behavior was just broken. Same for nm_setting_ip_config_remove_route_by_value(). --- libnm-core/nm-setting-ip-config.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 8678edfe03..dd09baa62c 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -2140,8 +2140,14 @@ nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int idx) * @setting: the #NMSettingIPConfig * @route: the route to add * - * Adds a new route and associated information to the setting. The + * Appends a new route and associated information to the setting. The * given route is duplicated internally and is not changed by this function. + * If an identical route (considering attributes as well) already exists, the + * route is not added and the function returns %FALSE. + * + * Note that before 1.10, this function would not consider route attributes + * and not add a route that has an existing route with same dest/prefix,next_hop,metric + * parameters. * * Returns: %TRUE if the route was added; %FALSE if the route was already known. **/ @@ -2158,7 +2164,7 @@ nm_setting_ip_config_add_route (NMSettingIPConfig *setting, priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); for (i = 0; i < priv->routes->len; i++) { - if (nm_ip_route_equal (priv->routes->pdata[i], route)) + if (_nm_ip_route_equal (priv->routes->pdata[i], route, TRUE)) return FALSE; } @@ -2193,7 +2199,9 @@ nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int idx) * @setting: the #NMSettingIPConfig * @route: the route to remove * - * Removes the route @route. + * Removes the first matching route that matches @route. + * Note that before 1.10, this function would only compare dest/prefix,next_hop,metric + * and ignore route attributes. Now, @route must match exactly. * * Returns: %TRUE if the route was found and removed; %FALSE if it was not. **/ @@ -2209,7 +2217,7 @@ nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); for (i = 0; i < priv->routes->len; i++) { - if (nm_ip_route_equal (priv->routes->pdata[i], route)) { + if (_nm_ip_route_equal (priv->routes->pdata[i], route, TRUE)) { g_ptr_array_remove_index (priv->routes, i); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); return TRUE; From f83e6b974324528a1d792b1d9c09fd8fb18446d3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 27 Sep 2017 12:40:43 +0200 Subject: [PATCH 3/3] libnm: add nm_ip_route_equal_full() function Expose previously internal function nm_ip_route_equal_full(). It's just useful API. However, add a @cmp_flags argument, so that in the future we could extend it. --- libnm-core/nm-setting-ip-config.c | 26 +++++++++++++++++--------- libnm-core/nm-setting-ip-config.h | 11 +++++++++++ libnm/libnm.ver | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index dd09baa62c..69dd91b40b 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -753,18 +753,22 @@ nm_ip_route_unref (NMIPRoute *route) } /** - * _nm_ip_route_equal: + * nm_ip_route_equal_full: * @route: the #NMIPRoute * @other: the #NMIPRoute to compare @route to. - * @consider_attributes: whether to compare attributes too + * @cmp_flags: tune how to compare attributes. Currently only + * NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE (0) and NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS (1) + * is supported. * * Determines if two #NMIPRoute objects contain the same destination, prefix, * next hop, and metric. * * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + * + * Since: 1.10 **/ -static gboolean -_nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other, gboolean consider_attributes) +gboolean +nm_ip_route_equal_full (NMIPRoute *route, NMIPRoute *other, guint cmp_flags) { g_return_val_if_fail (route != NULL, FALSE); g_return_val_if_fail (route->refcount > 0, FALSE); @@ -772,12 +776,16 @@ _nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other, gboolean consider_attrib g_return_val_if_fail (other != NULL, FALSE); g_return_val_if_fail (other->refcount > 0, FALSE); + g_return_val_if_fail (NM_IN_SET (cmp_flags, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS), FALSE); + if ( route->prefix != other->prefix || route->metric != other->metric || strcmp (route->dest, other->dest) != 0 || g_strcmp0 (route->next_hop, other->next_hop) != 0) return FALSE; - if (consider_attributes) { + if (cmp_flags == NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS) { GHashTableIter iter; const char *key; GVariant *value, *value2; @@ -813,7 +821,7 @@ _nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other, gboolean consider_attrib gboolean nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other) { - return _nm_ip_route_equal (route, other, FALSE); + return nm_ip_route_equal_full (route, other, NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE); } /** @@ -2164,7 +2172,7 @@ nm_setting_ip_config_add_route (NMSettingIPConfig *setting, priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); for (i = 0; i < priv->routes->len; i++) { - if (_nm_ip_route_equal (priv->routes->pdata[i], route, TRUE)) + if (nm_ip_route_equal_full (priv->routes->pdata[i], route, NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) return FALSE; } @@ -2217,7 +2225,7 @@ nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); for (i = 0; i < priv->routes->len; i++) { - if (_nm_ip_route_equal (priv->routes->pdata[i], route, TRUE)) { + if (nm_ip_route_equal_full (priv->routes->pdata[i], route, NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) { g_ptr_array_remove_index (priv->routes, i); g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); return TRUE; @@ -2620,7 +2628,7 @@ compare_property (NMSetting *setting, if (a_priv->routes->len != b_priv->routes->len) return FALSE; for (i = 0; i < a_priv->routes->len; i++) { - if (!_nm_ip_route_equal (a_priv->routes->pdata[i], b_priv->routes->pdata[i], TRUE)) + if (!nm_ip_route_equal_full (a_priv->routes->pdata[i], b_priv->routes->pdata[i], NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) return FALSE; } return TRUE; diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h index a3e4007c9e..16aa415684 100644 --- a/libnm-core/nm-setting-ip-config.h +++ b/libnm-core/nm-setting-ip-config.h @@ -92,6 +92,17 @@ void nm_ip_route_ref (NMIPRoute *route); void nm_ip_route_unref (NMIPRoute *route); gboolean nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other); + +enum { + NM_IP_ROUTE_EQUAL_CMP_FLAGS_NONE = 0, + NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS = (1LL << 0), +}; + +NM_AVAILABLE_IN_1_10 +gboolean nm_ip_route_equal_full (NMIPRoute *route, + NMIPRoute *other, + guint cmp_flags); + NMIPRoute *nm_ip_route_dup (NMIPRoute *route); int nm_ip_route_get_family (NMIPRoute *route); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index a2b8be52ef..5f3867c4f7 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1185,6 +1185,7 @@ global: nm_client_connectivity_check_set_enabled; nm_device_dummy_get_hw_address; nm_device_ppp_get_type; + nm_ip_route_equal_full; nm_ip_route_table_sync_mode_get_type; nm_setting_bridge_get_group_forward_mask; nm_setting_ip_config_get_route_table_sync;