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));
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
static gboolean
|
||||
_nm_ip4_config_intersect_helper (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty,
|
||||
gboolean update_dst)
|
||||
{
|
||||
NMIP4ConfigPrivate *dst_priv;
|
||||
const NMIP4ConfigPrivate *src_priv;
|
||||
@@ -1488,15 +1489,16 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
const NMPlatformIP4Address *a;
|
||||
const NMPlatformIP4Route *r;
|
||||
const NMPObject *new_best_default_route;
|
||||
gboolean changed;
|
||||
gboolean changed, result = FALSE;
|
||||
|
||||
g_return_if_fail (src);
|
||||
g_return_if_fail (dst);
|
||||
g_return_val_if_fail (src, FALSE);
|
||||
g_return_val_if_fail (dst, FALSE);
|
||||
|
||||
dst_priv = NM_IP4_CONFIG_GET_PRIVATE (dst);
|
||||
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 */
|
||||
changed = FALSE;
|
||||
@@ -1506,13 +1508,18 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
NMP_OBJECT_UP_CAST (a)))
|
||||
continue;
|
||||
|
||||
if (!update_dst)
|
||||
return TRUE;
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (changed)
|
||||
if (changed) {
|
||||
_notify_addresses (dst);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
/* ignore nameservers */
|
||||
|
||||
@@ -1544,6 +1551,9 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!update_dst)
|
||||
return TRUE;
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
@@ -1553,8 +1563,11 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
nm_assert (changed);
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
|
||||
if (changed) {
|
||||
_notify_routes (dst);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
/* ignore domains */
|
||||
/* ignore dns searches */
|
||||
@@ -1562,9 +1575,58 @@ nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
/* ignore NIS */
|
||||
/* 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:
|
||||
|
@@ -187,6 +187,9 @@ void nm_ip4_config_subtract (NMIP4Config *dst,
|
||||
void nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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__ */
|
||||
|
@@ -1081,26 +1081,28 @@ nm_ip6_config_subtract (NMIP6Config *dst,
|
||||
g_object_thaw_notify (G_OBJECT (dst));
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
static gboolean
|
||||
_nm_ip6_config_intersect_helper (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty,
|
||||
gboolean update_dst)
|
||||
{
|
||||
NMIP6ConfigPrivate *dst_priv;
|
||||
const NMIP6ConfigPrivate *src_priv;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP6Address *a;
|
||||
const NMPlatformIP6Route *r;
|
||||
gboolean changed;
|
||||
gboolean changed, result = FALSE;
|
||||
const NMPObject *new_best_default_route;
|
||||
|
||||
g_return_if_fail (src);
|
||||
g_return_if_fail (dst);
|
||||
g_return_val_if_fail (src, FALSE);
|
||||
g_return_val_if_fail (dst, FALSE);
|
||||
|
||||
dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst);
|
||||
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 */
|
||||
changed = FALSE;
|
||||
@@ -1110,13 +1112,18 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
NMP_OBJECT_UP_CAST (a)))
|
||||
continue;
|
||||
|
||||
if (!update_dst)
|
||||
return TRUE;
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (changed)
|
||||
if (changed) {
|
||||
_notify_addresses (dst);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
/* ignore nameservers */
|
||||
|
||||
@@ -1148,6 +1155,9 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!update_dst)
|
||||
return TRUE;
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
@@ -1157,14 +1167,67 @@ nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
nm_assert (changed);
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
if (changed) {
|
||||
_notify_routes (dst);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
/* ignore domains */
|
||||
/* ignore dns searches */
|
||||
/* 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,
|
||||
const NMIP6Config *src,
|
||||
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);
|
||||
void nm_ip6_config_dump (const NMIP6Config *self, const char *detail);
|
||||
|
||||
|
Reference in New Issue
Block a user