core: support tracking default-route in NMIP4Config/NMIP6Config

Default-routes are for the most part like regular routes. Add support to
track them like regular routes in NMIP4Config/NMIP6Config.

One thing is, sometimes we need to figure out whether an ip-config
instance has a default-route. For that, keep track of the best
default-route (there might be multiple) and expose it. That is
the most complicated part of this patch, because there are so many
places where the list of routes gets modified (replace, intersect,
subtract, merge, add), and they all need to take care of updating
the best default-route.

In a next patch, NMDefaultRouteManager will be dropped and default-routes
will be tracked by NMIP4Config/NMIP6Config.
This commit is contained in:
Thomas Haller
2017-08-31 13:39:04 +02:00
parent a214f398e7
commit 0918b4914d
7 changed files with 439 additions and 69 deletions

View File

@@ -91,8 +91,10 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address) nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address)
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains); nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains); if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
}
/* Terminating NULL so we can use g_strfreev() to free it */ /* Terminating NULL so we can use g_strfreev() to free it */
g_ptr_array_add (domains, NULL); g_ptr_array_add (domains, NULL);
@@ -119,8 +121,10 @@ get_ip6_rdns_domains (NMIP6Config *ip6)
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address) nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address)
nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains); nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains); if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
}
/* Terminating NULL so we can use g_strfreev() to free it */ /* Terminating NULL so we can use g_strfreev() to free it */
g_ptr_array_add (domains, NULL); g_ptr_array_add (domains, NULL);

View File

@@ -166,6 +166,8 @@ dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
/* Static routes */ /* Static routes */
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau")); g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) { 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[0] = route->network;
array[1] = route->plen; array[1] = route->plen;
array[2] = route->gateway; array[2] = route->gateway;
@@ -235,6 +237,8 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
/* Static routes */ /* Static routes */
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)")); g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)"));
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) { nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
continue;
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
&route->network, &route->network,
sizeof (struct in6_addr), 1); sizeof (struct in6_addr), 1);

View File

