diff options
Diffstat (limited to 'src/NetworkManagerUtils.c')
| -rw-r--r-- | src/NetworkManagerUtils.c | 133 |
1 files changed, 99 insertions, 34 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index ecb1d8ae..596c5bb3 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -175,37 +175,78 @@ nm_utils_get_ip_config_method (NMConnection *connection, if (ip_setting_type == NM_TYPE_SETTING_IP4_CONFIG) { g_return_val_if_fail (s_con != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - if (nm_setting_connection_get_master (s_con)) + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (!s_ip4) return NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - else { - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) - return NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - method = nm_setting_ip_config_get_method (s_ip4); - g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - - return method; - } + method = nm_setting_ip_config_get_method (s_ip4); + g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + return method; } else if (ip_setting_type == NM_TYPE_SETTING_IP6_CONFIG) { g_return_val_if_fail (s_con != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - if (nm_setting_connection_get_master (s_con)) + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (!s_ip6) return NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - else { - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!s_ip6) - return NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - method = nm_setting_ip_config_get_method (s_ip6); - g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - - return method; - } + method = nm_setting_ip_config_get_method (s_ip6); + g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + + return method; } else g_assert_not_reached (); } +gboolean +nm_utils_connection_has_default_route (NMConnection *connection, + int addr_family, + gboolean *out_is_never_default) +{ + const char *method; + NMSettingIPConfig *s_ip; + gboolean is_never_default = FALSE; + gboolean has_default_route = FALSE; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE); + + if (!connection) + goto out; + + if (addr_family == AF_INET) + s_ip = nm_connection_get_setting_ip4_config (connection); + else + s_ip = nm_connection_get_setting_ip6_config (connection); + if (!s_ip) + goto out; + if (nm_setting_ip_config_get_never_default (s_ip)) { + is_never_default = TRUE; + goto out; + } + + if (addr_family == AF_INET) { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + if (NM_IN_STRSET (method, NULL, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + goto out; + } else { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (NM_IN_STRSET (method, NULL, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) + goto out; + } + + has_default_route = TRUE; +out: + NM_SET_OUT (out_is_never_default, is_never_default); + return has_default_route; +} + +/*****************************************************************************/ + void nm_utils_complete_generic (NMPlatform *platform, NMConnection *connection, @@ -250,7 +291,7 @@ nm_utils_complete_generic (NMPlatform *platform, } /* Normalize */ - parameters = g_hash_table_new (g_str_hash, g_str_equal); + parameters = g_hash_table_new (nm_str_hash, g_str_equal); g_hash_table_insert (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD, default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); nm_connection_normalize (connection, parameters, NULL, NULL); @@ -392,12 +433,14 @@ check_ip_routes (NMConnection *orig, gint64 default_metric, gboolean v4) { - gs_free NMIPRoute **routes1 = NULL, **routes2 = NULL; + gs_free NMIPRoute **routes1 = NULL; + NMIPRoute **routes2; NMSettingIPConfig *s_ip1, *s_ip2; gint64 m; const char *s_name; GHashTable *props; - guint i, num; + guint i, i1, i2, num1, num2; + const guint8 PLEN = v4 ? 32 : 128; s_name = v4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME : NM_SETTING_IP6_CONFIG_SETTING_NAME; @@ -414,27 +457,49 @@ check_ip_routes (NMConnection *orig, if (!s_ip1 || !s_ip2) return FALSE; - num = nm_setting_ip_config_get_num_routes (s_ip1); - if (num != nm_setting_ip_config_get_num_routes (s_ip2)) - return FALSE; + num1 = nm_setting_ip_config_get_num_routes (s_ip1); + num2 = nm_setting_ip_config_get_num_routes (s_ip2); - routes1 = g_new (NMIPRoute *, num); - routes2 = g_new (NMIPRoute *, num); + routes1 = g_new (NMIPRoute *, (gsize) num1 + num2); + routes2 = &routes1[num1]; - for (i = 0; i < num; i++) { + for (i = 0; i < num1; i++) routes1[i] = nm_setting_ip_config_get_route (s_ip1, i); + for (i = 0; i < num2; i++) routes2[i] = nm_setting_ip_config_get_route (s_ip2, i); - } m = nm_setting_ip_config_get_route_metric (s_ip2); if (m != -1) default_metric = m; - g_qsort_with_data (routes1, num, sizeof (NMIPRoute *), route_ptr_compare, &default_metric); - g_qsort_with_data (routes2, num, sizeof (NMIPRoute *), route_ptr_compare, &default_metric); + g_qsort_with_data (routes1, num1, sizeof (NMIPRoute *), route_ptr_compare, &default_metric); + g_qsort_with_data (routes2, num2, sizeof (NMIPRoute *), route_ptr_compare, &default_metric); + + for (i1 = 0, i2 = 0; i2 < num2; i1++) { + if (i1 >= num1) + return FALSE; + if (route_compare (routes1[i1], routes2[i2], default_metric) == 0) { + i2++; + continue; + } + + /* if @orig (@routes1) contains /32 routes that are missing in @candidate, + * we accept that. + * + * A /32 may have been added automatically, as a direct-route to the gateway. + * The generated connection (@orig) would contain that route, so we shall ignore + * it. + * + * Likeweise for /128 for IPv6. */ + if (nm_ip_route_get_prefix (routes1[i1]) == PLEN) + continue; + + return FALSE; + } - for (i = 0; i < num; i++) { - if (route_compare (routes1[i], routes2[i], default_metric)) + /* check that @orig has no left-over (except host routes that we ignore). */ + for (; i1 < num1; i1++) { + if (nm_ip_route_get_prefix (routes1[i1]) != PLEN) return FALSE; } |