core: use NMIP[46]Route in nm-ip[46]-config

This commit is contained in:
Pavel Šimerda 2013-07-31 23:07:32 +02:00 committed by Dan Williams
parent 7570832b20
commit 6762b2f792
10 changed files with 301 additions and 301 deletions

View file

@ -2022,7 +2022,7 @@ aipd_get_ip4_config (NMDevice *self, struct in_addr lla)
{
NMIP4Config *config = NULL;
NMPlatformIP4Address address;
NMIP4Route *route;
NMPlatformIP4Route route;
config = nm_ip4_config_new ();
g_assert (config);
@ -2033,14 +2033,12 @@ aipd_get_ip4_config (NMDevice *self, struct in_addr lla)
nm_ip4_config_add_address (config, &address);
/* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, (guint32) htonl (0xE0000000L));
nm_ip4_route_set_prefix (route, 4);
nm_ip4_route_set_next_hop (route, (guint32) 0);
nm_ip4_route_set_metric (route, 0);
nm_ip4_config_take_route (config, route);
memset (&route, 0, sizeof (route));
route.network = htonl (0xE0000000L);
route.plen = 4;
nm_ip4_config_add_route (config, &route);
return config;
return config;
}
#define IPV4LL_NETWORK (htonl (0xA9FE0000L))
@ -2969,13 +2967,14 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
for (i = 0; i < rdisc->routes->len; i++) {
NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
NMIP6Route *route = nm_ip6_route_new ();
NMPlatformIP6Route route;
nm_ip6_route_set_dest (route, &discovered_route->network);
nm_ip6_route_set_prefix (route, discovered_route->plen);
nm_ip6_route_set_next_hop (route, &discovered_route->gateway);
memset (&route, 0, sizeof (route));
route.network = discovered_route->network;
route.plen = discovered_route->plen;
route.gateway = discovered_route->gateway;
nm_ip6_config_take_route (priv->ac_ip6_config, route);
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
}
}

View file

@ -831,7 +831,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str,
for (r = routes; *r; r += 2) {
char *slash;
NMIP4Route *route;
NMPlatformIP4Route route;
int rt_cidr = 32;
struct in_addr rt_addr;
struct in_addr rt_route;
@ -860,13 +860,12 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str,
/* FIXME: how to handle multiple routers? */
*gwaddr = rt_route.s_addr;
} else {
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
nm_ip4_route_set_prefix (route, rt_cidr);
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
nm_ip4_config_take_route (ip4_config, route);
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
memset (&route, 0, sizeof (route));
route.network = rt_addr.s_addr;
route.plen = rt_cidr;
route.gateway = rt_route.s_addr;
nm_ip4_config_add_route (ip4_config, &route);
}
}
@ -876,15 +875,16 @@ out:
}
static const char **
process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
process_dhclient_rfc3442_route (const char **octets, NMPlatformIP4Route *route, gboolean *success)
{
const char **o = octets;
int addr_len = 0, i = 0;
long int tmp;
NMIP4Route *route;
char *next_hop;
struct in_addr tmp_addr;
*success = FALSE;
if (!*o)
return o; /* no prefix */
@ -892,8 +892,8 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
return o;
route = nm_ip4_route_new ();
nm_ip4_route_set_prefix (route, (guint32) tmp);
memset (route, 0, sizeof (*route));
route->plen = tmp;
o++;
if (tmp > 0)
@ -916,7 +916,7 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
goto error;
}
tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp);
nm_ip4_route_set_dest (route, tmp_addr.s_addr);
route->network = tmp_addr.s_addr;
}
/* Handle next hop */
@ -925,14 +925,13 @@ process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
g_free (next_hop);
goto error;
}
nm_ip4_route_set_next_hop (route, tmp_addr.s_addr);
route->gateway = tmp_addr.s_addr;
g_free (next_hop);
*out_route = route;
*success = TRUE;
return o + 4; /* advance to past the next hop */
error:
nm_ip4_route_unref (route);
return o;
}
@ -943,7 +942,8 @@ ip4_process_dhclient_rfc3442_routes (const char *str,
{
char **octets, **o;
gboolean have_routes = FALSE;
NMIP4Route *route = NULL;
NMPlatformIP4Route route;
gboolean success;
o = octets = g_strsplit_set (str, " .", 0);
if (g_strv_length (octets) < 5) {
@ -952,32 +952,28 @@ ip4_process_dhclient_rfc3442_routes (const char *str,
}
while (*o) {
route = NULL;
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route);
if (!route) {
memset (&route, 0, sizeof (route));
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success);
if (!success) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes");
break;
}
have_routes = TRUE;
if (nm_ip4_route_get_prefix (route) == 0) {
if (!route.plen) {
/* gateway passed as classless static route */
*gwaddr = nm_ip4_route_get_next_hop (route);
nm_ip4_route_unref (route);
*gwaddr = route.gateway;
} else {
char addr[INET_ADDRSTRLEN + 1];
char nh[INET_ADDRSTRLEN + 1];
struct in_addr tmp;
/* normal route */
nm_ip4_config_take_route (ip4_config, route);
nm_ip4_config_add_route (ip4_config, &route);
tmp.s_addr = nm_ip4_route_get_dest (route);
inet_ntop (AF_INET, &tmp, addr, sizeof (addr));
tmp.s_addr = nm_ip4_route_get_next_hop (route);
inet_ntop (AF_INET, &tmp, nh, sizeof (nh));
inet_ntop (AF_INET, &route.network, addr, sizeof (addr));
inet_ntop (AF_INET, &route.gateway, nh, sizeof (nh));
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
addr, nm_ip4_route_get_prefix (route), nh);
addr, route.plen, nh);
}
}
@ -1066,7 +1062,7 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
}
for (s = searches; *s; s += 2) {
NMIP4Route *route;
NMPlatformIP4Route route;
struct in_addr rt_addr;
struct in_addr rt_route;
@ -1081,12 +1077,12 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
// FIXME: ensure the IP addresse and route are sane
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
nm_ip4_route_set_prefix (route, 32); /* 255.255.255.255 */
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
memset (&route, 0, sizeof (route));
route.network = rt_addr.s_addr;
route.plen = 32;
route.gateway = rt_route.s_addr;
nm_ip4_config_take_route (ip4_config, route);
nm_ip4_config_add_route (ip4_config, &route);
nm_log_info (LOGD_DHCP, " static route %s gw %s", *s, *(s + 1));
}