@@ -377,6 +377,7 @@ typedef struct {
GVariant *route_data_variant; GVariant *route_data_variant;
GVariant *routes_variant; GVariant *routes_variant;
NMDedupMultiIndex *multi_idx; NMDedupMultiIndex *multi_idx;
const NMPObject *best_default_route;
union { union {
NMIPConfigDedupMultiIdxType idx_ip4_addresses_; NMIPConfigDedupMultiIdxType idx_ip4_addresses_;
NMDedupMultiIdxType idx_ip4_addresses; NMDedupMultiIdxType idx_ip4_addresses;
@@ -471,6 +472,95 @@ nm_ip_config_iter_ip4_route_init (NMDedupMultiIter *ipconf_iter, const NMIP4Conf
/*****************************************************************************/ /*****************************************************************************/
const NMPObject *
_nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NMPObject *obj_cmp)
{
int addr_family;
int c;
guint metric_cur, metric_cmp;
nm_assert ( !obj_cur
|| NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_cur), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
nm_assert ( !obj_cmp
|| ( !obj_cur
&& NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_cmp), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE))
|| NMP_OBJECT_GET_TYPE (obj_cur) == NMP_OBJECT_GET_TYPE (obj_cmp));
nm_assert ( !obj_cur
|| nm_ip_config_best_default_route_is (obj_cur));
/* assumes that @obj_cur is already the best default route (or NULL). It checks whether
* @obj_cmp is also a default route and returns the best of both. */
if ( obj_cmp
&& nm_ip_config_best_default_route_is (obj_cmp)) {
if (!obj_cur)
return obj_cmp;
addr_family = NMP_OBJECT_GET_CLASS (obj_cmp)->addr_family;
metric_cur = nm_utils_ip_route_metric_normalize (addr_family, NMP_OBJECT_CAST_IP_ROUTE (obj_cur)->metric);
metric_cmp = nm_utils_ip_route_metric_normalize (addr_family, NMP_OBJECT_CAST_IP_ROUTE (obj_cmp)->metric);
if (metric_cmp < metric_cur)
return obj_cmp;
if (metric_cmp == metric_cur) {
/* Routes have the same metric. We still want to deterministically
* prefer one or the other. It's important to consistently choose one
* or the other, so that the order doesn't matter how routes are added
* (and merged). */
c = nmp_object_cmp (obj_cur, obj_cmp);
if (c != 0)
return c < 0 ? obj_cur : obj_cmp;
/* as last resort, compare pointers. */
if (obj_cmp < obj_cur)
return obj_cmp;
}
}
return obj_cur;
}
gboolean
_nm_ip_config_best_default_route_set (const NMPObject **best_default_route, const NMPObject *new_candidate)
{
if (new_candidate == *best_default_route)
return FALSE;
nmp_object_ref (new_candidate);
nm_clear_nmp_object (best_default_route);
*best_default_route = new_candidate;
return TRUE;
}
gboolean
_nm_ip_config_best_default_route_merge (const NMPObject **best_default_route, const NMPObject *new_candidate)
{
new_candidate = _nm_ip_config_best_default_route_find_better (*best_default_route,
new_candidate);
return _nm_ip_config_best_default_route_set (best_default_route, new_candidate);
}
const NMPObject *
nm_ip4_config_best_default_route_get (const NMIP4Config *self)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), NULL);
return NM_IP4_CONFIG_GET_PRIVATE (self)->best_default_route;
}
const NMPObject *
_nm_ip4_config_best_default_route_find (const NMIP4Config *self)
{
NMDedupMultiIter ipconf_iter;
const NMPObject *new_best_default_route = NULL;
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, NULL) {
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route,
ipconf_iter.current->obj);
}
return new_best_default_route;
}
/*****************************************************************************/
static void static void
_notify_addresses (NMIP4Config *self) _notify_addresses (NMIP4Config *self)
{ {
@@ -487,6 +577,7 @@ _notify_routes (NMIP4Config *self)
{ {
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
nm_assert (priv->best_default_route == _nm_ip4_config_best_default_route_find (self));
nm_clear_g_variant (&priv->route_data_variant); nm_clear_g_variant (&priv->route_data_variant);
nm_clear_g_variant (&priv->routes_variant); nm_clear_g_variant (&priv->routes_variant);
_notify (self, PROP_ROUTE_DATA); _notify (self, PROP_ROUTE_DATA);
@@ -1056,8 +1147,7 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) { nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
NMIPRoute *s_route; NMIPRoute *s_route;
/* Ignore default route. */ if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
if (!route->plen)
continue; continue;
/* Ignore routes provided by external sources */ /* Ignore routes provided by external sources */
@@ -1133,10 +1223,8 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
/* routes */ /* routes */
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) { if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
const NMPlatformIP4Route *route; nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, NULL)
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &route)
_add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL);
} }
if (dst_priv->route_metric == -1) if (dst_priv->route_metric == -1)
@@ -1310,6 +1398,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
const NMPlatformIP4Route *r; const NMPlatformIP4Route *r;
NMDedupMultiIter ipconf_iter; NMDedupMultiIter ipconf_iter;
gboolean changed; gboolean changed;
gboolean changed_default_route;
g_return_if_fail (src != NULL); g_return_if_fail (src != NULL);
g_return_if_fail (dst != NULL); g_return_if_fail (dst != NULL);
@@ -1349,12 +1438,24 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
/* routes */ /* routes */
changed = FALSE; changed = FALSE;
changed_default_route = FALSE;
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) { nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
nm_auto_nmpobj const NMPObject *obj_old = NULL;
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx, if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
&dst_priv->idx_ip4_routes, &dst_priv->idx_ip4_routes,
NMP_OBJECT_UP_CAST (r), NMP_OBJECT_UP_CAST (r),
NULL)) (gconstpointer *) &obj_old)) {
if (dst_priv->best_default_route == obj_old) {
nm_clear_nmp_object (&dst_priv->best_default_route);
changed_default_route = TRUE;
}
changed = TRUE; changed = TRUE;
}
}
if (changed_default_route) {
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
_nm_ip4_config_best_default_route_find (dst));
} }
if (changed) if (changed)
_notify_routes (dst); _notify_routes (dst);
@@ -1421,16 +1522,17 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
NMDedupMultiIter ipconf_iter; NMDedupMultiIter ipconf_iter;
const NMPlatformIP4Address *a; const NMPlatformIP4Address *a;
const NMPlatformIP4Route *r; const NMPlatformIP4Route *r;
const NMPObject *new_best_default_route;
gboolean changed; gboolean changed;
g_return_if_fail (src); g_return_if_fail (src);
g_return_if_fail (dst); g_return_if_fail (dst);
g_object_freeze_notify (G_OBJECT (dst));
dst_priv = NM_IP4_CONFIG_GET_PRIVATE (dst); dst_priv = NM_IP4_CONFIG_GET_PRIVATE (dst);
src_priv = NM_IP4_CONFIG_GET_PRIVATE (src); src_priv = NM_IP4_CONFIG_GET_PRIVATE (src);
g_object_freeze_notify (G_OBJECT (dst));
/* addresses */ /* addresses */
changed = FALSE; changed = FALSE;
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, dst, &a) { nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, dst, &a) {
@@ -1459,17 +1561,24 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
/* routes */ /* routes */
changed = FALSE; changed = FALSE;
new_best_default_route = NULL;
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) { nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx, if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
&src_priv->idx_ip4_routes, &src_priv->idx_ip4_routes,
NMP_OBJECT_UP_CAST (r))) o)) {
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
continue; continue;
}
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx, if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
ipconf_iter.current) != 1) ipconf_iter.current) != 1)
nm_assert_not_reached (); nm_assert_not_reached ();
changed = TRUE; changed = TRUE;
} }
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
nm_assert (changed);
if (changed) if (changed)
_notify_routes (dst); _notify_routes (dst);
@@ -1509,6 +1618,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
const NMIP4ConfigPrivate *src_priv; const NMIP4ConfigPrivate *src_priv;
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst; NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
const NMDedupMultiHeadEntry *head_entry_src; const NMDedupMultiHeadEntry *head_entry_src;
const NMPObject *new_best_default_route;
g_return_val_if_fail (src != NULL, FALSE); g_return_val_if_fail (src != NULL, FALSE);
g_return_val_if_fail (dst != NULL, FALSE); g_return_val_if_fail (dst != NULL, FALSE);
@@ -1627,19 +1737,25 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
} }
if (!are_equal) { if (!are_equal) {
has_minor_changes = TRUE; has_minor_changes = TRUE;
new_best_default_route = NULL;
nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes); nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) { nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
const NMPObject *o = ipconf_iter_src.current->obj;
const NMPObject *obj_new;
_nm_ip_config_add_obj (dst_priv->multi_idx, _nm_ip_config_add_obj (dst_priv->multi_idx,
&dst_priv->idx_ip4_routes_, &dst_priv->idx_ip4_routes_,
dst_priv->ifindex, dst_priv->ifindex,
ipconf_iter_src.current->obj, o,
NULL, NULL,
FALSE, FALSE,
TRUE, TRUE,
NULL, NULL,
NULL); &obj_new);
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
} }
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE); nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE);
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
_notify_routes (dst); _notify_routes (dst);
} }
@@ -2028,18 +2144,12 @@ nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *new)
void void
_nmtst_ip4_config_del_address (NMIP4Config *self, guint i) _nmtst_ip4_config_del_address (NMIP4Config *self, guint i)
{ {
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
const NMPlatformIP4Address *a; const NMPlatformIP4Address *a;
a = _nmtst_ip4_config_get_address (self, i); a = _nmtst_ip4_config_get_address (self, i);
g_return_if_fail (a); if (!nm_ip4_config_nmpobj_remove (self,
NMP_OBJECT_UP_CAST (a)))
if (nm_dedup_multi_index_remove_obj (priv->multi_idx, g_assert_not_reached ();
&priv->idx_ip4_addresses,
NMP_OBJECT_UP_CAST (a),
NULL) != 1)
g_return_if_reached ();
_notify_addresses (self);
} }
guint guint
@@ -2121,8 +2231,10 @@ nm_ip4_config_reset_routes (NMIP4Config *self)
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
if (nm_dedup_multi_index_remove_idx (priv->multi_idx, if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
&priv->idx_ip4_routes) > 0) &priv->idx_ip4_routes) > 0) {
nm_clear_nmp_object (&priv->best_default_route);
_notify_routes (self); _notify_routes (self);
}
} }
static void static void
@@ -2132,6 +2244,7 @@ _add_route (NMIP4Config *self,
const NMPObject **out_obj_new) const NMPObject **out_obj_new)
{ {
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
nm_auto_nmpobj const NMPObject *obj_old = NULL;
const NMPObject *obj_new_2; const NMPObject *obj_new_2;
nm_assert ((!new) != (!obj_new)); nm_assert ((!new) != (!obj_new));
@@ -2145,8 +2258,12 @@ _add_route (NMIP4Config *self,
(const NMPlatformObject *) new, (const NMPlatformObject *) new,
TRUE, TRUE,
FALSE, FALSE,
NULL, &obj_old,
&obj_new_2)) { &obj_new_2)) {
if ( priv->best_default_route == obj_old
&& obj_old != obj_new_2)
nm_clear_nmp_object (&priv->best_default_route);
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
_notify_routes (self); _notify_routes (self);
} else } else
@@ -2172,7 +2289,7 @@ nm_ip4_config_add_route (NMIP4Config *self,
{ {
g_return_if_fail (self); g_return_if_fail (self);
g_return_if_fail (new); g_return_if_fail (new);
g_return_if_fail (new->plen > 0 && new->plen <= 32); g_return_if_fail (new->plen <= 32);
g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (self)->ifindex > 0); g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (self)->ifindex > 0);
_add_route (self, NULL, new, out_obj_new); _add_route (self, NULL, new, out_obj_new);
@@ -2181,18 +2298,12 @@ nm_ip4_config_add_route (NMIP4Config *self,
void void
_nmtst_ip4_config_del_route (NMIP4Config *self, guint i) _nmtst_ip4_config_del_route (NMIP4Config *self, guint i)
{ {
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
const NMPlatformIP4Route *r; const NMPlatformIP4Route *r;
r = _nmtst_ip4_config_get_route (self, i); r = _nmtst_ip4_config_get_route (self, i);
g_return_if_fail (r); if (!nm_ip4_config_nmpobj_remove (self,
NMP_OBJECT_UP_CAST (r)))
if (nm_dedup_multi_index_remove_obj (priv->multi_idx, g_assert_not_reached ();
&priv->idx_ip4_routes,
NMP_OBJECT_UP_CAST (r),
NULL) != 1)
g_return_if_reached ();
_notify_routes (self);
} }
guint guint
@@ -2701,6 +2812,84 @@ nm_ip4_config_get_metered (const NMIP4Config *self)
/*****************************************************************************/ /*****************************************************************************/
const NMPObject *
nm_ip4_config_nmpobj_lookup (const NMIP4Config *self, const NMPObject *needle)
{
const NMIP4ConfigPrivate *priv;
const NMDedupMultiIdxType *idx_type;
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), NULL);
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
switch (NMP_OBJECT_GET_TYPE (needle)) {
case NMP_OBJECT_TYPE_IP4_ADDRESS:
idx_type = &priv->idx_ip4_addresses;
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
idx_type = &priv->idx_ip4_routes;
break;
default:
g_return_val_if_reached (NULL);
}
return nm_dedup_multi_entry_get_obj (nm_dedup_multi_index_lookup_obj (priv->multi_idx,
idx_type,
needle));
}
gboolean
nm_ip4_config_nmpobj_remove (NMIP4Config *self,
const NMPObject *needle)
{
NMIP4ConfigPrivate *priv;
NMDedupMultiIdxType *idx_type;
nm_auto_nmpobj const NMPObject *obj_old = NULL;
guint n;
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE);
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
switch (NMP_OBJECT_GET_TYPE (needle)) {
case NMP_OBJECT_TYPE_IP4_ADDRESS:
idx_type = &priv->idx_ip4_addresses;
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
idx_type = &priv->idx_ip4_routes;
break;
default:
g_return_val_if_reached (FALSE);
}
n = nm_dedup_multi_index_remove_obj (priv->multi_idx,
idx_type,
needle,
(gconstpointer *) &obj_old);
if (n != 1) {
nm_assert (n == 0);
return FALSE;
}
nm_assert (NMP_OBJECT_GET_TYPE (obj_old) == NMP_OBJECT_GET_TYPE (needle));
switch (NMP_OBJECT_GET_TYPE (obj_old)) {
case NMP_OBJECT_TYPE_IP4_ADDRESS:
_notify_addresses (self);
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
if (priv->best_default_route == obj_old) {
_nm_ip_config_best_default_route_set (&priv->best_default_route,
_nm_ip4_config_best_default_route_find (self));
}
_notify_routes (self);
break;
default:
nm_assert_not_reached ();
}
return TRUE;
}
/*****************************************************************************/
static inline void static inline void
hash_u32 (GChecksum *sum, guint32 n) hash_u32 (GChecksum *sum, guint32 n)
{ {
@@ -3056,6 +3245,8 @@ finalize (GObject *object)
NMIP4Config *self = NM_IP4_CONFIG (object); NMIP4Config *self = NM_IP4_CONFIG (object);
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
nm_clear_nmp_object (&priv->best_default_route);
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_addresses); nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_addresses);
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_routes); nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_routes);

