diff options
Diffstat (limited to 'src/nm-ip6-config.c')
-rw-r--r-- | src/nm-ip6-config.c | 217 |
1 files changed, 166 insertions, 51 deletions
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index db64e72618..a148d826e6 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -653,6 +653,85 @@ nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6 return FALSE; } +/*******************************************************************************/ + +static int +_addresses_get_index (const NMIP6Config *self, const NMPlatformIP6Address *addr) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->addresses->len; i++) { + const NMPlatformIP6Address *a = &g_array_index (priv->addresses, NMPlatformIP6Address, i); + + if (IN6_ARE_ADDR_EQUAL (&addr->address, &a->address)) + return (int) i; + } + return -1; +} + +static int +_nameservers_get_index (const NMIP6Config *self, const struct in6_addr *ns) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->nameservers->len; i++) { + const struct in6_addr *n = &g_array_index (priv->nameservers, struct in6_addr, i); + + if (IN6_ARE_ADDR_EQUAL (ns, n)) + return (int) i; + } + return -1; +} + +static int +_routes_get_index (const NMIP6Config *self, const NMPlatformIP6Route *route) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->routes->len; i++) { + const NMPlatformIP6Route *r = &g_array_index (priv->routes, NMPlatformIP6Route, i); + + if (routes_are_duplicate (route, r, FALSE)) + return (int) i; + } + return -1; +} + +static int +_domains_get_index (const NMIP6Config *self, const char *domain) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->domains->len; i++) { + const char *d = g_ptr_array_index (priv->domains, i); + + if (g_strcmp0 (domain, d) == 0) + return (int) i; + } + return -1; +} + +static int +_searches_get_index (const NMIP6Config *self, const char *search) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->searches->len; i++) { + const char *s = g_ptr_array_index (priv->searches, i); + + if (g_strcmp0 (search, s) == 0) + return (int) i; + } + return -1; +} + +/*******************************************************************************/ + /** * nm_ip6_config_subtract: * @dst: config from which to remove everything in @src @@ -663,7 +742,8 @@ nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6 void nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) { - guint32 i, j; + guint i; + gint idx; const struct in6_addr *dst_tmp, *src_tmp; g_return_if_fail (src != NULL); @@ -673,30 +753,16 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) /* addresses */ for (i = 0; i < nm_ip6_config_get_num_addresses (src); i++) { - const NMPlatformIP6Address *src_addr = nm_ip6_config_get_address (src, i); - - for (j = 0; j < nm_ip6_config_get_num_addresses (dst); j++) { - const NMPlatformIP6Address *dst_addr = nm_ip6_config_get_address (dst, j); - - if (IN6_ARE_ADDR_EQUAL (&src_addr->address, &dst_addr->address)) { - nm_ip6_config_del_address (dst, j); - break; - } - } + idx = _addresses_get_index (dst, nm_ip6_config_get_address (src, i)); + if (idx >= 0) + nm_ip6_config_del_address (dst, idx); } /* nameservers */ for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++) { - const struct in6_addr *src_ns = nm_ip6_config_get_nameserver (src, i); - - for (j = 0; j < nm_ip6_config_get_num_nameservers (dst); j++) { - const struct in6_addr *dst_ns = nm_ip6_config_get_nameserver (dst, j); - - if (IN6_ARE_ADDR_EQUAL (src_ns, dst_ns)) { - nm_ip6_config_del_nameserver (dst, j); - break; - } - } + idx = _nameservers_get_index (dst, nm_ip6_config_get_nameserver (src, i)); + if (idx >= 0) + nm_ip6_config_del_nameserver (dst, idx); } /* default gateway */ @@ -710,44 +776,23 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) /* routes */ for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) { - const NMPlatformIP6Route *src_route = nm_ip6_config_get_route (src, i); - - for (j = 0; j < nm_ip6_config_get_num_routes (dst); j++) { - const NMPlatformIP6Route *dst_route = nm_ip6_config_get_route (dst, j); - - if (routes_are_duplicate (src_route, dst_route, FALSE)) { - nm_ip6_config_del_route (dst, j); - break; - } - } + idx = _routes_get_index (dst, nm_ip6_config_get_route (src, i)); + if (idx >= 0) + nm_ip6_config_del_route (dst, idx); } /* domains */ for (i = 0; i < nm_ip6_config_get_num_domains (src); i++) { - const char *src_domain = nm_ip6_config_get_domain (src, i); - - for (j = 0; j < nm_ip6_config_get_num_domains (dst); j++) { - const char *dst_domain = nm_ip6_config_get_domain (dst, j); - - if (g_strcmp0 (src_domain, dst_domain) == 0) { - nm_ip6_config_del_domain (dst, j); - break; - } - } + idx = _domains_get_index (dst, nm_ip6_config_get_domain (src, i)); + if (idx >= 0) + nm_ip6_config_del_domain (dst, idx); } /* dns searches */ for (i = 0; i < nm_ip6_config_get_num_searches (src); i++) { - const char *src_search = nm_ip6_config_get_search (src, i); - - for (j = 0; j < nm_ip6_config_get_num_searches (dst); j++) { - const char *dst_search = nm_ip6_config_get_search (dst, j); - - if (g_strcmp0 (src_search, dst_search) == 0) { - nm_ip6_config_del_search (dst, j); - break; - } - } + idx = _searches_get_index (dst, nm_ip6_config_get_search (src, i)); + if (idx >= 0) + nm_ip6_config_del_search (dst, idx); } if (nm_ip6_config_get_mss (src) == nm_ip6_config_get_mss (dst)) @@ -756,6 +801,76 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) g_object_thaw_notify (G_OBJECT (dst)); } +void +nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src) +{ + guint i; + gint idx; + const struct in6_addr *dst_tmp, *src_tmp; + + g_return_if_fail (src != NULL); + g_return_if_fail (dst != NULL); + + g_object_freeze_notify (G_OBJECT (dst)); + + /* addresses */ + for (i = 0; i < nm_ip6_config_get_num_addresses (dst); ) { + idx = _addresses_get_index (src, nm_ip6_config_get_address (dst, i)); + if (idx < 0) + nm_ip6_config_del_address (dst, i); + else + i++; + } + + /* nameservers */ + for (i = 0; i < nm_ip6_config_get_num_nameservers (dst); ) { + idx = _nameservers_get_index (src, nm_ip6_config_get_nameserver (dst, i)); + if (idx < 0) + nm_ip6_config_del_nameserver (dst, i); + else + i++; + } + + /* default gateway */ + dst_tmp = nm_ip6_config_get_gateway (dst); + if (dst_tmp) { + src_tmp = nm_ip6_config_get_gateway (src); + if ( !nm_ip6_config_get_num_addresses (dst) + || !src_tmp + || !IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp)) + nm_ip6_config_set_gateway (dst, NULL); + } + + /* routes */ + for (i = 0; i < nm_ip6_config_get_num_routes (dst); ) { + idx = _routes_get_index (src, nm_ip6_config_get_route (dst, i)); + if (idx < 0) + nm_ip6_config_del_route (dst, i); + else + i++; + } + + /* domains */ + for (i = 0; i < nm_ip6_config_get_num_domains (src); ) { + idx = _domains_get_index (src, nm_ip6_config_get_domain (dst, i)); + if (idx < 0) + nm_ip6_config_del_domain (dst, i); + else + i++; + } + + /* dns searches */ + for (i = 0; i < nm_ip6_config_get_num_searches (src); i++) { + idx = _searches_get_index (src, nm_ip6_config_get_search (dst, i)); + if (idx < 0) + nm_ip6_config_del_search (dst, i); + else + i++; + } + + g_object_thaw_notify (G_OBJECT (dst)); +} + /** * nm_ip6_config_replace: * @dst: config which will be replaced with everything in @src |