summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-11-21 20:21:37 +0100
committerThomas Haller <thaller@redhat.com>2015-01-24 18:27:12 +0100
commitda708059dabb2854d11eed1a403398327b31535b (patch)
tree9b3783d729e97b8cb9bda518907130923a18b175
parent557667df12fc05b76326d6406553985effeeb2ac (diff)
downloadNetworkManager-da708059dabb2854d11eed1a403398327b31535b.tar.gz
device: always pickup externally configured default routes for a device
Even more eagerly pickup external default routes from the device. For assumed devices we already picked up the default route. (a) For assumed devices we already did not enforce the default route at all. Instead it was always picked up by from the actualy system configuration. Note that this is the case for assumed-generated connections and for assuming existing connections. That means that when NM assumes a connection at startup, it will never actively manage the default route on that interface. It will only react on what is present. (b) For managed devices that have by configuration no default route, still pick up the default route. That means, that even a device that is managed and never-default=yes, can have the default route -- if configured externally. (c) Only during a commit phase (i.e. when we have new configuraiton to be applied), we enforce the default route or its absence. (d) During any IP change event from platform, we again pickup whatever is present. That means if you remove the default route from a managed interface, NM will not re-add it until anything triggers (c). This also means, that during the commit phase, we add default routes as 'synced' to the default-route-manager, but the following event from platform, will change the route entry immediately to 'non-synced'. That is expected and correct.
-rw-r--r--src/devices/nm-device.c168
1 files changed, 94 insertions, 74 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 77aaedbac7..caed116f51 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -2913,6 +2913,7 @@ ip4_config_merge_and_apply (NMDevice *self,
NMIP4Config *composite;
gboolean has_direct_route;
const guint32 default_route_metric = nm_device_get_ip4_route_metric (self);
+ guint32 gateway;
/* Merge all the configs into the composite config */
if (config) {
@@ -2961,56 +2962,65 @@ ip4_config_merge_and_apply (NMDevice *self,
priv->default_route.v4_has = FALSE;
priv->default_route.v4_is_assumed = TRUE;
- if (!connection)
+ if (!commit) {
+ /* during a non-commit event, we always pickup whatever is configured. */
goto END_ADD_DEFAULT_ROUTE;
+ }
- if ( !nm_device_uses_assumed_connection (self)
- && nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection)) {
- guint32 gateway;
+ if (nm_device_uses_assumed_connection (self))
+ goto END_ADD_DEFAULT_ROUTE;
- priv->default_route.v4_is_assumed = FALSE;
- if (!nm_ip4_config_get_num_addresses (composite)) {
- /* without addresses we can have no default route. */
- goto END_ADD_DEFAULT_ROUTE;
- }
+ /* we are about to commit (for a non-assumed connection). Enforce whatever we have
+ * configured. */
+ priv->default_route.v4_is_assumed = FALSE;
- gateway = nm_ip4_config_get_gateway (composite);
- if ( !gateway
- && nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
- goto END_ADD_DEFAULT_ROUTE;
-
- has_direct_route = ( gateway == 0
- || nm_ip4_config_get_subnet_for_host (composite, gateway)
- || nm_ip4_config_get_direct_route_for_host (composite, gateway));
-
- /* In the (!has_direct_route && !commit) case it is not clear whether
- * adding the default route will succeed. Still give it a try and add it */
-
- priv->default_route.v4_has = TRUE;
- memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
- priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER;
- priv->default_route.v4.gateway = gateway;
- priv->default_route.v4.metric = default_route_metric;
- priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
-
- if (!has_direct_route && commit) {
- NMPlatformIP4Route r = priv->default_route.v4;
-
- /* add a direct route to the gateway */
- r.network = gateway;
- r.plen = 32;
- r.gateway = 0;
- nm_ip4_config_add_route (composite, &r);
- }
- } else {
- /* For interfaces that are assumed and that have no default-route by configuration, we assume
- * the default connection and pick up whatever is configured. */
- priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4);
+ if ( !connection
+ || !nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection))
+ goto END_ADD_DEFAULT_ROUTE;
+
+ if (!nm_ip4_config_get_num_addresses (composite)) {
+ /* without addresses we can have no default route. */
+ goto END_ADD_DEFAULT_ROUTE;
+ }
+
+ gateway = nm_ip4_config_get_gateway (composite);
+ if ( !gateway
+ && nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
+ goto END_ADD_DEFAULT_ROUTE;
+
+ has_direct_route = ( gateway == 0
+ || nm_ip4_config_get_subnet_for_host (composite, gateway)
+ || nm_ip4_config_get_direct_route_for_host (composite, gateway));
+
+ priv->default_route.v4_has = TRUE;
+ memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
+ priv->default_route.v4.source = NM_IP_CONFIG_SOURCE_USER;
+ priv->default_route.v4.gateway = gateway;
+ priv->default_route.v4.metric = default_route_metric;
+ priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
+
+ if (!has_direct_route) {
+ NMPlatformIP4Route r = priv->default_route.v4;
+
+ /* add a direct route to the gateway */
+ r.network = gateway;
+ r.plen = 32;
+ r.gateway = 0;
+ nm_ip4_config_add_route (composite, &r);
}
END_ADD_DEFAULT_ROUTE:
+ if (priv->default_route.v4_is_assumed) {
+ /* If above does not explicitly assign a default route, we always pick up the
+ * default route based on what is currently configured.
+ * That means that even managed connections with never-default, can
+ * get a default route (if configured externally).
+ */
+ priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4);
+ }
+
/* Allow setting MTU etc */
if (commit) {
if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
@@ -3485,6 +3495,7 @@ ip6_config_merge_and_apply (NMDevice *self,
gboolean success;
NMIP6Config *composite;
gboolean has_direct_route;
+ const struct in6_addr *gateway;
/* If no config was passed in, create a new one */
composite = nm_ip6_config_new ();
@@ -3531,56 +3542,65 @@ ip6_config_merge_and_apply (NMDevice *self,
priv->default_route.v6_has = FALSE;
priv->default_route.v6_is_assumed = TRUE;
- if (!connection)
+ if (!commit) {
+ /* during a non-commit event, we always pickup whatever is configured. */
goto END_ADD_DEFAULT_ROUTE;
+ }
- if ( !nm_device_uses_assumed_connection (self)
- && nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection)) {
- const struct in6_addr *gateway;
+ if (nm_device_uses_assumed_connection (self))
+ goto END_ADD_DEFAULT_ROUTE;
- priv->default_route.v6_is_assumed = FALSE;
- if (!nm_ip6_config_get_num_addresses (composite)) {
- /* without addresses we can have no default route. */
- goto END_ADD_DEFAULT_ROUTE;
- }
+ /* we are about to commit (for a non-assumed connection). Enforce whatever we have
+ * configured. */
+ priv->default_route.v6_is_assumed = FALSE;
+
+ if ( !connection
+ || !nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection))
+ goto END_ADD_DEFAULT_ROUTE;
- gateway = nm_ip6_config_get_gateway (composite);
- if (!gateway)
- goto END_ADD_DEFAULT_ROUTE;
+ if (!nm_ip6_config_get_num_addresses (composite)) {
+ /* without addresses we can have no default route. */
+ goto END_ADD_DEFAULT_ROUTE;
+ }
+ gateway = nm_ip6_config_get_gateway (composite);
+ if (!gateway)
+ goto END_ADD_DEFAULT_ROUTE;
- has_direct_route = nm_ip6_config_get_direct_route_for_host (composite, gateway) != NULL;
+ has_direct_route = nm_ip6_config_get_direct_route_for_host (composite, gateway) != NULL;
- /* In the (!has_direct_route && !commit) case it is not clear whether
- * adding the default route will succeed. Still give it a try and add it */
- priv->default_route.v6_has = TRUE;
- memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
- priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER;
- priv->default_route.v6.gateway = *gateway;
- priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self);
- priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
+ priv->default_route.v6_has = TRUE;
+ memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
+ priv->default_route.v6.source = NM_IP_CONFIG_SOURCE_USER;
+ priv->default_route.v6.gateway = *gateway;
+ priv->default_route.v6.metric = nm_device_get_ip6_route_metric (self);
+ priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
- if (!has_direct_route && commit) {
- NMPlatformIP6Route r = priv->default_route.v6;
+ if (!has_direct_route) {
+ NMPlatformIP6Route r = priv->default_route.v6;
- /* add a direct route to the gateway */
- r.network = *gateway;
- r.plen = 128;
- r.gateway = in6addr_any;
- nm_ip6_config_add_route (composite, &r);
- }
- } else {
- /* For interfaces that are assumed and that have no default-route by configuration, we assume
- * the default connection and pick up whatever is configured. */
- priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6);
+ /* add a direct route to the gateway */
+ r.network = *gateway;
+ r.plen = 128;
+ r.gateway = in6addr_any;
+ nm_ip6_config_add_route (composite, &r);
}
END_ADD_DEFAULT_ROUTE:
+ if (priv->default_route.v6_is_assumed) {
+ /* If above does not explicitly assign a default route, we always pick up the
+ * default route based on what is currently configured.
+ * That means that even managed connections with never-default, can
+ * get a default route (if configured externally).
+ */
+ priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6);
+ }
+
nm_ip6_config_addresses_sort (composite,
priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);