View File

@@ -75,6 +75,25 @@ nm_ip_config_iter_ip4_route_next (NMDedupMultiIter *ipconf_iter, const NMPlatfor
/*****************************************************************************/ /*****************************************************************************/
static inline gboolean
nm_ip_config_best_default_route_is (const NMPObject *obj)
{
const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE (obj);
/* return whether @obj is considered a default-route, that is, a route
* as added by NetworkManager. E.g. if the route is not in the main-table,
* it's considered just like a regular route. */
return r
&& !r->table_coerced
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r);
}
const NMPObject *_nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NMPObject *obj_cmp);
gboolean _nm_ip_config_best_default_route_set (const NMPObject **best_default_route, const NMPObject *new_candidate);
gboolean _nm_ip_config_best_default_route_merge (const NMPObject **best_default_route, const NMPObject *new_candidate);
/*****************************************************************************/
gboolean nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a, gboolean nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a,
const NMPlatformIP4Address *b); const NMPlatformIP4Address *b);
gboolean nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a, gboolean nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a,
@@ -163,6 +182,9 @@ gboolean nm_ip4_config_has_gateway (const NMIP4Config *self);
guint32 nm_ip4_config_get_gateway (const NMIP4Config *self); guint32 nm_ip4_config_get_gateway (const NMIP4Config *self);
gint64 nm_ip4_config_get_route_metric (const NMIP4Config *self); gint64 nm_ip4_config_get_route_metric (const NMIP4Config *self);
const NMPObject *nm_ip4_config_best_default_route_get (const NMIP4Config *self);
const NMPObject *_nm_ip4_config_best_default_route_find (const NMIP4Config *self);
const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self); const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self);
void nm_ip4_config_reset_addresses (NMIP4Config *self); void nm_ip4_config_reset_addresses (NMIP4Config *self);
void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address); void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address);
@@ -234,6 +256,11 @@ NMIPConfigSource nm_ip4_config_get_mtu_source (const NMIP4Config *self);
void nm_ip4_config_set_metered (NMIP4Config *self, gboolean metered); void nm_ip4_config_set_metered (NMIP4Config *self, gboolean metered);
gboolean nm_ip4_config_get_metered (const NMIP4Config *self); gboolean nm_ip4_config_get_metered (const NMIP4Config *self);
const NMPObject *nm_ip4_config_nmpobj_lookup (const NMIP4Config *self,
const NMPObject *needle);
gboolean nm_ip4_config_nmpobj_remove (NMIP4Config *self,
const NMPObject *needle);
void nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only); void nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only);
gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b); gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b);

View File

@@ -72,6 +72,7 @@ typedef struct {
GVariant *route_data_variant; GVariant *route_data_variant;
GVariant *routes_variant; GVariant *routes_variant;
NMDedupMultiIndex *multi_idx; NMDedupMultiIndex *multi_idx;
const NMPObject *best_default_route;
union { union {
NMIPConfigDedupMultiIdxType idx_ip6_addresses_; NMIPConfigDedupMultiIdxType idx_ip6_addresses_;
NMDedupMultiIdxType idx_ip6_addresses; NMDedupMultiIdxType idx_ip6_addresses;
@@ -177,6 +178,29 @@ nm_ip_config_iter_ip6_route_init (NMDedupMultiIter *ipconf_iter, const NMIP6Conf
/*****************************************************************************/ /*****************************************************************************/
const NMPObject *
nm_ip6_config_best_default_route_get (const NMIP6Config *self)
{
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), NULL);
return NM_IP6_CONFIG_GET_PRIVATE (self)->best_default_route;
}
const NMPObject *
_nm_ip6_config_best_default_route_find (const NMIP6Config *self)
{
NMDedupMultiIter ipconf_iter;
const NMPObject *new_best_default_route = NULL;
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, NULL) {
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route,
ipconf_iter.current->obj);
}
return new_best_default_route;
}
/*****************************************************************************/
static void static void
_notify_addresses (NMIP6Config *self) _notify_addresses (NMIP6Config *self)
{ {
@@ -193,6 +217,7 @@ _notify_routes (NMIP6Config *self)
{ {
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
nm_assert (priv->best_default_route == _nm_ip6_config_best_default_route_find (self));
nm_clear_g_variant (&priv->route_data_variant); nm_clear_g_variant (&priv->route_data_variant);
nm_clear_g_variant (&priv->routes_variant); nm_clear_g_variant (&priv->routes_variant);
_notify (self, PROP_ROUTE_DATA); _notify (self, PROP_ROUTE_DATA);
@@ -781,8 +806,7 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
if (IN6_IS_ADDR_LINKLOCAL (&route->network)) if (IN6_IS_ADDR_LINKLOCAL (&route->network))
continue; continue;
/* Ignore default route. */ if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
if (!route->plen)
continue; continue;
/* Ignore routes provided by external sources */ /* Ignore routes provided by external sources */
@@ -857,10 +881,8 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
/* routes */ /* routes */
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) { if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
const NMPlatformIP6Route *route; nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, NULL)
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &route)
_add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL);
} }
if (dst_priv->route_metric == -1) if (dst_priv->route_metric == -1)
@@ -997,6 +1019,7 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
NMDedupMultiIter ipconf_iter; NMDedupMultiIter ipconf_iter;
const struct in6_addr *dst_tmp, *src_tmp; const struct in6_addr *dst_tmp, *src_tmp;
gboolean changed; gboolean changed;
gboolean changed_default_route;
g_return_if_fail (src != NULL); g_return_if_fail (src != NULL);
g_return_if_fail (dst != NULL); g_return_if_fail (dst != NULL);
@@ -1037,12 +1060,24 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
/* routes */ /* routes */
changed = FALSE; changed = FALSE;
changed_default_route = FALSE;
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r) { nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r) {
nm_auto_nmpobj const NMPObject *obj_old = NULL;
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx, if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
&dst_priv->idx_ip6_routes, &dst_priv->idx_ip6_routes,
NMP_OBJECT_UP_CAST (r), NMP_OBJECT_UP_CAST (r),
NULL)) (gconstpointer *) &obj_old)) {
if (dst_priv->best_default_route == obj_old) {
nm_clear_nmp_object (&dst_priv->best_default_route);
changed_default_route = TRUE;
}
changed = TRUE; changed = TRUE;
}
}
if (changed_default_route) {
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
_nm_ip6_config_best_default_route_find (dst));
} }
if (changed) if (changed)
_notify_routes (dst); _notify_routes (dst);
@@ -1088,6 +1123,7 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
const NMPlatformIP6Address *a; const NMPlatformIP6Address *a;
const NMPlatformIP6Route *r; const NMPlatformIP6Route *r;
gboolean changed; gboolean changed;
const NMPObject *new_best_default_route;
g_return_if_fail (src); g_return_if_fail (src);
g_return_if_fail (dst); g_return_if_fail (dst);
@@ -1128,17 +1164,24 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
/* routes */ /* routes */
changed = FALSE; changed = FALSE;
new_best_default_route = NULL;
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) { nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) {
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx, if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
&src_priv->idx_ip6_routes, &src_priv->idx_ip6_routes,
NMP_OBJECT_UP_CAST (r))) o)) {
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
continue; continue;
}
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx, if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
ipconf_iter.current) != 1) ipconf_iter.current) != 1)
nm_assert_not_reached (); nm_assert_not_reached ();
changed = TRUE; changed = TRUE;
} }
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
nm_assert (changed);
if (changed) if (changed)
_notify_routes (dst); _notify_routes (dst);
@@ -1175,6 +1218,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
const NMIP6ConfigPrivate *src_priv; const NMIP6ConfigPrivate *src_priv;
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst; NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
const NMDedupMultiHeadEntry *head_entry_src; const NMDedupMultiHeadEntry *head_entry_src;
const NMPObject *new_best_default_route;
g_return_val_if_fail (NM_IS_IP6_CONFIG (src), FALSE); g_return_val_if_fail (NM_IS_IP6_CONFIG (src), FALSE);
g_return_val_if_fail (NM_IS_IP6_CONFIG (dst), FALSE); g_return_val_if_fail (NM_IS_IP6_CONFIG (dst), FALSE);
@@ -1293,19 +1337,25 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
} }
if (!are_equal) { if (!are_equal) {
has_minor_changes = TRUE; has_minor_changes = TRUE;
new_best_default_route = NULL;
nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes); nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes);
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) { nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
const NMPObject *o = ipconf_iter_src.current->obj;
const NMPObject *obj_new;
_nm_ip_config_add_obj (dst_priv->multi_idx, _nm_ip_config_add_obj (dst_priv->multi_idx,
&dst_priv->idx_ip6_routes_, &dst_priv->idx_ip6_routes_,
dst_priv->ifindex, dst_priv->ifindex,
ipconf_iter_src.current->obj, o,
NULL, NULL,
FALSE, FALSE,
TRUE, TRUE,
NULL, NULL,
NULL); &obj_new);
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
} }
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE); nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE);
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
_notify_routes (dst); _notify_routes (dst);
} }
@@ -1631,18 +1681,12 @@ nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *new)
void void
_nmtst_ip6_config_del_address (NMIP6Config *self, guint i) _nmtst_ip6_config_del_address (NMIP6Config *self, guint i)
{ {
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
const NMPlatformIP6Address *a; const NMPlatformIP6Address *a;
a = _nmtst_ip6_config_get_address (self, i); a = _nmtst_ip6_config_get_address (self, i);
g_return_if_fail (a); if (!nm_ip6_config_nmpobj_remove (self,
NMP_OBJECT_UP_CAST (a)))
if (nm_dedup_multi_index_remove_obj (priv->multi_idx, g_assert_not_reached ();
&priv->idx_ip6_addresses,
NMP_OBJECT_UP_CAST (a),
NULL) != 1)
g_return_if_reached ();
_notify_addresses (self);
} }
guint guint
@@ -1767,6 +1811,7 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
NMIP6ConfigPrivate *priv; NMIP6ConfigPrivate *priv;
guint i; guint i;
gboolean changed = FALSE; gboolean changed = FALSE;
const NMPObject *new_best_default_route;
g_return_if_fail (NM_IS_IP6_CONFIG (self)); g_return_if_fail (NM_IS_IP6_CONFIG (self));
@@ -1776,9 +1821,11 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
nm_dedup_multi_index_dirty_set_idx (priv->multi_idx, &priv->idx_ip6_routes); nm_dedup_multi_index_dirty_set_idx (priv->multi_idx, &priv->idx_ip6_routes);
new_best_default_route = NULL;
for (i = 0; i < routes_n; i++) { for (i = 0; i < routes_n; i++) {
const NMNDiscRoute *ndisc_route = &routes[i]; const NMNDiscRoute *ndisc_route = &routes[i];
NMPObject obj; NMPObject obj;
const NMPObject *obj_new;
NMPlatformIP6Route *r; NMPlatformIP6Route *r;
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL); nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
@@ -1798,10 +1845,14 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
FALSE, FALSE,
TRUE, TRUE,
NULL, NULL,
NULL)) &obj_new))
changed = TRUE; changed = TRUE;
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
} }
if (_nm_ip_config_best_default_route_set (&priv->best_default_route, new_best_default_route))
changed = TRUE;
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0) if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)
changed = TRUE; changed = TRUE;
@@ -1815,8 +1866,10 @@ nm_ip6_config_reset_routes (NMIP6Config *self)
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
if (nm_dedup_multi_index_remove_idx (priv->multi_idx, if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
&priv->idx_ip6_routes) > 0) &priv->idx_ip6_routes) > 0) {
nm_clear_nmp_object (&priv->best_default_route);
_notify_routes (self); _notify_routes (self);
}
} }
static void static void
@@ -1826,6 +1879,7 @@ _add_route (NMIP6Config *self,
const NMPObject **out_obj_new) const NMPObject **out_obj_new)
{ {
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
nm_auto_nmpobj const NMPObject *obj_old = NULL;
const NMPObject *obj_new_2; const NMPObject *obj_new_2;
nm_assert ((!new) != (!obj_new)); nm_assert ((!new) != (!obj_new));
@@ -1839,8 +1893,12 @@ _add_route (NMIP6Config *self,
(const NMPlatformObject *) new, (const NMPlatformObject *) new,
TRUE, TRUE,
FALSE, FALSE,
NULL, &obj_old,
&obj_new_2)) { &obj_new_2)) {
if ( priv->best_default_route == obj_old
&& obj_old != obj_new_2)
nm_clear_nmp_object (&priv->best_default_route);
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
_notify_routes (self); _notify_routes (self);
} else } else
@@ -1866,7 +1924,7 @@ nm_ip6_config_add_route (NMIP6Config *self,
{ {
g_return_if_fail (self); g_return_if_fail (self);
g_return_if_fail (new); g_return_if_fail (new);
g_return_if_fail (new->plen > 0 && new->plen <= 128); g_return_if_fail (new->plen <= 128);
g_return_if_fail (NM_IP6_CONFIG_GET_PRIVATE (self)->ifindex > 0); g_return_if_fail (NM_IP6_CONFIG_GET_PRIVATE (self)->ifindex > 0);
_add_route (self, NULL, new, out_obj_new); _add_route (self, NULL, new, out_obj_new);
@@ -1875,18 +1933,12 @@ nm_ip6_config_add_route (NMIP6Config *self,
void void
_nmtst_ip6_config_del_route (NMIP6Config *self, guint i) _nmtst_ip6_config_del_route (NMIP6Config *self, guint i)
{ {
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
const NMPlatformIP6Route *r; const NMPlatformIP6Route *r;
r = _nmtst_ip6_config_get_route (self, i); r = _nmtst_ip6_config_get_route (self, i);
g_return_if_fail (r); if (!nm_ip6_config_nmpobj_remove (self,
NMP_OBJECT_UP_CAST (r)))
if (nm_dedup_multi_index_remove_obj (priv->multi_idx, g_assert_not_reached ();
&priv->idx_ip6_routes,
NMP_OBJECT_UP_CAST (r),
NULL) != 1)
g_return_if_reached ();
_notify_routes (self);
} }
guint guint
@@ -2251,6 +2303,84 @@ nm_ip6_config_get_mss (const NMIP6Config *self)
/*****************************************************************************/ /*****************************************************************************/
const NMPObject *
nm_ip6_config_nmpobj_lookup (const NMIP6Config *self, const NMPObject *needle)
{
const NMIP6ConfigPrivate *priv;
const NMDedupMultiIdxType *idx_type;
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), NULL);
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
switch (NMP_OBJECT_GET_TYPE (needle)) {
case NMP_OBJECT_TYPE_IP6_ADDRESS:
idx_type = &priv->idx_ip6_addresses;
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
idx_type = &priv->idx_ip6_routes;
break;
default:
g_return_val_if_reached (NULL);
}
return nm_dedup_multi_entry_get_obj (nm_dedup_multi_index_lookup_obj (priv->multi_idx,
idx_type,
needle));
}
gboolean
nm_ip6_config_nmpobj_remove (NMIP6Config *self,
const NMPObject *needle)
{
NMIP6ConfigPrivate *priv;
NMDedupMultiIdxType *idx_type;
nm_auto_nmpobj const NMPObject *obj_old = NULL;
guint n;
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), FALSE);
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
switch (NMP_OBJECT_GET_TYPE (needle)) {
case NMP_OBJECT_TYPE_IP6_ADDRESS:
idx_type = &priv->idx_ip6_addresses;
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
idx_type = &priv->idx_ip6_routes;
break;
default:
g_return_val_if_reached (FALSE);
}
n = nm_dedup_multi_index_remove_obj (priv->multi_idx,
idx_type,
needle,
(gconstpointer *) &obj_old);
if (n != 1) {
nm_assert (n == 0);
return FALSE;
}
nm_assert (NMP_OBJECT_GET_TYPE (obj_old) == NMP_OBJECT_GET_TYPE (needle));
switch (NMP_OBJECT_GET_TYPE (obj_old)) {
case NMP_OBJECT_TYPE_IP6_ADDRESS:
_notify_addresses (self);
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
if (priv->best_default_route == obj_old) {
_nm_ip_config_best_default_route_set (&priv->best_default_route,
_nm_ip6_config_best_default_route_find (self));
}
_notify_routes (self);
break;
default:
nm_assert_not_reached ();
}
return TRUE;
}
/*****************************************************************************/
static inline void static inline void
hash_u32 (GChecksum *sum, guint32 n) hash_u32 (GChecksum *sum, guint32 n)
{ {
@@ -2611,6 +2741,8 @@ finalize (GObject *object)
NMIP6Config *self = NM_IP6_CONFIG (object); NMIP6Config *self = NM_IP6_CONFIG (object);
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
nm_clear_nmp_object (&priv->best_default_route);
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_addresses); nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_addresses);
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_routes); nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_routes);