View file

@ -85,9 +85,9 @@ nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4)
}
for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) {
NMIP4Route *route = nm_ip4_config_get_route (ip4, i);
NMPlatformIP4Route *route = nm_ip4_config_get_route (ip4, i);
add_ip4_to_rdns_array (nm_ip4_route_get_dest (route), domains);
add_ip4_to_rdns_array (route->network, domains);
}
/* Terminating NULL so we can use g_strfreev() to free it */

View file

@ -41,7 +41,7 @@ typedef struct {
gboolean never_default;
guint32 gateway;
GArray *addresses;
GSList *routes;
GArray *routes;
GArray *nameservers;
GPtrArray *domains;
GPtrArray *searches;
@ -109,13 +109,12 @@ nm_ip4_config_capture (int ifindex)
{
NMIP4Config *config = nm_ip4_config_new ();
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
GArray *routes_array;
NMPlatformIP4Route *routes;
NMIP4Route *route;
int i;
g_array_unref (priv->addresses);
g_array_unref (priv->routes);
priv->addresses = nm_platform_ip4_address_get_all (ifindex);
priv->routes = nm_platform_ip4_route_get_all (ifindex, FALSE);
/* Require at least one IP address. */
if (!priv->addresses->len) {
@ -123,18 +122,6 @@ nm_ip4_config_capture (int ifindex)
return NULL;
}
routes_array = nm_platform_ip4_route_get_all (ifindex, FALSE);
routes = (NMPlatformIP4Route *)routes_array->data;
for (i = 0; i < routes_array->len; i++) {
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, routes[i].network);
nm_ip4_route_set_prefix (route, routes[i].plen);
nm_ip4_route_set_next_hop (route, routes[i].gateway);
nm_ip4_route_set_metric (route, routes[i].metric);
nm_ip4_config_take_route (config, route);
}
g_array_unref (routes_array);
return config;
}
@ -154,16 +141,11 @@ nm_ip4_config_commit (NMIP4Config *config, int ifindex, int priority)
/* Routes */
{
int count = nm_ip4_config_get_num_routes (config);
NMIP4Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count);
NMPlatformIP4Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip4_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = nm_ip4_route_get_dest (config_route);
route.plen = nm_ip4_route_get_prefix (config_route);
route.gateway = nm_ip4_route_get_next_hop (config_route);
memcpy (&route, nm_ip4_config_get_route (config, i), sizeof (route));
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
@ -237,8 +219,18 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting)
/* Routes */
if (nm_setting_ip4_config_get_ignore_auto_routes (setting))
nm_ip4_config_reset_routes (config);
for (i = 0; i < nroutes; i++)
nm_ip4_config_add_route (config, nm_setting_ip4_config_get_route (setting, i));
for (i = 0; i < nroutes; i++) {
NMIP4Route *s_route = nm_setting_ip4_config_get_route (setting, i);
NMPlatformIP4Route route;
memset (&route, 0, sizeof (route));
route.network = nm_ip4_route_get_dest (s_route);
route.plen = nm_ip4_route_get_prefix (s_route);
route.gateway = nm_ip4_route_get_next_hop (s_route);
route.metric = nm_ip4_route_get_metric (s_route);
nm_ip4_config_add_route (config, &route);
}
/* DNS */
if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) {
@ -300,13 +292,19 @@ nm_ip4_config_update_setting (NMIP4Config *config, NMSettingIP4Config *setting)
/* Routes */
for (i = 0; i < nroutes; i++) {
NMIP4Route *route = nm_ip4_config_get_route (config, i);
NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
gs_unref_object NMIP4Route *s_route = nm_ip4_route_new ();
/* Ignore default route. */
if (!nm_ip4_route_get_prefix (route))
if (!route->plen)
continue;
nm_setting_ip4_config_add_route (setting, route);
nm_ip4_route_set_dest (s_route, route->network);
nm_ip4_route_set_prefix (s_route, route->plen);
nm_ip4_route_set_next_hop (s_route, route->gateway);
nm_ip4_route_set_metric (s_route, route->metric);
nm_setting_ip4_config_add_route (setting, s_route);
}
/* DNS */
@ -430,12 +428,12 @@ nm_ip4_config_subtract (NMIP4Config *dst, NMIP4Config *src)
/* routes */
for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) {
NMIP4Route *src_route = nm_ip4_config_get_route (src, i);
NMPlatformIP4Route *src_route = nm_ip4_config_get_route (src, i);
for (j = 0; j < nm_ip4_config_get_num_routes (dst); j++) {
NMIP4Route *dst_route = nm_ip4_config_get_route (dst, j);
NMPlatformIP4Route *dst_route = nm_ip4_config_get_route (dst, j);
if (nm_ip4_route_compare (src_route, dst_route)) {
if (src_route->network == dst_route->network && src_route->plen == dst_route->plen) {
nm_ip4_config_del_route (dst, j);
break;
}
@ -545,15 +543,12 @@ nm_ip4_config_dump (NMIP4Config *config, const char *detail)
/* routes */
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
NMIP4Route *route = nm_ip4_config_get_route (config, i);
guint dest = nm_ip4_route_get_dest (route);
guint nh = nm_ip4_route_get_next_hop (route);
NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
if (inet_ntop (AF_INET, (void *) &dest, buf, sizeof (buf)) &&
inet_ntop (AF_INET, (void *) &nh, buf2, sizeof (buf2))) {
if (inet_ntop (AF_INET, &route->network, buf, sizeof (buf)) &&
inet_ntop (AF_INET, &route->gateway, buf2, sizeof (buf2))) {
g_message (" rt: %s/%u via %s metric:%u",
buf, nm_ip4_route_get_prefix (route), buf2,
nm_ip4_route_get_metric (route));
buf, route->plen, buf2, route->metric);
}
}
@ -705,74 +700,43 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref);
priv->routes = NULL;
g_array_set_size (priv->routes, 0);
}
static gboolean
routes_are_duplicate (NMIP4Route *a, NMIP4Route *b)
routes_are_duplicate (NMPlatformIP4Route *a, NMPlatformIP4Route *b)
{
if (nm_ip4_route_get_dest (a) != nm_ip4_route_get_dest (b))
return FALSE;
if (nm_ip4_route_get_prefix (a) != nm_ip4_route_get_prefix (b))
return FALSE;
return TRUE;
return a->network == b->network && a->plen == b->plen;
}
void
nm_ip4_config_add_route (NMIP4Config *config, NMIP4Route *new)
nm_ip4_config_add_route (NMIP4Config *config, NMPlatformIP4Route *new)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
GSList *iter;
int i;
g_return_if_fail (new != NULL);
for (iter = priv->routes; iter; iter = g_slist_next (iter)) {
NMIP4Route *item = (NMIP4Route *) iter->data;
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
if (routes_are_duplicate (item, new)) {
nm_ip4_route_unref (item);
iter->data = nm_ip4_route_dup (new);
memcpy (item, new, sizeof (*item));
return;
}
}
priv->routes = g_slist_append (priv->routes, nm_ip4_route_dup (new));
}
void
nm_ip4_config_take_route (NMIP4Config *config, NMIP4Route *route)
{
g_return_if_fail (route != NULL);
nm_ip4_config_add_route (config, route);
nm_ip4_route_unref (route);
g_array_append_val (priv->routes, *new);
}
void
nm_ip4_config_del_route (NMIP4Config *config, guint i)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
GSList *iter, *last = priv->routes;
guint n;
if (i == 0) {
last = priv->routes;
priv->routes = last->next;
last->next = NULL;
g_slist_free_full (last, (GDestroyNotify) nm_ip4_route_unref);
} else {
for (iter = priv->routes->next, n = 1, last = NULL; iter; iter = iter->next, n++) {
if (n == i) {
last->next = iter->next;
iter->next = NULL;
g_slist_free_full (iter, (GDestroyNotify) nm_ip4_route_unref);
break;
}
last = iter;
}
}
g_return_if_fail (i < priv->routes->len);
g_array_remove_index (priv->routes, i);
}
guint
@ -780,15 +744,15 @@ nm_ip4_config_get_num_routes (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return g_slist_length (priv->routes);
return priv->routes->len;
}
NMIP4Route *
NMPlatformIP4Route *
nm_ip4_config_get_route (NMIP4Config *config, guint i)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
return (NMIP4Route *) g_slist_nth_data (priv->routes, i);
return &g_array_index (priv->routes, NMPlatformIP4Route, i);
}
/******************************************************************/
@ -1144,12 +1108,12 @@ nm_ip4_config_hash (NMIP4Config *config, GChecksum *sum, gboolean dns_only)
}
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
NMIP4Route *r = nm_ip4_config_get_route (config, i);
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
hash_u32 (sum, nm_ip4_route_get_dest (r));
hash_u32 (sum, nm_ip4_route_get_prefix (r));
hash_u32 (sum, nm_ip4_route_get_next_hop (r));
hash_u32 (sum, nm_ip4_route_get_metric (r));
hash_u32 (sum, route->network);
hash_u32 (sum, route->plen);
hash_u32 (sum, route->gateway);
hash_u32 (sum, route->metric);
}
n = nm_ip4_config_get_ptp_address (config);
@ -1216,6 +1180,7 @@ nm_ip4_config_init (NMIP4Config *config)
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
priv->addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address));
priv->routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32));
priv->domains = g_ptr_array_new_with_free_func (g_free);
priv->searches = g_ptr_array_new_with_free_func (g_free);
@ -1229,7 +1194,7 @@ finalize (GObject *object)
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
g_array_unref (priv->addresses);
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref);
g_array_unref (priv->addresses);
g_array_unref (priv->nameservers);
g_ptr_array_unref (priv->domains);
g_ptr_array_unref (priv->searches);
@ -1270,7 +1235,25 @@ get_property (GObject *object, guint prop_id,
}
break;
case PROP_ROUTES:
nm_utils_ip4_routes_to_gvalue (priv->routes, value);
{
GPtrArray *routes = g_ptr_array_new ();
guint nroutes = nm_ip4_config_get_num_routes (config);
int i;
for (i = 0; i < nroutes; i++) {
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
g_array_append_val (array, route->network);
g_array_append_val (array, route->plen);
g_array_append_val (array, route->gateway);
g_array_append_val (array, route->metric);
g_ptr_array_add (routes, array);
}
g_value_take_boxed (value, routes);
}
break;
case PROP_NAMESERVERS:
g_value_set_boxed (value, priv->nameservers);

