diff options
| author | Thomas Haller <thaller@redhat.com> | 2014-11-21 20:21:37 +0100 |
|---|---|---|
| committer | Thomas Haller <thaller@redhat.com> | 2015-01-24 18:27:12 +0100 |
| commit | da708059dabb2854d11eed1a403398327b31535b (patch) | |
| tree | 9b3783d729e97b8cb9bda518907130923a18b175 | |
| parent | 557667df12fc05b76326d6406553985effeeb2ac (diff) | |
| download | NetworkManager-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.c | 168 |
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); |