View File

@@ -127,6 +127,9 @@ void nm_ip6_config_set_gateway (NMIP6Config *self, const struct in6_addr *);
const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *self); const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *self);
gint64 nm_ip6_config_get_route_metric (const NMIP6Config *self); gint64 nm_ip6_config_get_route_metric (const NMIP6Config *self);
const NMPObject *nm_ip6_config_best_default_route_get (const NMIP6Config *self);
const NMPObject *_nm_ip6_config_best_default_route_find (const NMIP6Config *self);
const NMDedupMultiHeadEntry *nm_ip6_config_lookup_addresses (const NMIP6Config *self); const NMDedupMultiHeadEntry *nm_ip6_config_lookup_addresses (const NMIP6Config *self);
void nm_ip6_config_reset_addresses (NMIP6Config *self); void nm_ip6_config_reset_addresses (NMIP6Config *self);
void nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *address); void nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *address);
@@ -184,6 +187,11 @@ gint nm_ip6_config_get_dns_priority (const NMIP6Config *self);
void nm_ip6_config_set_mss (NMIP6Config *self, guint32 mss); void nm_ip6_config_set_mss (NMIP6Config *self, guint32 mss);
guint32 nm_ip6_config_get_mss (const NMIP6Config *self); guint32 nm_ip6_config_get_mss (const NMIP6Config *self);
const NMPObject *nm_ip6_config_nmpobj_lookup (const NMIP6Config *self,
const NMPObject *needle);
gboolean nm_ip6_config_nmpobj_remove (NMIP6Config *self,
const NMPObject *needle);
void nm_ip6_config_hash (const NMIP6Config *self, GChecksum *sum, gboolean dns_only); void nm_ip6_config_hash (const NMIP6Config *self, GChecksum *sum, gboolean dns_only);
gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b); gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b);

View File

@@ -192,6 +192,8 @@ get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
} }
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) { nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) {
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
continue;
cidr = g_strdup_printf ("%s/%u", cidr = g_strdup_printf ("%s/%u",
nm_utils_inet4_ntop (routes->network, NULL), nm_utils_inet4_ntop (routes->network, NULL),
routes->plen); routes->plen);
@@ -225,6 +227,8 @@ get_ip6_domains (GPtrArray *domains, NMIP6Config *ip6)
} }
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &routes) { nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &routes) {
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
continue;
cidr = g_strdup_printf ("%s/%u", cidr = g_strdup_printf ("%s/%u",
nm_utils_inet6_ntop (&routes->network, NULL), nm_utils_inet6_ntop (&routes->network, NULL),
routes->plen); routes->plen);