summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-06-12 18:40:14 +0200
committerThomas Haller <thaller@redhat.com>2017-07-05 14:22:10 +0200
commit935411e5c03dcb62d5b2a85e67bf3220c75d0f5e (patch)
treea2736d05ab3424e576e250c65b44a6a16e4a861b
parent89385bd9683c521fbc85b5e452459c3d46d4528d (diff)
downloadNetworkManager-935411e5c03dcb62d5b2a85e67bf3220c75d0f5e.tar.gz
core: refactor NMIP4Config to use dedup-index for IPv4 routes
Eventually, every NMPlatformIP4Route, NMPlatformIP6Route, NMPlatformIP4Address and NMPlatformIP6Address should be shared an deduplicated via the global NMDedupMultiIndex instance. As first proof of concept, refactor NMIP4Config to track IPv4 routes via the shared multi_idx. There is later potential for improvement, when we pass (deduplicated) NMPObject instances around instead of plain NMPlatformIP4Route, which needs still a lot of comparing and cloning.
-rw-r--r--src/dhcp/tests/test-dhcp-utils.c6
-rw-r--r--src/dns/nm-dns-dnsmasq.c9
-rw-r--r--src/nm-dispatcher.c5
-rw-r--r--src/nm-ip4-config.c510
-rw-r--r--src/nm-ip4-config.h31
-rw-r--r--src/nm-pacrunner-manager.c8
-rw-r--r--src/tests/test-ip4-config.c12
-rw-r--r--src/vpn/nm-vpn-connection.c17
8 files changed, 410 insertions, 188 deletions
diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c
index 0d4e7f78e1..f3fa963e52 100644
--- a/src/dhcp/tests/test-dhcp-utils.c
+++ b/src/dhcp/tests/test-dhcp-utils.c
@@ -135,7 +135,7 @@ test_generic_options (void)
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
/* Route #1 */
- route = nm_ip4_config_get_route (ip4_config, 0);
+ route = _nmtst_nm_ip4_config_get_route (ip4_config, 0);
g_assert (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0);
@@ -144,7 +144,7 @@ test_generic_options (void)
g_assert_cmpint (route->metric, ==, 0);
/* Route #2 */
- route = nm_ip4_config_get_route (ip4_config, 1);
+ route = _nmtst_nm_ip4_config_get_route (ip4_config, 1);
g_assert (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0);
@@ -221,7 +221,7 @@ ip4_test_route (NMIP4Config *ip4_config,
g_assert (expected_prefix <= 32);
- route = nm_ip4_config_get_route (ip4_config, route_num);
+ route = _nmtst_nm_ip4_config_get_route (ip4_config, route_num);
g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0);
g_assert (route->network == tmp);
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c
index a6204ae4a0..730134b5e1 100644
--- a/src/dns/nm-dns-dnsmasq.c
+++ b/src/dns/nm-dns-dnsmasq.c
@@ -80,7 +80,9 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
{
char **strv;
GPtrArray *domains = NULL;
- int i;
+ guint i;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
g_return_val_if_fail (ip4 != NULL, NULL);
@@ -92,11 +94,8 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
}
- for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (ip4, i);
-
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route)
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
- }
/* Terminating NULL so we can use g_strfreev() to free it */
g_ptr_array_add (domains, NULL);
diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c
index 0d482e0cad..6bea925488 100644
--- a/src/nm-dispatcher.c
+++ b/src/nm-dispatcher.c
@@ -113,6 +113,7 @@ static void
dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
{
GVariantBuilder int_builder;
+ NMDedupMultiIter ipconf_iter;
guint n, i;
const NMPlatformIP4Address *addr;
const NMPlatformIP4Route *route;
@@ -163,9 +164,7 @@ dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
/* Static routes */
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
- n = nm_ip4_config_get_num_routes (ip4);
- for (i = 0; i < n; i++) {
- route = nm_ip4_config_get_route (ip4, i);
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
array[0] = route->network;
array[1] = route->plen;
array[2] = route->gateway;
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 9ec7eebb95..1f0d86d30e 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -29,6 +29,7 @@
#include "nm-utils/nm-dedup-multi.h"
#include "nm-utils.h"
+#include "platform/nmp-object.h"
#include "platform/nm-platform.h"
#include "platform/nm-platform-utils.h"
#include "NetworkManagerUtils.h"
@@ -45,6 +46,78 @@ G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF);
/*****************************************************************************/
+static gboolean
+_idx_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a,
+ const NMPlatformIP4Route *r_b)
+{
+ return r_a->network == r_b->network
+ && r_a->plen == r_b->plen;
+}
+
+static guint
+_idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
+ const NMDedupMultiObj *obj)
+{
+ const NMPObject *o = (NMPObject *) obj;
+ guint h;
+
+ switch (NMP_OBJECT_GET_TYPE (o)) {
+ case NMP_OBJECT_TYPE_IP4_ADDRESS:
+ case NMP_OBJECT_TYPE_IP6_ADDRESS:
+ g_return_val_if_reached (0);
+ case NMP_OBJECT_TYPE_IP4_ROUTE:
+ h = 40303327;
+ h = NM_HASH_COMBINE (h, o->ip4_route.network);
+ h = NM_HASH_COMBINE (h, o->ip4_route.plen);
+ break;
+ case NMP_OBJECT_TYPE_IP6_ROUTE:
+ g_return_val_if_reached (0);
+ default:
+ g_return_val_if_reached (0);
+ };
+
+ return h;
+}
+
+static gboolean
+_idx_obj_id_equal (const NMDedupMultiIdxType *idx_type,
+ const NMDedupMultiObj *obj_a,
+ const NMDedupMultiObj *obj_b)
+{
+ const NMPObject *o_a = (NMPObject *) obj_a;
+ const NMPObject *o_b = (NMPObject *) obj_b;
+
+ nm_assert (NMP_OBJECT_GET_TYPE (o_a) == NMP_OBJECT_GET_TYPE (o_b));
+
+ switch (NMP_OBJECT_GET_TYPE (o_a)) {
+ case NMP_OBJECT_TYPE_IP4_ADDRESS:
+ case NMP_OBJECT_TYPE_IP6_ADDRESS:
+ g_return_val_if_reached (FALSE);
+ case NMP_OBJECT_TYPE_IP4_ROUTE:
+ return _idx_obj_id_equal_ip4_route (&o_a->ip4_route, &o_b->ip4_route);
+ case NMP_OBJECT_TYPE_IP6_ROUTE:
+ g_return_val_if_reached (FALSE);
+ default:
+ g_return_val_if_reached (FALSE);
+ };
+}
+
+static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = {
+ .idx_obj_id_hash = _idx_obj_id_hash,
+ .idx_obj_id_equal = _idx_obj_id_equal,
+};
+
+void
+nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type,
+ NMPObjectType obj_type)
+{
+ nm_dedup_multi_idx_type_init ((NMDedupMultiIdxType *) idx_type,
+ &_dedup_multi_idx_type_class);
+ idx_type->obj_type = obj_type;
+}
+
+/*****************************************************************************/
+
NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config,
PROP_MULTI_IDX,
PROP_IFINDEX,
@@ -73,7 +146,6 @@ typedef struct {
gint dns_priority;
gint64 route_metric;
GArray *addresses;
- GArray *routes;
GArray *nameservers;
GPtrArray *domains;
GPtrArray *searches;
@@ -84,6 +156,7 @@ typedef struct {
GVariant *address_data_variant;
GVariant *addresses_variant;
NMDedupMultiIndex *multi_idx;
+ NMDedupMultiIdxType idx_ip4_routes;
} NMIP4ConfigPrivate;
struct _NMIP4Config {
@@ -101,6 +174,10 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT)
/*****************************************************************************/
+static void _add_route (NMIP4Config *config, const NMPObject *o_new, const NMPlatformIP4Route *new);
+
+/*****************************************************************************/
+
int
nm_ip4_config_get_ifindex (const NMIP4Config *config)
{
@@ -124,6 +201,49 @@ _ipv4_is_zeronet (in_addr_t network)
/*****************************************************************************/
+static const NMDedupMultiHeadEntry *
+_idx_ip4_routes (const NMIP4Config *self)
+{
+ const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+
+ return nm_dedup_multi_index_lookup_head (priv->multi_idx,
+ &priv->idx_ip4_routes,
+ NULL);
+}
+
+static const NMPlatformIP4Route *
+_entry_iter_get_ip4_route (const CList *iter)
+{
+ const NMDedupMultiEntry *e = c_list_entry (iter, NMDedupMultiEntry, lst_entries);
+ const NMPObject *o = (NMPObject *) e->box->obj;
+
+ nm_assert (o);
+ nm_assert (NMP_OBJECT_GET_TYPE (o) == NMP_OBJECT_TYPE_IP4_ROUTE);
+ return &o->ip4_route;
+}
+
+void
+nm_ip4_config_iter_ip4_route_init (NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
+{
+ g_return_if_fail (NM_IS_IP4_CONFIG (self));
+ nm_dedup_multi_iter_init (ipconf_iter, _idx_ip4_routes (self));
+}
+
+gboolean
+nm_ip4_config_iter_ip4_route_next (NMDedupMultiIter *ipconf_iter, const NMPlatformIP4Route **out_route)
+{
+ gboolean has_next;
+
+ has_next = nm_dedup_multi_iter_next (ipconf_iter);
+ if (has_next) {
+ nm_assert (NMP_OBJECT_GET_TYPE (ipconf_iter->current->box->obj) == NMP_OBJECT_TYPE_IP4_ROUTE);
+ NM_SET_OUT (out_route, &(((const NMPObject *) ipconf_iter->current->box->obj)->ip4_route));
+ }
+ return has_next;
+}
+
+/*****************************************************************************/
+
/**
* nm_ip4_config_capture_resolv_conf():
* @nameservers: array of guint32
@@ -196,13 +316,6 @@ addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Addre
&& ((a->peer_address ^ b->peer_address) & nm_utils_ip4_prefix_to_netmask (a->plen)) == 0;
}
-static gboolean
-routes_are_duplicate (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gboolean consider_gateway_and_metric)
-{
- return a->network == b->network && a->plen == b->plen &&
- (!consider_gateway_and_metric || (a->gateway == b->gateway && a->metric == b->metric));
-}
-
/*****************************************************************************/
static gint
@@ -277,6 +390,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
guint32 lowest_metric = G_MAXUINT32;
guint32 old_gateway = 0;
gboolean old_has_gateway = FALSE;
+ gs_unref_array GArray *routes = NULL;
/* Slaves have no IP configuration */
if (nm_platform_link_get_master (platform, ifindex) > 0)
@@ -286,18 +400,17 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
g_array_unref (priv->addresses);
- g_array_unref (priv->routes);
priv->addresses = nm_platform_ip4_address_get_all (platform, ifindex);
g_array_sort (priv->addresses, sort_captured_addresses);
- priv->routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
+ routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
/* Extract gateway from default route */
old_gateway = priv->gateway;
old_has_gateway = priv->has_gateway;
- for (i = 0; i < priv->routes->len; ) {
- const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i);
+ for (i = 0; i < routes->len; ) {
+ const NMPlatformIP4Route *route = &g_array_index (routes, NMPlatformIP4Route, i);
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
if (route->metric < lowest_metric) {
@@ -306,7 +419,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
}
priv->has_gateway = TRUE;
/* Remove the default route from the list */
- g_array_remove_index_fast (priv->routes, i);
+ g_array_remove_index_fast (routes, i);
continue;
}
i++;
@@ -320,18 +433,21 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
* automatically added by NetworkManager when needed.
*/
if (priv->has_gateway) {
- for (i = 0; i < priv->routes->len; i++) {
- const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i);
+ for (i = 0; i < routes->len; i++) {
+ const NMPlatformIP4Route *route = &g_array_index (routes, NMPlatformIP4Route, i);
if ( (route->plen == 32)
&& (route->network == priv->gateway)
&& (route->gateway == 0)) {
- g_array_remove_index (priv->routes, i);
+ g_array_remove_index (routes, i);
i--;
}
}
}
+ for (i = 0; i < routes->len; i++)
+ _add_route (config, NULL, &g_array_index (routes, NMPlatformIP4Route, i));
+
/* If the interface has the default route, and has IPv4 addresses, capture
* nameservers from /etc/resolv.conf.
*/
@@ -367,11 +483,15 @@ nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteMa
/* Routes */
{
+ const NMDedupMultiHeadEntry *head_entry;
guint i;
- guint count = nm_ip4_config_get_num_routes (config);
- GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count);
- gboolean success;
+ gs_unref_array GArray *routes = NULL;
gs_unref_array GArray *device_route_purge_list = NULL;
+ const CList *iter;
+
+ head_entry = _idx_ip4_routes (config);
+
+ routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), head_entry ? head_entry->len : 0);
if ( default_route_metric >= 0
&& added_addresses) {
@@ -414,20 +534,15 @@ nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteMa
}
}
- for (i = 0; i < count; i++) {
- const NMPlatformIP4Route *route;
-
- route = nm_ip4_config_get_route (config, i);
- /* duplicates in @routes are no problem as route-manager handles them
- * gracefully (by ignoring them). */
- g_array_append_vals (routes, route, 1);
+ if (head_entry) {
+ c_list_for_each (iter, &head_entry->lst_entries_head)
+ g_array_append_vals (routes, _entry_iter_get_ip4_route (iter), 1);
}
nm_route_manager_ip4_route_register_device_route_purge_list (route_manager, device_route_purge_list);
- success = nm_route_manager_ip4_route_sync (route_manager, ifindex, routes, default_route_metric < 0, routes_full_sync);
- g_array_unref (routes);
- if (!success)
+ if (!nm_route_manager_ip4_route_sync (route_manager, ifindex, routes,
+ default_route_metric < 0, routes_full_sync))
return FALSE;
}
@@ -547,7 +662,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
merge_route_attributes (s_route, &route);
- nm_ip4_config_add_route (config, &route);
+ _add_route (config, NULL, &route);
}
/* DNS */
@@ -583,10 +698,12 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
{
NMSettingIPConfig *s_ip4;
guint32 gateway;
- guint naddresses, nroutes, nnameservers, nsearches, noptions;
+ guint naddresses, nnameservers, nsearches, noptions;
const char *method = NULL;
int i;
gint64 route_metric;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ());
@@ -599,7 +716,6 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
gateway = nm_ip4_config_get_gateway (config);
naddresses = nm_ip4_config_get_num_addresses (config);
- nroutes = nm_ip4_config_get_num_routes (config);
nnameservers = nm_ip4_config_get_num_nameservers (config);
nsearches = nm_ip4_config_get_num_searches (config);
noptions = nm_ip4_config_get_num_dns_options (config);
@@ -646,8 +762,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
NULL);
/* Routes */
- for (i = 0; i < nroutes; i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
NMIPRoute *s_route;
/* Ignore default route. */
@@ -700,6 +815,7 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
NMIP4ConfigPrivate *dst_priv;
const NMIP4ConfigPrivate *src_priv;
guint32 i;
+ NMDedupMultiIter ipconf_iter;
g_return_if_fail (src != NULL);
g_return_if_fail (dst != NULL);
@@ -725,8 +841,10 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
/* routes */
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
- for (i = 0; i < nm_ip4_config_get_num_routes (src); i++)
- nm_ip4_config_add_route (dst, nm_ip4_config_get_route (src, i));
+ const NMPlatformIP4Route *route;
+
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, src, &route)
+ _add_route (dst, NMP_OBJECT_UP_CAST (route), NULL);
}
if (dst_priv->route_metric == -1)
@@ -822,22 +940,6 @@ _nameservers_get_index (const NMIP4Config *self, guint32 ns)
}
static int
-_routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
- guint i;
-
- for (i = 0; i < priv->routes->len; i++) {
- const NMPlatformIP4Route *r = &g_array_index (priv->routes, NMPlatformIP4Route, i);
-
- if ( route->network == r->network
- && route->plen == r->plen)
- return (int) i;
- }
- return -1;
-}
-
-static int
_domains_get_index (const NMIP4Config *self, const char *domain)
{
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
@@ -924,12 +1026,17 @@ _wins_get_index (const NMIP4Config *self, guint32 wins_server)
void
nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
{
- guint32 i;
+ NMIP4ConfigPrivate *priv_dst;
+ guint i;
gint idx;
+ const NMPlatformIP4Route *r;
+ NMDedupMultiIter ipconf_iter;
g_return_if_fail (src != NULL);
g_return_if_fail (dst != NULL);
+ priv_dst = NM_IP4_CONFIG_GET_PRIVATE (dst);
+
g_object_freeze_notify (G_OBJECT (dst));
/* addresses */
@@ -957,10 +1064,10 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
/* ignore route_metric */
/* routes */
- for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) {
- idx = _routes_get_index (dst, nm_ip4_config_get_route (src, i));
- if (idx >= 0)
- nm_ip4_config_del_route (dst, idx);
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
+ nm_dedup_multi_index_remove_obj (priv_dst->multi_idx,
+ &priv_dst->idx_ip4_routes,
+ NMP_OBJECT_UP_CAST (r));
}
/* domains */
@@ -1020,14 +1127,21 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
void
nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
{
- guint32 i;
+ NMIP4ConfigPrivate *priv_dst;
+ const NMIP4ConfigPrivate *priv_src;
+ guint i;
gint idx;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *r;
- g_return_if_fail (src != NULL);
- g_return_if_fail (dst != NULL);
+ g_return_if_fail (src);
+ g_return_if_fail (dst);
g_object_freeze_notify (G_OBJECT (dst));
+ priv_dst = NM_IP4_CONFIG_GET_PRIVATE (dst);
+ priv_src = NM_IP4_CONFIG_GET_PRIVATE (src);
+
/* addresses */
for (i = 0; i < nm_ip4_config_get_num_addresses (dst); ) {
idx = _addresses_get_index (src, nm_ip4_config_get_address (dst, i));
@@ -1048,12 +1162,15 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
}
/* routes */
- for (i = 0; i < nm_ip4_config_get_num_routes (dst); ) {
- idx = _routes_get_index (src, nm_ip4_config_get_route (dst, i));
- if (idx < 0)
- nm_ip4_config_del_route (dst, i);
- else
- i++;
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
+ if (nm_dedup_multi_index_lookup_obj (priv_src->multi_idx,
+ &priv_src->idx_ip4_routes,
+ NMP_OBJECT_UP_CAST (r)))
+ continue;
+
+ if (nm_dedup_multi_index_remove_entry (priv_dst->multi_idx,
+ ipconf_iter.current) != 1)
+ nm_assert_not_reached ();
}
/* ignore domains */
@@ -1091,7 +1208,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
NMIP4ConfigPrivate *dst_priv;
const NMIP4ConfigPrivate *src_priv;
const NMPlatformIP4Address *dst_addr, *src_addr;
- const NMPlatformIP4Route *dst_route, *src_route;
+ NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
g_return_val_if_fail (src != NULL, FALSE);
g_return_val_if_fail (dst != NULL, FALSE);
@@ -1158,26 +1275,45 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
}
/* routes */
- num = nm_ip4_config_get_num_routes (src);
- are_equal = num == nm_ip4_config_get_num_routes (dst);
- if (are_equal) {
- for (i = 0; i < num; i++ ) {
- if (nm_platform_ip4_route_cmp (src_route = nm_ip4_config_get_route (src, i),
- dst_route = nm_ip4_config_get_route (dst, i))) {
- are_equal = FALSE;
- if (!routes_are_duplicate (src_route, dst_route, TRUE)) {
- has_relevant_changes = TRUE;
- break;
- }
+ nm_ip4_config_iter_ip4_route_init (&ipconf_iter_src, src);
+ nm_ip4_config_iter_ip4_route_init (&ipconf_iter_dst, dst);
+ are_equal = TRUE;
+ while (TRUE) {
+ gboolean has;
+ const NMPlatformIP4Route *r_src, *r_dst;
+
+ has = nm_ip4_config_iter_ip4_route_next (&ipconf_iter_src, &r_src);
+ if (has != nm_ip4_config_iter_ip4_route_next (&ipconf_iter_dst, &r_dst)) {
+ are_equal = FALSE;
+ has_relevant_changes = TRUE;
+ break;
+ }
+ if (!has)
+ break;
+
+ if (nm_platform_ip4_route_cmp (r_src, r_dst) != 0) {
+ are_equal = FALSE;
+ if (!_idx_obj_id_equal_ip4_route (r_src, r_dst)) {
+ has_relevant_changes = TRUE;
+ break;
}
}
- } else
- has_relevant_changes = TRUE;
+ }
if (!are_equal) {
- nm_ip4_config_reset_routes (dst);
- for (i = 0; i < num; i++)
- nm_ip4_config_add_route (dst, nm_ip4_config_get_route (src, i));
+ const NMPlatformIP4Route *r_src;
+
has_minor_changes = TRUE;
+ nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
+ nm_dedup_multi_iter_rewind (&ipconf_iter_src);
+ while (nm_ip4_config_iter_ip4_route_next (&ipconf_iter_src, &r_src)) {
+ nm_dedup_multi_index_add (dst_priv->multi_idx,
+ &dst_priv->idx_ip4_routes,
+ NMP_OBJECT_UP_CAST (r_src),
+ NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE,
+ NULL,
+ NULL);
+ }
+ nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE);
}
/* nameservers */
@@ -1339,8 +1475,11 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
void
nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
{
- guint32 i, tmp;
+ guint32 tmp;
+ guint i;
const char *str;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
g_message ("--------- NMIP4Config %p (%s)", config, detail);
@@ -1370,8 +1509,8 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
}
/* routes */
- for (i = 0; i < nm_ip4_config_get_num_routes (config); i++)
- g_message (" rt: %s", nm_platform_ip4_route_to_string (nm_ip4_config_get_route (config, i), NULL, 0));
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route)
+ g_message (" rt: %s", nm_platform_ip4_route_to_string (route, NULL, 0));
/* domains */
for (i = 0; i < nm_ip4_config_get_num_domains (config); i++)
@@ -1621,13 +1760,88 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
- if (priv->routes->len != 0) {
- g_array_set_size (priv->routes, 0);
+ if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
+ &priv->idx_ip4_routes) > 0) {
_notify (config, PROP_ROUTE_DATA);
_notify (config, PROP_ROUTES);
}
}
+static void
+_add_route (NMIP4Config *config, const NMPObject *o_new, const NMPlatformIP4Route *new)
+{
+ NMIP4ConfigPrivate *priv;
+ NMPObject o_new_storage;
+ const NMDedupMultiBox *box_old;
+
+ nm_assert (NM_IS_IP4_CONFIG (config));
+
+ priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+
+ nm_assert (priv->ifindex > 0);
+
+ /* we go through extra lengths to accept a full o_new object. That one,
+ * can be reused by increasing the ref-count. */
+ if (!o_new) {
+ nm_assert (new);
+ nm_assert (new->plen > 0 && new->plen <= 32);
+ nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE,
+ (const NMPlatformObject *) new);
+ o_new_storage.ip4_route.ifindex = priv->ifindex;
+ o_new = &o_new_storage;
+ } else {
+ nm_assert (!new);
+ nm_assert (NMP_OBJECT_GET_TYPE (o_new) == NMP_OBJECT_TYPE_IP4_ROUTE);
+ nm_assert (o_new->ip4_route.plen > 0 && o_new->ip4_route.plen <= 32);
+ if (o_new->ip4_route.ifindex != priv->ifindex) {
+ nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE, &o_new->object);
+ o_new_storage.ip4_route.ifindex = priv->ifindex;
+ o_new = &o_new_storage;
+ }
+ }
+
+ if (!nm_dedup_multi_index_add (priv->multi_idx,
+ &priv->idx_ip4_routes,
+ o_new,
+ NM_DEDUP_MULTI_IDX_MODE_APPEND,
+ NULL,
+ &box_old)) {
+ if (box_old)
+ nm_dedup_multi_box_unref (priv->multi_idx, box_old);
+ return;
+ }
+
+ if (box_old) {
+ NMIPConfigSource old_source;
+
+ old_source = ((const NMPObject *) box_old->obj)->ip_route.rt_source;
+ /* we want to keep the maximum rt_source. But since we expect
+ * that usually we already add the maxiumum right away, we first try to
+ * add the new route (replacing the old one). Only if we later
+ * find out that rt_source is now lower, we fix it.
+ */
+ if (o_new->ip_route.rt_source < old_source) {
+ if (o_new != &o_new_storage) {
+ nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE,
+ &o_new->object);
+ o_new = &o_new_storage;
+ }
+ o_new_storage.ip_route.rt_source = old_source;
+ if (!nm_dedup_multi_index_add (priv->multi_idx,
+ &priv->idx_ip4_routes,
+ o_new,
+ NM_DEDUP_MULTI_IDX_MODE_APPEND,
+ NULL,
+ NULL))
+ nm_assert_not_reached ();
+ }
+ nm_dedup_multi_box_unref (priv->multi_idx, box_old);
+ }
+
+ _notify (config, PROP_ROUTE_DATA);
+ _notify (config, PROP_ROUTES);
+}
+
/**
* nm_ip4_config_add_route:
* @config: the #NMIP4Config
@@ -1641,76 +1855,70 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
void
nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
- NMIPConfigSource old_source;
- int i;
-
- g_return_if_fail (new != NULL);
+ g_return_if_fail (config);
+ g_return_if_fail (new);
g_return_if_fail (new->plen > 0 && new->plen <= 32);
- g_return_if_fail (priv->ifindex > 0);
+ g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (config)->ifindex > 0);
- for (i = 0; i < priv->routes->len; i++ ) {
- NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
-
- if (routes_are_duplicate (item, new, FALSE)) {
- if (nm_platform_ip4_route_cmp (item, new) == 0)
- return;
- old_source = item->rt_source;
- memcpy (item, new, sizeof (*item));
- /* Restore highest priority source */
- item->rt_source = MAX (old_source, new->rt_source);
- item->ifindex = priv->ifindex;
- goto NOTIFY;
- }
- }
-
- g_array_append_val (priv->routes, *new);
- g_array_index (priv->routes, NMPlatformIP4Route, priv->routes->len - 1).ifindex = priv->ifindex;
-NOTIFY:
- _notify (config, PROP_ROUTE_DATA);
- _notify (config, PROP_ROUTES);
+ _add_route (config, NULL, new);
}
void
-nm_ip4_config_del_route (NMIP4Config *config, guint i)
+_nmtst_nm_ip4_config_del_route (NMIP4Config *self, guint i)
{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ const NMPlatformIP4Route *r;
- g_return_if_fail (i < priv->routes->len);
+ r = _nmtst_nm_ip4_config_get_route (self, i);
+ g_return_if_fail (r);
- g_array_remove_index (priv->routes, i);
- _notify (config, PROP_ROUTE_DATA);
- _notify (config, PROP_ROUTES);
+ if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
+ &priv->idx_ip4_routes,
+ NMP_OBJECT_UP_CAST (r)) != 1)
+ g_return_if_reached ();
+ _notify (self, PROP_ROUTE_DATA);
+ _notify (self, PROP_ROUTES);
}
guint
-nm_ip4_config_get_num_routes (const NMIP4Config *config)
+nm_ip4_config_get_num_routes (const NMIP4Config *self)
{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ const NMDedupMultiHeadEntry *head_entry;
- return priv->routes->len;
+ head_entry = _idx_ip4_routes (self);
+ nm_assert ((head_entry ? head_entry->len : 0) == c_list_length (&head_entry->lst_entries_head));
+ return head_entry ? head_entry->len : 0;
}
const NMPlatformIP4Route *
-nm_ip4_config_get_route (const NMIP4Config *config, guint i)
-{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-
- return &g_array_index (priv->routes, NMPlatformIP4Route, i);
+_nmtst_nm_ip4_config_get_route (const NMIP4Config *self, guint i)
+{
+ const NMDedupMultiHeadEntry *head_entry;
+ CList *iter;
+ guint j;
+
+ head_entry = _idx_ip4_routes (self);
+ if (head_entry) {
+ j = 0;
+ c_list_for_each (iter, &head_entry->lst_entries_head) {
+ if (i == j)
+ return _entry_iter_get_ip4_route (iter);
+ j++;
+ }
+ }
+ g_return_val_if_reached (NULL);
}
const NMPlatformIP4Route *
-nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host)
+nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host)
{
- const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
- guint i;
- NMPlatformIP4Route *best_route = NULL;
+ const NMPlatformIP4Route *best_route = NULL;
+ const NMPlatformIP4Route *item;
+ NMDedupMultiIter ipconf_iter;
g_return_val_if_fail (host, NULL);
- for (i = 0; i < priv->routes->len; i++) {
- NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
-
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, self, &item) {
if (item->gateway != 0)
continue;
@@ -1725,7 +1933,6 @@ nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host
best_route = item;
}
-
return best_route;
}
@@ -2193,6 +2400,8 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
{
guint i;
const char *s;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
g_return_if_fail (config);
g_return_if_fail (sum);
@@ -2208,9 +2417,8 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
hash_u32 (sum, address->peer_address & nm_utils_ip4_prefix_to_netmask (address->plen));
}
- for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
hash_u32 (sum, route->network);
hash_u32 (sum, route->plen);
hash_u32 (sum, route->gateway);
@@ -2295,6 +2503,9 @@ get_property (GObject *object, guint prop_id,
{
NMIP4Config *config = NM_IP4_CONFIG (object);
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
+ GVariantBuilder array_builder, addr_builder, route_builder;
switch (prop_id) {
case PROP_IFINDEX:
@@ -2303,7 +2514,6 @@ get_property (GObject *object, guint prop_id,
case PROP_ADDRESS_DATA:
case PROP_ADDRESSES:
{
- GVariantBuilder array_builder, addr_builder;
gs_unref_array GArray *new = NULL;
guint naddr, i;
@@ -2370,14 +2580,8 @@ return_cached:
break;
case PROP_ROUTE_DATA:
{
- GVariantBuilder array_builder, route_builder;
- guint nroutes = nm_ip4_config_get_num_routes (config);
- guint i;
-
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
- for (i = 0; i < nroutes; i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
-
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&route_builder, "{sv}",
"dest",
@@ -2402,13 +2606,8 @@ return_cached:
break;
case PROP_ROUTES:
{
- GVariantBuilder array_builder;
- guint nroutes = nm_ip4_config_get_num_routes (config);
- guint i;
-
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau"));
- for (i = 0; i < nroutes; i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
guint32 dbus_route[4];
/* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the
@@ -2501,8 +2700,10 @@ nm_ip4_config_init (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+ nm_ip_config_dedup_multi_idx_type_init ((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
+ NMP_OBJECT_TYPE_IP4_ROUTE);
+
priv->addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address));
- priv->routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32));
priv->domains = g_ptr_array_new_with_free_func (g_free);
priv->searches = g_ptr_array_new_with_free_func (g_free);
@@ -2528,10 +2729,11 @@ finalize (GObject *object)
NMIP4Config *self = NM_IP4_CONFIG (object);
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
+ nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_routes);
+
nm_clear_g_variant (&priv->address_data_variant);
nm_clear_g_variant (&priv->addresses_variant);
g_array_unref (priv->addresses);
- g_array_unref (priv->routes);
g_array_unref (priv->nameservers);
g_ptr_array_unref (priv->domains);
g_ptr_array_unref (priv->searches);
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 1a336968fd..f1f2979232 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -24,6 +24,27 @@
#include "nm-exported-object.h"
#include "nm-setting-ip4-config.h"
+#include "nm-utils/nm-dedup-multi.h"
+
+/*****************************************************************************/
+
+typedef struct {
+ NMDedupMultiIdxType parent;
+ NMPObjectType obj_type;
+} NMIPConfigDedupMultiIdxType;
+
+void nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type, NMPObjectType obj_type);
+
+void nm_ip4_config_iter_ip4_route_init (NMDedupMultiIter *iter, const NMIP4Config *self);
+gboolean nm_ip4_config_iter_ip4_route_next (NMDedupMultiIter *iter, const NMPlatformIP4Route **out_route);
+
+#define nm_ip4_config_iter_ip4_route_for_each(iter, self, route) \
+ for (nm_ip4_config_iter_ip4_route_init ((iter), (self)); \
+ nm_ip4_config_iter_ip4_route_next ((iter), (route)); \
+ )
+
+/*****************************************************************************/
+
#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ())
#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP4_CONFIG, NMIP4Config))
#define NM_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
@@ -55,14 +76,14 @@ typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
GType nm_ip4_config_get_type (void);
-NMIP4Config * nm_ip4_config_new (struct _NMDedupMultiIndex *multi_idx,
+NMIP4Config * nm_ip4_config_new (NMDedupMultiIndex *multi_idx,
int ifindex);
int nm_ip4_config_get_ifindex (const NMIP4Config *config);
-struct _NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
+NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
-NMIP4Config *nm_ip4_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
+NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
gboolean nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteManager *route_manager, int ifindex, gboolean routes_full_sync, gint64 default_route_metric);
void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric);
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config);
@@ -93,9 +114,9 @@ gboolean nm_ip4_config_address_exists (const NMIP4Config *config, const NMPlatfo
void nm_ip4_config_reset_routes (NMIP4Config *config);
void nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *route);
-void nm_ip4_config_del_route (NMIP4Config *config, guint i);
+void _nmtst_nm_ip4_config_del_route (NMIP4Config *config, guint i);
guint nm_ip4_config_get_num_routes (const NMIP4Config *config);
-const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint i);
+const NMPlatformIP4Route *_nmtst_nm_ip4_config_get_route (const NMIP4Config *config, guint i);
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host);
diff --git a/src/nm-pacrunner-manager.c b/src/nm-pacrunner-manager.c
index 0a1cd823f4..a4c345e5d7 100644
--- a/src/nm-pacrunner-manager.c
+++ b/src/nm-pacrunner-manager.c
@@ -168,8 +168,10 @@ add_proxy_config (GVariantBuilder *proxy_data, const NMProxyConfig *proxy_config
static void
get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
{
+ NMDedupMultiIter ipconf_iter;
char *cidr;
- int i;
+ const NMPlatformIP4Route *routes;
+ guint i;
/* Extract searches */
for (i = 0; i < nm_ip4_config_get_num_searches (ip4); i++)
@@ -189,9 +191,7 @@ get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
g_ptr_array_add (domains, cidr);
}
- for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) {
- const NMPlatformIP4Route *routes = nm_ip4_config_get_route (ip4, i);
-
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) {
cidr = g_strdup_printf ("%s/%u",
nm_utils_inet4_ntop (routes->network, NULL),
routes->plen);
diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c
index d9afb4c6ac..e865f5f26a 100644
--- a/src/tests/test-ip4-config.c
+++ b/src/tests/test-ip4-config.c
@@ -121,7 +121,7 @@ test_subtract (void)
g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0);
g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1);
- test_route = nm_ip4_config_get_route (dst, 0);
+ test_route = _nmtst_nm_ip4_config_get_route (dst, 0);
g_assert (test_route != NULL);
g_assert_cmpuint (test_route->network, ==, nmtst_inet4_from_string (expected_route_dest));
g_assert_cmpuint (test_route->plen, ==, expected_route_plen);
@@ -236,27 +236,27 @@ test_add_route_with_source (void)
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (a, &route);
- test_route = nm_ip4_config_get_route (a, 0);
+ test_route = _nmtst_nm_ip4_config_get_route (a, 0);
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
nm_ip4_config_add_route (a, &route);
- test_route = nm_ip4_config_get_route (a, 0);
+ test_route = _nmtst_nm_ip4_config_get_route (a, 0);
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
/* Test that a lower priority address source is overwritten */
- nm_ip4_config_del_route (a, 0);
+ _nmtst_nm_ip4_config_del_route (a, 0);
route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
nm_ip4_config_add_route (a, &route);
- test_route = nm_ip4_config_get_route (a, 0);
+ test_route = _nmtst_nm_ip4_config_get_route (a, 0);
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
nm_ip4_config_add_route (a, &route);
- test_route = nm_ip4_config_get_route (a, 0);
+ test_route = _nmtst_nm_ip4_config_get_route (a, 0);
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
g_object_unref (a);
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index 9a0de7ebfe..7c8f06ced6 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -942,6 +942,7 @@ print_vpn_config (NMVpnConnection *self)
char *dns_domain = NULL;
guint32 num, i;
char buf[NM_UTILS_INET_ADDRSTRLEN];
+ NMDedupMultiIter ipconf_iter;
if (priv->ip4_external_gw) {
_LOGI ("Data: VPN Gateway: %s",
@@ -954,6 +955,8 @@ print_vpn_config (NMVpnConnection *self)
_LOGI ("Data: Tunnel Device: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (priv->ip_iface));
if (priv->ip4_config) {
+ const NMPlatformIP4Route *route;
+
_LOGI ("Data: IPv4 configuration:");
address4 = nm_ip4_config_get_address (priv->ip4_config, 0);
@@ -965,10 +968,7 @@ print_vpn_config (NMVpnConnection *self)
_LOGI ("Data: Internal Point-to-Point Address: %s", nm_utils_inet4_ntop (address4->peer_address, NULL));
_LOGI ("Data: Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (priv->ip4_config));
- num = nm_ip4_config_get_num_routes (priv->ip4_config);
- for (i = 0; i < num; i++) {
- const NMPlatformIP4Route *route = nm_ip4_config_get_route (priv->ip4_config, i);
-
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route) {
_LOGI ("Data: Static Route: %s/%d Next Hop: %s",
nm_utils_inet4_ntop (route->network, NULL),
route->plen,
@@ -1404,7 +1404,6 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
const char *str;
GVariant *v;
gboolean b;
- guint i, n;
int ip_ifindex;
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
@@ -1505,9 +1504,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b)
&& b) {
if (priv->ip4_config) {
- n = nm_ip4_config_get_num_routes (priv->ip4_config);
- for (i = 0; i < n; i++)
- nm_ip4_config_add_route (config, nm_ip4_config_get_route (priv->ip4_config, i));
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIP4Route *route;
+
+ nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route)
+ nm_ip4_config_add_route (config, route);
}
} else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) {
while (g_variant_iter_next (iter, "@au", &v)) {