View file

@ -24,7 +24,6 @@
#include <glib-object.h>
#include "nm-platform.h"
/* NMIP4Route type */
#include "nm-setting-ip4-config.h"
#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ())
@ -84,11 +83,10 @@ const NMPlatformIP4Address *nm_ip4_config_get_address (NMIP4Config *config, guin
/* Routes */
void nm_ip4_config_reset_routes (NMIP4Config *config);
void nm_ip4_config_add_route (NMIP4Config *config, NMIP4Route *route);
void nm_ip4_config_take_route (NMIP4Config *config, NMIP4Route *route);
void nm_ip4_config_add_route (NMIP4Config *config, NMPlatformIP4Route *route);
void nm_ip4_config_del_route (NMIP4Config *config, guint i);
guint32 nm_ip4_config_get_num_routes (NMIP4Config *config);
NMIP4Route * nm_ip4_config_get_route (NMIP4Config *config, guint32 i);
NMPlatformIP4Route * nm_ip4_config_get_route (NMIP4Config *config, guint32 i);
/* Nameservers */
void nm_ip4_config_reset_nameservers (NMIP4Config *config);

View file

@ -41,7 +41,7 @@ typedef struct {
gboolean never_default;
struct in6_addr gateway;
GArray *addresses;
GSList *routes;
GArray *routes;
GArray *nameservers;
GPtrArray *domains;
GPtrArray *searches;
@ -112,31 +112,19 @@ nm_ip6_config_capture (int ifindex)
{
NMIP6Config *config = nm_ip6_config_new ();
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
GArray *routes_array;
NMPlatformIP6Route *routes;
NMIP6Route *route;
int i;
g_array_unref (priv->addresses);
priv->addresses = nm_platform_ip6_address_get_all (ifindex);
g_array_unref (priv->routes);
priv->addresses = nm_platform_ip6_address_get_all (ifindex);
priv->routes = nm_platform_ip6_route_get_all (ifindex, FALSE);
/* Require at least one IP address. */
if (!priv->addresses->len) {
g_object_unref (config);
return NULL;
}
routes_array = nm_platform_ip6_route_get_all (ifindex, FALSE);
routes = (NMPlatformIP6Route *)routes_array->data;
for (i = 0; i < routes_array->len; i++) {
route = nm_ip6_route_new ();
nm_ip6_route_set_dest (route, &routes[i].network);
nm_ip6_route_set_prefix (route, routes[i].plen);
nm_ip6_route_set_next_hop (route, &routes[i].gateway);
nm_ip6_route_set_metric (route, routes[i].metric);
nm_ip6_config_take_route (config, route);
}
g_array_unref (routes_array);
return config;
}
@ -155,16 +143,11 @@ nm_ip6_config_commit (NMIP6Config *config, int ifindex, int priority)
/* Routes */
{
int count = nm_ip6_config_get_num_routes (config);
NMIP6Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count);
NMPlatformIP6Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip6_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = *nm_ip6_route_get_dest (config_route);
route.plen = nm_ip6_route_get_prefix (config_route);
route.gateway = *nm_ip6_route_get_next_hop (config_route);
memcpy (&route, nm_ip6_config_get_route (config, i), sizeof (route));
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
@ -240,8 +223,18 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting)
/* Routes */
if (nm_setting_ip6_config_get_ignore_auto_routes (setting))
nm_ip6_config_reset_routes (config);
for (i = 0; i < nroutes; i++)
nm_ip6_config_add_route (config, nm_setting_ip6_config_get_route (setting, i));
for (i = 0; i < nroutes; i++) {
NMIP6Route *s_route = nm_setting_ip6_config_get_route (setting, i);
NMPlatformIP6Route route;
memset (&route, 0, sizeof (route));
route.network = *nm_ip6_route_get_dest (s_route);
route.plen = nm_ip6_route_get_prefix (s_route);
route.gateway = *nm_ip6_route_get_next_hop (s_route);
route.metric = nm_ip6_route_get_metric (s_route);
nm_ip6_config_add_route (config, &route);
}
/* DNS */
if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) {
@ -304,17 +297,24 @@ nm_ip6_config_update_setting (NMIP6Config *config, NMSettingIP6Config *setting)
/* Routes */
for (i = 0; i < nroutes; i++) {
NMIP6Route *route = nm_ip6_config_get_route (config, i);
NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i);
NMIP6Route *s_route = nm_ip6_route_new ();
/* Ignore link-local route. */
if (IN6_IS_ADDR_LINKLOCAL (nm_ip6_route_get_dest (route)))
if (IN6_IS_ADDR_LINKLOCAL (&route->network))
continue;
/* Ignore default route. */
if (!nm_ip6_route_get_prefix (route))
if (!route->plen)
continue;
nm_setting_ip6_config_add_route (setting, route);
nm_ip6_route_set_dest (s_route, &route->network);
nm_ip6_route_set_prefix (s_route, route->plen);
if (!IN6_IS_ADDR_UNSPECIFIED (&route->network))
nm_ip6_route_set_next_hop (s_route, &route->gateway);
nm_ip6_route_set_metric (s_route, route->metric);
nm_setting_ip6_config_add_route (setting, s_route);
}
/* DNS */
@ -484,49 +484,33 @@ nm_ip6_config_reset_routes (NMIP6Config *config)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref);
priv->routes = NULL;
g_array_set_size (priv->routes, 0);
}
static gboolean
routes_are_duplicate (NMIP6Route *a, NMIP6Route *b)
routes_are_duplicate (NMPlatformIP6Route *a, NMPlatformIP6Route *b)
{
if (nm_ip6_route_get_dest (a) != nm_ip6_route_get_dest (b))
return FALSE;
if (nm_ip6_route_get_prefix (a) != nm_ip6_route_get_prefix (b))
return FALSE;
return TRUE;
return IN6_ARE_ADDR_EQUAL (&a->network, &b->network) && a->plen == b->plen;
}
void
nm_ip6_config_add_route (NMIP6Config *config, NMIP6Route *new)
nm_ip6_config_add_route (NMIP6Config *config, NMPlatformIP6Route *new)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
GSList *iter;
int i;
g_return_if_fail (new != NULL);
for (iter = priv->routes; iter; iter = g_slist_next (iter)) {
NMIP6Route *item = (NMIP6Route *) iter->data;
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i);
if (routes_are_duplicate (item, new)) {
nm_ip6_route_unref (item);
iter->data = nm_ip6_route_dup (new);
memcpy (item, new, sizeof (*item));
return;
}
}
priv->routes = g_slist_append (priv->routes, nm_ip6_route_dup (new));
}
void
nm_ip6_config_take_route (NMIP6Config *config, NMIP6Route *route)
{
g_return_if_fail (route != NULL);
nm_ip6_config_add_route (config, route);
nm_ip6_route_unref (route);
g_array_append_val (priv->routes, *new);
}
guint
@ -534,15 +518,15 @@ nm_ip6_config_get_num_routes (NMIP6Config *config)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return g_slist_length (priv->routes);
return priv->routes->len;
}
NMIP6Route *
NMPlatformIP6Route *
nm_ip6_config_get_route (NMIP6Config *config, guint i)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
return (NMIP6Route *) g_slist_nth_data (priv->routes, i);
return &g_array_index (priv->routes, NMPlatformIP6Route, i);
}
/******************************************************************/
@ -744,12 +728,12 @@ nm_ip6_config_hash (NMIP6Config *config, GChecksum *sum, gboolean dns_only)
}
for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) {
NMIP6Route *r = nm_ip6_config_get_route (config, i);
NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i);
hash_in6addr (sum, nm_ip6_route_get_dest (r));
hash_u32 (sum, nm_ip6_route_get_prefix (r));
hash_in6addr (sum, nm_ip6_route_get_next_hop (r));
hash_u32 (sum, nm_ip6_route_get_metric (r));
hash_in6addr (sum, &route->network);
hash_u32 (sum, route->plen);
hash_in6addr (sum, &route->gateway);
hash_u32 (sum, route->metric);
}
in6a = nm_ip6_config_get_ptp_address (config);
@ -806,6 +790,7 @@ nm_ip6_config_init (NMIP6Config *config)
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
priv->addresses = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Address));
priv->routes = g_array_new (FALSE, TRUE, sizeof (NMPlatformIP6Route));
priv->nameservers = g_array_new (FALSE, TRUE, sizeof (struct in6_addr));
priv->domains = g_ptr_array_new_with_free_func (g_free);
priv->searches = g_ptr_array_new_with_free_func (g_free);
@ -817,7 +802,7 @@ finalize (GObject *object)
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
g_array_unref (priv->addresses);
g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref);
g_array_unref (priv->routes);
g_array_unref (priv->nameservers);
g_ptr_array_unref (priv->domains);
g_ptr_array_unref (priv->searches);
@ -896,15 +881,55 @@ get_property (GObject *object, guint prop_id,
g_value_take_boxed (value, addresses);
}
break;
case PROP_ROUTES:
{
GPtrArray *routes = g_ptr_array_new ();
int nroutes = nm_ip6_config_get_num_routes (config);
int i;
for (i = 0; i < nroutes; i++) {
NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i);
GValueArray *array = g_value_array_new (4);
GByteArray *ba;
GValue element = G_VALUE_INIT;
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
ba = g_byte_array_new ();
g_byte_array_append (ba, (guint8 *) &route->network, sizeof (route->network));
g_value_take_boxed (&element, ba);
g_value_array_append (array, &element);
g_value_unset (&element);
g_value_init (&element, G_TYPE_UINT);
g_value_set_uint (&element, route->plen);
g_value_array_append (array, &element);
g_value_unset (&element);
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
ba = g_byte_array_new ();
g_byte_array_append (ba, (guint8 *) &route->gateway, sizeof (route->gateway));
g_value_take_boxed (&element, ba);
g_value_array_append (array, &element);
g_value_unset (&element);
g_value_init (&element, G_TYPE_UINT);
g_value_set_uint (&element, route->metric);
g_value_array_append (array, &element);
g_value_unset (&element);
g_ptr_array_add (routes, array);
}
g_value_take_boxed (value, routes);
}
break;
case PROP_NAMESERVERS:
nameservers_to_gvalue (priv->nameservers, value);
break;
case PROP_DOMAINS:
g_value_set_boxed (value, priv->domains);
break;
case PROP_ROUTES:
nm_utils_ip6_routes_to_gvalue (priv->routes, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -24,9 +24,7 @@
#include <glib-object.h>
#include "nm-platform.h"
/* NMIP6Route type */
#include "nm-setting-ip6-config.h"
#include "nm-platform.h"
#define NM_TYPE_IP6_CONFIG (nm_ip6_config_get_type ())
#define NM_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP6_CONFIG, NMIP6Config))
@ -81,10 +79,9 @@ NMPlatformIP6Address *nm_ip6_config_get_address (NMIP6Config *config, guint i);
/* Routes */
void nm_ip6_config_reset_routes (NMIP6Config *config);
void nm_ip6_config_add_route (NMIP6Config *config, NMIP6Route *route);
void nm_ip6_config_take_route (NMIP6Config *config, NMIP6Route *route);
void nm_ip6_config_add_route (NMIP6Config *config, NMPlatformIP6Route *route);
guint32 nm_ip6_config_get_num_routes (NMIP6Config *config);
NMIP6Route * nm_ip6_config_get_route (NMIP6Config *config, guint32 i);
NMPlatformIP6Route * nm_ip6_config_get_route (NMIP6Config *config, guint32 i);
/* Nameservers */
void nm_ip6_config_reset_nameservers (NMIP6Config *config);

View file

@ -102,7 +102,7 @@ test_generic_options (const char *client)
GHashTable *options;
NMIP4Config *ip4_config;
const NMPlatformIP4Address *address;
NMIP4Route *route;
NMPlatformIP4Route *route;
struct in_addr tmp;
const char *expected_addr = "192.168.1.106";
const char *expected_gw = "192.168.1.1";
@ -176,34 +176,34 @@ test_generic_options (const char *client)
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-generic", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
ASSERT (route->network == tmp.s_addr,
"dhcp-generic", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-generic", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
ASSERT (route->gateway == tmp.s_addr,
"dhcp-generic", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 32,
ASSERT (route->plen == 32,
"dhcp-generic", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
ASSERT (route->metric == 0,
"dhcp-generic", "unexpected route #1 metric");
/* Route #2 */
route = nm_ip4_config_get_route (ip4_config, 1);
ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0,
"dhcp-generic", "couldn't convert expected route destination #2");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
ASSERT (route->network == tmp.s_addr,
"dhcp-generic", "unexpected route #2 destination");
ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0,
"dhcp-generic", "couldn't convert expected route next hop #2");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
ASSERT (route->gateway == tmp.s_addr,
"dhcp-generic", "unexpected route #2 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 32,
ASSERT (route->plen == 32,
"dhcp-generic", "unexpected route #2 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
ASSERT (route->metric == 0,
"dhcp-generic", "unexpected route #2 metric");
g_hash_table_destroy (options);
@ -258,24 +258,24 @@ ip4_test_route (const char *test,
const char *expected_gw,
guint expected_prefix)
{
NMIP4Route *route;
NMPlatformIP4Route *route;
struct in_addr tmp;
route = nm_ip4_config_get_route (ip4_config, route_num);
ASSERT (inet_pton (AF_INET, expected_dest, &tmp) > 0,
test, "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
ASSERT (route->network == tmp.s_addr,
test, "unexpected route %d destination", route_num + 1);
ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0,
test, "couldn't convert expected route next hop %d",
route_num + 1);
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
ASSERT (route->gateway == tmp.s_addr,
test, "unexpected route %d next hop", route_num + 1);
ASSERT (nm_ip4_route_get_prefix (route) == expected_prefix,
ASSERT (route->plen == expected_prefix,
test, "unexpected route %d prefix", route_num + 1);
ASSERT (nm_ip4_route_get_metric (route) == 0,
ASSERT (route->metric == 0,
test, "unexpected route %d metric", route_num + 1);
}

View file

@ -32,22 +32,21 @@ addr_init (NMPlatformIP4Address *a, const char *addr, guint plen)
a->plen = plen;
}
static NMIP4Route *
route_new (const char *network, guint plen, const char *gw)
static void
route_new (NMPlatformIP4Route *route, const char *network, guint plen, const char *gw)
{
NMIP4Route *route;
guint n;
route = nm_ip4_route_new ();
g_assert (route);
memset (route, 0, sizeof (*route));
g_assert (inet_pton (AF_INET, network, (void *) &n) == 1);
nm_ip4_route_set_dest (route, n);
nm_ip4_route_set_prefix (route, plen);
route->network = n;
route->plen = plen;
if (gw) {
n = 0;
g_assert (inet_pton (AF_INET, gw, (void *) &n) == 1);
nm_ip4_route_set_next_hop (route, n);
route->gateway = n;
}
return route;
}
static guint32
@ -64,7 +63,7 @@ build_test_config (void)
{
NMIP4Config *config;
NMPlatformIP4Address addr;
NMIP4Route *route;
NMPlatformIP4Route route;
/* Build up the config to subtract */
config = nm_ip4_config_new ();
@ -72,11 +71,11 @@ build_test_config (void)
addr_init (&addr, "192.168.1.10", 24);
nm_ip4_config_add_address (config, &addr);
route = route_new ("10.0.0.0", 8, "192.168.1.1");
nm_ip4_config_take_route (config, route);
route_new (&route, "10.0.0.0", 8, "192.168.1.1");
nm_ip4_config_add_route (config, &route);
route = route_new ("172.16.0.0", 16, "192.168.1.1");
nm_ip4_config_take_route (config, route);
route_new (&route, "172.16.0.0", 16, "192.168.1.1");
nm_ip4_config_add_route (config, &route);
nm_ip4_config_set_gateway (config, addr_to_num ("192.168.1.1"));
@ -104,7 +103,7 @@ test_subtract (void)
NMIP4Config *src, *dst;
NMPlatformIP4Address addr;
const NMPlatformIP4Address *test_addr;
NMIP4Route *route;
NMPlatformIP4Route route, *test_route;
const char *expected_addr = "192.168.1.12";
guint32 expected_addr_plen = 24;
const char *expected_route_dest = "8.7.6.5";
@ -124,8 +123,8 @@ test_subtract (void)
addr_init (&addr, expected_addr, expected_addr_plen);
nm_ip4_config_add_address (dst, &addr);
route = route_new (expected_route_dest, expected_route_plen, expected_route_next_hop);
nm_ip4_config_take_route (dst, route);
route_new (&route, expected_route_dest, expected_route_plen, expected_route_next_hop);
nm_ip4_config_add_route (dst, &route);
nm_ip4_config_add_nameserver (dst, expected_ns1);
nm_ip4_config_add_nameserver (dst, expected_ns2);
@ -148,11 +147,11 @@ test_subtract (void)
g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0);
g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1);
route = nm_ip4_config_get_route (dst, 0);
g_assert (route != NULL);
g_assert_cmpuint (nm_ip4_route_get_dest (route), ==, addr_to_num (expected_route_dest));
g_assert_cmpuint (nm_ip4_route_get_prefix (route), ==, expected_route_plen);
g_assert_cmpuint (nm_ip4_route_get_next_hop (route), ==, addr_to_num (expected_route_next_hop));
test_route = nm_ip4_config_get_route (dst, 0);
g_assert (test_route != NULL);
g_assert_cmpuint (test_route->network, ==, addr_to_num (expected_route_dest));
g_assert_cmpuint (test_route->plen, ==, expected_route_plen);
g_assert_cmpuint (test_route->gateway, ==, addr_to_num (expected_route_next_hop));
g_assert_cmpuint (nm_ip4_config_get_num_nameservers (dst), ==, 2);
g_assert_cmpuint (nm_ip4_config_get_nameserver (dst, 0), ==, expected_ns1);

View file

@ -300,7 +300,7 @@ add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
{
NMIP4Config *parent_config;
guint32 parent_gw;
NMIP4Route *route;
NMPlatformIP4Route route;
NMIP4Config *vpn4_config;
g_return_if_fail (NM_IS_DEVICE (parent_device));
@ -318,29 +318,30 @@ add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
vpn4_config = nm_ip4_config_new ();
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, vpn_gw);
nm_ip4_route_set_prefix (route, 32);
nm_ip4_route_set_next_hop (route, parent_gw);
memset (&route, 0, sizeof (route));
route.network = vpn_gw;
route.plen = 32;
route.gateway = parent_gw;
/* If the VPN gateway is in the same subnet as one of the parent device's
* IP addresses, don't add the host route to it, but a route through the
* parent device.
*/
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
nm_ip4_route_set_next_hop (route, 0);
route.gateway = 0;
nm_ip4_config_take_route (vpn4_config, route);
nm_ip4_config_add_route (vpn4_config, &route);
/* Ensure there's a route to the parent device's gateway through the
* parent device, since if the VPN claims the default route and the VPN
* routes include a subnet that matches the parent device's subnet,
* the parent device's gateway would get routed through the VPN and fail.
*/
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, parent_gw);
nm_ip4_route_set_prefix (route, 32);
nm_ip4_config_take_route (vpn4_config, route);
memset (&route, 0, sizeof (route));
route.network = parent_gw;
route.plen = 32;
nm_ip4_config_add_route (vpn4_config, &route);
nm_device_set_vpn4_config (parent_device, vpn4_config);
g_object_unref (vpn4_config);
@ -352,7 +353,7 @@ add_ip6_vpn_gateway_route (NMDevice *parent_device,
{
NMIP6Config *parent_config;
const struct in6_addr *parent_gw;
NMIP6Route *route;
NMPlatformIP6Route route;
NMIP6Config *vpn6_config;
g_return_if_fail (NM_IS_DEVICE (parent_device));
@ -366,29 +367,30 @@ add_ip6_vpn_gateway_route (NMDevice *parent_device,
vpn6_config = nm_ip6_config_new ();
route = nm_ip6_route_new ();
nm_ip6_route_set_dest (route, vpn_gw);
nm_ip6_route_set_prefix (route, 128);
nm_ip6_route_set_next_hop (route, parent_gw);
memset (&route, 0, sizeof (route));
route.network = *vpn_gw;
route.plen = 128;
route.gateway = *parent_gw;
/* If the VPN gateway is in the same subnet as one of the parent device's
* IP addresses, don't add the host route to it, but a route through the
* parent device.
*/
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
nm_ip6_route_set_next_hop (route, &in6addr_any);
route.gateway = in6addr_any;
nm_ip6_config_take_route (vpn6_config, route);
nm_ip6_config_add_route (vpn6_config, &route);
/* Ensure there's a route to the parent device's gateway through the
* parent device, since if the VPN claims the default route and the VPN
* routes include a subnet that matches the parent device's subnet,
* the parent device's gateway would get routed through the VPN and fail.
*/
route = nm_ip6_route_new ();
nm_ip6_route_set_dest (route, parent_gw);
nm_ip6_route_set_prefix (route, 128);
nm_ip6_config_take_route (vpn6_config, route);
memset (&route, 0, sizeof (route));
route.network = *parent_gw;
route.plen = 128;
nm_ip6_config_add_route (vpn6_config, &route);
nm_device_set_vpn6_config (parent_device, vpn6_config);
g_object_unref (vpn6_config);
@ -575,13 +577,12 @@ print_vpn_config (NMVPNConnection *connection)
num = nm_ip4_config_get_num_routes (priv->ip4_config);
for (i = 0; i < num; i++) {
NMIP4Route *route;
NMPlatformIP4Route *route = nm_ip4_config_get_route (priv->ip4_config, i);
route = nm_ip4_config_get_route (priv->ip4_config, i);
nm_log_info (LOGD_VPN, " Static Route: %s/%d Next Hop: %s",
ip_address_to_string (nm_ip4_route_get_dest (route)),
nm_ip4_route_get_prefix (route),
ip_address_to_string (nm_ip4_route_get_next_hop (route)));
ip_address_to_string (route->network),
route->plen,
ip_address_to_string (route->gateway));
}
nm_log_info (LOGD_VPN, " Forbid Default Route: %s",
@ -615,13 +616,12 @@ print_vpn_config (NMVPNConnection *connection)
num = nm_ip6_config_get_num_routes (priv->ip6_config);
for (i = 0; i < num; i++) {
NMIP6Route *route;
NMPlatformIP6Route *route = nm_ip6_config_get_route (priv->ip6_config, i);
route = nm_ip6_config_get_route (priv->ip6_config, i);
nm_log_info (LOGD_VPN, " Static Route: %s/%d Next Hop: %s",
ip6_address_to_string (nm_ip6_route_get_dest (route)),
nm_ip6_route_get_prefix (route),
ip6_address_to_string (nm_ip6_route_get_next_hop (route)));
ip6_address_to_string (&route->network),
route->plen,
ip6_address_to_string (&route->gateway));
}
nm_log_info (LOGD_VPN, " Forbid Default Route: %s",
@ -931,25 +931,27 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
routes = nm_utils_ip4_routes_from_gvalue (val);
for (iter = routes; iter; iter = iter->next) {
NMIP4Route *route = iter->data;
NMIP4Route *item = iter->data;
NMPlatformIP4Route route;
memset (&route, 0, sizeof (route));
route.network = nm_ip4_route_get_dest (item);
route.plen = nm_ip4_route_get_prefix (item);
route.gateway = nm_ip4_route_get_next_hop (item);
/* Ignore host routes to the VPN gateway since NM adds one itself
* below. Since NM knows more about the routing situation than
* the VPN server, we want to use the NM created route instead of
* whatever the server provides.
*/
if ( priv->ip4_external_gw
&& nm_ip4_route_get_dest (route) == priv->ip4_external_gw
&& nm_ip4_route_get_prefix (route) == 32) {
nm_ip4_route_unref (route);
if (priv->ip4_external_gw && route.network == priv->ip4_external_gw && route.plen == 32)
continue;
}
/* Otherwise accept the VPN-provided route */
nm_ip4_config_take_route (config, route);
nm_ip4_config_add_route (config, &route);
}
g_slist_free (routes);
g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref);
}
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT);
@ -1070,26 +1072,27 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
routes = nm_utils_ip6_routes_from_gvalue (val);
for (iter = routes; iter; iter = iter->next) {
NMIP6Route *route = iter->data;
NMIP6Route *item = iter->data;
NMPlatformIP6Route route;
memset (&route, 0, sizeof (route));
route.network = *nm_ip6_route_get_dest (item);
route.plen = nm_ip6_route_get_prefix (item);
route.gateway = *nm_ip6_route_get_next_hop (item);
/* Ignore host routes to the VPN gateway since NM adds one itself
* below. Since NM knows more about the routing situation than
* the VPN server, we want to use the NM created route instead of
* whatever the server provides.
*/
if ( priv->ip6_external_gw
&& nm_ip6_route_get_prefix (route) == 128
&& memcmp (nm_ip6_route_get_dest (route), priv->ip6_external_gw,
sizeof (struct in6_addr)) == 0) {
nm_ip6_route_unref (route);
if (IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) && route.plen == 128)
continue;
}
/* Otherwise accept the VPN-provided route */
nm_ip6_config_take_route (config, route);
nm_ip6_config_add_route (config, &route);
}
g_slist_free (routes);
g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref);
}
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT);