core: add non-destructive ip config intersect function
Add a new function to compute the intersection between 2 IP configurations without modifying them.
This commit is contained in:
@@ -1477,10 +1477,11 @@ nm_ip4_config_subtract (NMIP4Config *dst,
|
|||||||
g_object_thaw_notify (G_OBJECT (dst));
|
g_object_thaw_notify (G_OBJECT (dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static gboolean
|
||||||
nm_ip4_config_intersect (NMIP4Config *dst,
|
_nm_ip4_config_intersect_helper (NMIP4Config *dst,
|
||||||
const NMIP4Config *src,
|
const NMIP4Config *src,
|
||||||
guint32 default_route_metric_penalty)
|
guint32 default_route_metric_penalty,
|
||||||
|
gboolean update_dst)
|
||||||
{
|
{
|
||||||
NMIP4ConfigPrivate *dst_priv;
|
NMIP4ConfigPrivate *dst_priv;
|
||||||
const NMIP4ConfigPrivate *src_priv;
|
const NMIP4ConfigPrivate *src_priv;
|
||||||
@@ -1488,15 +1489,16 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
|||||||
const NMPlatformIP4Address *a;
|
const NMPlatformIP4Address *a;
|
||||||
const NMPlatformIP4Route *r;
|
const NMPlatformIP4Route *r;
|
||||||
const NMPObject *new_best_default_route;
|
const NMPObject *new_best_default_route;
|
||||||
gboolean changed;
|
gboolean changed, result = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (src);
|
g_return_val_if_fail (src, FALSE);
|
||||||
g_return_if_fail (dst);
|
g_return_val_if_fail (dst, FALSE);
|
||||||
|
|
||||||
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));
|
if (update_dst)
|
||||||
|
g_object_freeze_notify (G_OBJECT (dst));
|
||||||
|
|
||||||
/* addresses */
|
/* addresses */
|
||||||
changed = FALSE;
|
changed = FALSE;
|
||||||
@@ -1506,13 +1508,18 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
|||||||
NMP_OBJECT_UP_CAST (a)))
|
NMP_OBJECT_UP_CAST (a)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!update_dst)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
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 (changed)
|
if (changed) {
|
||||||
_notify_addresses (dst);
|
_notify_addresses (dst);
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignore nameservers */
|
/* ignore nameservers */
|
||||||
|
|
||||||
@@ -1544,6 +1551,9 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!update_dst)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
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 ();
|
||||||
@@ -1553,8 +1563,11 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
|||||||
nm_assert (changed);
|
nm_assert (changed);
|
||||||
_notify (dst, PROP_GATEWAY);
|
_notify (dst, PROP_GATEWAY);
|
||||||
}
|
}
|
||||||
if (changed)
|
|
||||||
|
if (changed) {
|
||||||
_notify_routes (dst);
|
_notify_routes (dst);
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignore domains */
|
/* ignore domains */
|
||||||
/* ignore dns searches */
|
/* ignore dns searches */
|
||||||
@@ -1562,9 +1575,58 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
|||||||
/* ignore NIS */
|
/* ignore NIS */
|
||||||
/* ignore WINS */
|
/* ignore WINS */
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (dst));
|
if (update_dst)
|
||||||
|
g_object_thaw_notify (G_OBJECT (dst));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip4_config_intersect:
|
||||||
|
* @dst: a configuration to be updated
|
||||||
|
* @src: another configuration
|
||||||
|
* @default_route_metric_penalty: the default route metric penalty
|
||||||
|
*
|
||||||
|
* Computes the intersection between @src and @dst and updates @dst in place
|
||||||
|
* with the result.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nm_ip4_config_intersect (NMIP4Config *dst,
|
||||||
|
const NMIP4Config *src,
|
||||||
|
guint32 default_route_metric_penalty)
|
||||||
|
{
|
||||||
|
_nm_ip4_config_intersect_helper (dst, src, default_route_metric_penalty, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip4_config_intersect_alloc:
|
||||||
|
* @a: a configuration
|
||||||
|
* @b: another configuration
|
||||||
|
* @default_route_metric_penalty: the default route metric penalty
|
||||||
|
*
|
||||||
|
* Computes the intersection between @a and @b and returns the result in a newly
|
||||||
|
* allocated configuration. As a special case, if @a and @b are identical (with
|
||||||
|
* respect to the only properties considered - addresses and routes) the
|
||||||
|
* functions returns NULL so that one of existing configuration can be reused
|
||||||
|
* without allocation.
|
||||||
|
*
|
||||||
|
* Returns: the intersection between @a and @b, or %NULL if the result is equal
|
||||||
|
* to @a and @b.
|
||||||
|
*/
|
||||||
|
NMIP4Config *
|
||||||
|
nm_ip4_config_intersect_alloc (const NMIP4Config *a,
|
||||||
|
const NMIP4Config *b,
|
||||||
|
guint32 default_route_metric_penalty)
|
||||||
|
{
|
||||||
|
NMIP4Config *a_copy;
|
||||||
|
|
||||||
|
if (_nm_ip4_config_intersect_helper ((NMIP4Config *) a, b,
|
||||||
|
default_route_metric_penalty, FALSE)) {
|
||||||
|
a_copy = nm_ip4_config_clone (a);
|
||||||
|
_nm_ip4_config_intersect_helper (a_copy, b, default_route_metric_penalty, TRUE);
|
||||||
|
return a_copy;
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_ip4_config_replace:
|
* nm_ip4_config_replace:
|
||||||
|
@@ -187,6 +187,9 @@ void nm_ip4_config_subtract (NMIP4Config *dst,
|
|||||||
void nm_ip4_config_intersect (NMIP4Config *dst,
|
void nm_ip4_config_intersect (NMIP4Config *dst,
|
||||||
const NMIP4Config *src,
|
const NMIP4Config *src,
|
||||||
guint32 default_route_metric_penalty);
|
guint32 default_route_metric_penalty);
|
||||||
|
NMIP4Config *nm_ip4_config_intersect_alloc (const NMIP4Config *a,
|
||||||
|
const NMIP4Config *b,
|
||||||
|
guint32 default_route_metric_penalty);
|
||||||
gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes);
|
gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes);
|
||||||
void nm_ip4_config_dump (const NMIP4Config *self, const char *detail);
|
void nm_ip4_config_dump (const NMIP4Config *self, const char *detail);
|
||||||
|
|
||||||
@@ -455,4 +458,23 @@ nm_ip_config_merge (NMIPConfig *dst,
|
|||||||
default_route_metric_penalty);
|
default_route_metric_penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline NMIPConfig *
|
||||||
|
nm_ip_config_intersect_alloc (const NMIPConfig *a,
|
||||||
|
const NMIPConfig *b,
|
||||||
|
guint32 default_route_metric_penalty)
|
||||||
|
{
|
||||||
|
int family;
|
||||||
|
|
||||||
|
family = nm_ip_config_get_addr_family (a);
|
||||||
|
nm_assert (family == nm_ip_config_get_addr_family (b));
|
||||||
|
|
||||||
|
if (family == AF_INET)
|
||||||
|
return (NMIPConfig *) nm_ip4_config_intersect_alloc ((const NMIP4Config *) a,
|
||||||
|
(const NMIP4Config *) b,
|
||||||
|
default_route_metric_penalty);
|
||||||
|
else
|
||||||
|
return (NMIPConfig *) nm_ip6_config_intersect_alloc ((const NMIP6Config *) a,
|
||||||
|
(const NMIP6Config *) b,
|
||||||
|
default_route_metric_penalty);
|
||||||
|
}
|
||||||
#endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */
|
#endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */
|
||||||
|
@@ -1081,26 +1081,28 @@ nm_ip6_config_subtract (NMIP6Config *dst,
|
|||||||
g_object_thaw_notify (G_OBJECT (dst));
|
g_object_thaw_notify (G_OBJECT (dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static gboolean
|
||||||
nm_ip6_config_intersect (NMIP6Config *dst,
|
_nm_ip6_config_intersect_helper (NMIP6Config *dst,
|
||||||
const NMIP6Config *src,
|
const NMIP6Config *src,
|
||||||
guint32 default_route_metric_penalty)
|
guint32 default_route_metric_penalty,
|
||||||
|
gboolean update_dst)
|
||||||
{
|
{
|
||||||
NMIP6ConfigPrivate *dst_priv;
|
NMIP6ConfigPrivate *dst_priv;
|
||||||
const NMIP6ConfigPrivate *src_priv;
|
const NMIP6ConfigPrivate *src_priv;
|
||||||
NMDedupMultiIter ipconf_iter;
|
NMDedupMultiIter ipconf_iter;
|
||||||
const NMPlatformIP6Address *a;
|
const NMPlatformIP6Address *a;
|
||||||
const NMPlatformIP6Route *r;
|
const NMPlatformIP6Route *r;
|
||||||
gboolean changed;
|
gboolean changed, result = FALSE;
|
||||||
const NMPObject *new_best_default_route;
|
const NMPObject *new_best_default_route;
|
||||||
|
|
||||||
g_return_if_fail (src);
|
g_return_val_if_fail (src, FALSE);
|
||||||
g_return_if_fail (dst);
|
g_return_val_if_fail (dst, FALSE);
|
||||||
|
|
||||||
dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst);
|
dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst);
|
||||||
src_priv = NM_IP6_CONFIG_GET_PRIVATE (src);
|
src_priv = NM_IP6_CONFIG_GET_PRIVATE (src);
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (dst));
|
if (update_dst)
|
||||||
|
g_object_freeze_notify (G_OBJECT (dst));
|
||||||
|
|
||||||
/* addresses */
|
/* addresses */
|
||||||
changed = FALSE;
|
changed = FALSE;
|
||||||
@@ -1110,13 +1112,18 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
|||||||
NMP_OBJECT_UP_CAST (a)))
|
NMP_OBJECT_UP_CAST (a)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!update_dst)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
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 (changed)
|
if (changed) {
|
||||||
_notify_addresses (dst);
|
_notify_addresses (dst);
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignore nameservers */
|
/* ignore nameservers */
|
||||||
|
|
||||||
@@ -1148,6 +1155,9 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!update_dst)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
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 ();
|
||||||
@@ -1157,14 +1167,67 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
|||||||
nm_assert (changed);
|
nm_assert (changed);
|
||||||
_notify (dst, PROP_GATEWAY);
|
_notify (dst, PROP_GATEWAY);
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed) {
|
||||||
_notify_routes (dst);
|
_notify_routes (dst);
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignore domains */
|
/* ignore domains */
|
||||||
/* ignore dns searches */
|
/* ignore dns searches */
|
||||||
/* ignore dns options */
|
/* ignore dns options */
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (dst));
|
if (update_dst)
|
||||||
|
g_object_thaw_notify (G_OBJECT (dst));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_intersect:
|
||||||
|
* @dst: a configuration to be updated
|
||||||
|
* @src: another configuration
|
||||||
|
* @default_route_metric_penalty: the default route metric penalty
|
||||||
|
*
|
||||||
|
* Computes the intersection between @src and @dst and updates @dst in place
|
||||||
|
* with the result.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nm_ip6_config_intersect (NMIP6Config *dst,
|
||||||
|
const NMIP6Config *src,
|
||||||
|
guint32 default_route_metric_penalty)
|
||||||
|
{
|
||||||
|
_nm_ip6_config_intersect_helper (dst, src, default_route_metric_penalty, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_intersect_alloc:
|
||||||
|
* @a: a configuration
|
||||||
|
* @b: another configuration
|
||||||
|
* @default_route_metric_penalty: the default route metric penalty
|
||||||
|
*
|
||||||
|
* Computes the intersection between @a and @b and returns the result in a newly
|
||||||
|
* allocated configuration. As a special case, if @a and @b are identical (with
|
||||||
|
* respect to the only properties considered - addresses and routes) the
|
||||||
|
* functions returns NULL so that one of existing configuration can be reused
|
||||||
|
* without allocation.
|
||||||
|
*
|
||||||
|
* Returns: the intersection between @a and @b, or %NULL if the result is equal
|
||||||
|
* to @a and @b.
|
||||||
|
*/
|
||||||
|
NMIP6Config *
|
||||||
|
nm_ip6_config_intersect_alloc (const NMIP6Config *a,
|
||||||
|
const NMIP6Config *b,
|
||||||
|
guint32 default_route_metric_penalty)
|
||||||
|
{
|
||||||
|
NMIP6Config *a_copy;
|
||||||
|
|
||||||
|
if (_nm_ip6_config_intersect_helper ((NMIP6Config *) a, b,
|
||||||
|
default_route_metric_penalty, FALSE)) {
|
||||||
|
a_copy = nm_ip6_config_clone (a);
|
||||||
|
_nm_ip6_config_intersect_helper (a_copy, b, default_route_metric_penalty, TRUE);
|
||||||
|
return a_copy;
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -134,6 +134,9 @@ void nm_ip6_config_subtract (NMIP6Config *dst,
|
|||||||
void nm_ip6_config_intersect (NMIP6Config *dst,
|
void nm_ip6_config_intersect (NMIP6Config *dst,
|
||||||
const NMIP6Config *src,
|
const NMIP6Config *src,
|
||||||
guint32 default_route_metric_penalty);
|
guint32 default_route_metric_penalty);
|
||||||
|
NMIP6Config *nm_ip6_config_intersect_alloc (const NMIP6Config *a,
|
||||||
|
const NMIP6Config *b,
|
||||||
|
guint32 default_route_metric_penalty);
|
||||||
gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes);
|
gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes);
|
||||||
void nm_ip6_config_dump (const NMIP6Config *self, const char *detail);
|
void nm_ip6_config_dump (const NMIP6Config *self, const char *detail);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user