core: don't leave additional default routes in captured IP config

There can be multiple default routes for an interface with different
metrics.  Grab the gateway of the default route with the lowest
metric as the overall gateway of the IP config.  Otherwise the rest
could get left in the config and applied at random times.
This commit is contained in:
Dan Williams 2013-11-19 22:51:29 -06:00
parent 12d96c30f2
commit da016d91f5
2 changed files with 15 additions and 10 deletions

View file

@ -177,7 +177,8 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
NMIP4Config *config;
NMIP4ConfigPrivate *priv;
guint i;
gboolean gateway_changed = FALSE;
guint lowest_metric = G_MAXUINT;
guint32 old_gateway = 0;
gboolean has_gateway = FALSE;
/* Slaves have no IP configuration */
@ -194,18 +195,19 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
priv->routes = nm_platform_ip4_route_get_all (ifindex, TRUE);
/* Extract gateway from default route */
old_gateway = priv->gateway;
for (i = 0; i < priv->routes->len; i++) {
const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i);
if (route->network == 0) {
if (priv->gateway != route->gateway) {
if (route->metric < lowest_metric) {
priv->gateway = route->gateway;
gateway_changed = TRUE;
lowest_metric = route->metric;
}
has_gateway = TRUE;
/* Remove the default route from the list */
g_array_remove_index (priv->routes, i);
break;
i--;
}
}
@ -220,7 +222,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
/* actually, nobody should be connected to the signal, just to be sure, notify */
_NOTIFY (config, PROP_ADDRESSES);
_NOTIFY (config, PROP_ROUTES);
if (gateway_changed)
if (priv->gateway != old_gateway)
_NOTIFY (config, PROP_GATEWAY);
return config;

View file

@ -179,7 +179,8 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf)
NMIP6Config *config;
NMIP6ConfigPrivate *priv;
guint i;
gboolean gateway_changed = FALSE;
guint lowest_metric = G_MAXUINT;
struct in6_addr old_gateway = IN6ADDR_ANY_INIT;
gboolean has_gateway = FALSE;
/* Slaves have no IP configuration */
@ -196,18 +197,20 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf)
priv->routes = nm_platform_ip6_route_get_all (ifindex, TRUE);
/* Extract gateway from default route */
old_gateway = priv->gateway;
for (i = 0; i < priv->routes->len; i++) {
const NMPlatformIP6Route *route = &g_array_index (priv->routes, NMPlatformIP6Route, i);
if (IN6_IS_ADDR_UNSPECIFIED (&route->network)) {
if (!IN6_ARE_ADDR_EQUAL (&priv->gateway, &route->gateway)) {
if (route->metric < lowest_metric) {
priv->gateway = route->gateway;
gateway_changed = TRUE;
lowest_metric = route->metric;
has_gateway = TRUE;
}
has_gateway = TRUE;
/* Remove the default route from the list */
g_array_remove_index (priv->routes, i);
break;
i--;
}
}
@ -222,7 +225,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf)
/* actually, nobody should be connected to the signal, just to be sure, notify */
_NOTIFY (config, PROP_ADDRESSES);
_NOTIFY (config, PROP_ROUTES);
if (gateway_changed)
if (!IN6_ARE_ADDR_EQUAL (&priv->gateway, &old_gateway))
_NOTIFY (config, PROP_GATEWAY);
return config;