static int find_route_slot(const unsigned char *prefix, unsigned char plen, const unsigned char *src_prefix, unsigned char src_plen, int *new_return) { int p, m, g, c; if(route_slots < 1) { if(new_return) *new_return = 0; return -1; } p = 0; g = route_slots - 1; do { m = (p + g) / 2; c = route_compare(prefix, plen, src_prefix, src_plen, routes[m]); if(c == 0) return m; else if(c < 0) g = m - 1; else p = m + 1; } while(p <= g); if(new_return) *new_return = p; return -1; }
static gboolean check_ip_routes (NMConnection *orig, NMConnection *candidate, GHashTable *settings, gint64 default_metric, gboolean v4) { gs_free NMIPRoute **routes1 = NULL, **routes2 = NULL; NMSettingIPConfig *s_ip1, *s_ip2; const char *s_name; GHashTable *props; guint i, num; s_name = v4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME : NM_SETTING_IP6_CONFIG_SETTING_NAME; props = check_property_in_hash (settings, s_name, NM_SETTING_IP_CONFIG_ROUTES); if (!props) return TRUE; s_ip1 = (NMSettingIPConfig *) nm_connection_get_setting_by_name (orig, s_name); s_ip2 = (NMSettingIPConfig *) nm_connection_get_setting_by_name (candidate, s_name); 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; routes1 = g_new (NMIPRoute *, num); routes2 = g_new (NMIPRoute *, num); for (i = 0; i < num; i++) { routes1[i] = nm_setting_ip_config_get_route (s_ip1, i); routes2[i] = nm_setting_ip_config_get_route (s_ip2, i); } qsort (routes1, num, sizeof (NMIPRoute *), route_ptr_compare); qsort (routes2, num, sizeof (NMIPRoute *), route_ptr_compare); for (i = 0; i < num; i++) { if (route_compare (routes1[i], routes2[i], default_metric)) return FALSE; } remove_from_hash (settings, props, s_name, NM_SETTING_IP_CONFIG_ROUTES); return TRUE; }
static int route_ptr_compare (const void *a, const void *b) { return route_compare (*(NMIPRoute **) a, *(NMIPRoute **) b, -1); }