core: add nm_ipX_config_get_direct_route_for_host() functions

add two functions nm_ip4_config_get_direct_route_for_host()
and nm_ip6_config_get_direct_route_for_host() to check if we have
a direct (non-gw) route to a certain host.

Signed-off-by: Thomas Haller <thaller@redhat.com>

https://bugzilla.gnome.org/show_bug.cgi?id=738590
This commit is contained in:
Thomas Haller
2014-08-28 23:36:45 +02:00
parent 22911696f4
commit ff145486d1
6 changed files with 77 additions and 6 deletions

View File

@@ -120,15 +120,15 @@ nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen)
* @src: source ip6 address
* @plen: prefix length of network
*
* Note: this function is self assignment save, to update @src inplace, set both
* Note: this function is self assignment safe, to update @src inplace, set both
* @dst and @src to the same destination.
*/
void
const struct in6_addr *
nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen)
{
g_return_if_fail (plen <= 128);
g_return_if_fail (src);
g_return_if_fail (dst);
g_return_val_if_fail (plen <= 128, NULL);
g_return_val_if_fail (src, NULL);
g_return_val_if_fail (dst, NULL);
if (plen < 128) {
guint nbytes = plen / 8;
@@ -144,6 +144,8 @@ nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_
memset (&dst->s6_addr[nbytes], 0, 16 - nbytes);
} else if (src != dst)
*dst = *src;
return dst;
}

View File

@@ -31,7 +31,7 @@
gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len);
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);
void nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
/**
* nm_utils_ip6_route_metric_normalize:

View File

@@ -1191,6 +1191,36 @@ nm_ip4_config_get_route (const NMIP4Config *config, guint i)
return &g_array_index (priv->routes, NMPlatformIP4Route, i);
}
const NMPlatformIP4Route *
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
int i;
NMPlatformIP4Route *best_route = NULL;
g_return_val_if_fail (host, NULL);
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
if (item->gateway != 0)
continue;
if (best_route && best_route->plen > item->plen)
continue;
if (nm_utils_ip4_address_clear_host_address (host, item->plen) != nm_utils_ip4_address_clear_host_address (item->network, item->plen))
continue;
if (best_route && best_route->metric <= item->metric)
continue;
best_route = item;
}
return best_route;
}
/******************************************************************/
void

View File

@@ -92,6 +92,8 @@ void nm_ip4_config_del_route (NMIP4Config *config, guint i);
guint32 nm_ip4_config_get_num_routes (const NMIP4Config *config);
const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint32 i);
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host);
/* Nameservers */
void nm_ip4_config_reset_nameservers (NMIP4Config *config);
void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver);

View File

@@ -1196,6 +1196,41 @@ nm_ip6_config_get_route (const NMIP6Config *config, guint i)
return &g_array_index (priv->routes, NMPlatformIP6Route, i);
}
const NMPlatformIP6Route *
nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
int i;
struct in6_addr network2, host2;
NMPlatformIP6Route *best_route = NULL;
g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL);
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i);
if (!IN6_IS_ADDR_UNSPECIFIED (&item->gateway))
continue;
if (best_route && best_route->plen > item->plen)
continue;
nm_utils_ip6_address_clear_host_address (&host2, host, item->plen);
nm_utils_ip6_address_clear_host_address (&network2, &item->network, item->plen);
if (!IN6_ARE_ADDR_EQUAL (&network2, &host2))
continue;
if (best_route &&
nm_utils_ip6_route_metric_normalize (best_route->metric) <= nm_utils_ip6_route_metric_normalize (item->metric))
continue;
best_route = item;
}
return best_route;
}
/******************************************************************/
void

View File

@@ -93,6 +93,8 @@ void nm_ip6_config_del_route (NMIP6Config *config, guint i);
guint32 nm_ip6_config_get_num_routes (const NMIP6Config *config);
const NMPlatformIP6Route *nm_ip6_config_get_route (const NMIP6Config *config, guint32 i);
const NMPlatformIP6Route *nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host);
/* Nameservers */
void nm_ip6_config_reset_nameservers (NMIP6Config *config);
void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *nameserver);