summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-09-12 13:45:53 +0200
committerThomas Haller <thaller@redhat.com>2017-09-13 08:17:31 +0200
commit9a3117f1d3095e58859efce57ea4fb41d8fb7696 (patch)
tree5c0568a3714f3ff0a20ddbd2526199ffca01b08a
parent4b4efac3ab8a7b84e25a2dea4eadbaa789c15f9c (diff)
downloadNetworkManager-9a3117f1d3095e58859efce57ea4fb41d8fb7696.tar.gz
core: track IPv4 device routes in NMIP4Config
For IPv6, we create device routes when processing the RA and add it to NMIP6Config like any other route. For IPv4 we didn't do that. Instead we created the list of device routes during nm_ip4_config_commit() and passed it to nm_platform_ip_route_sync().
-rw-r--r--src/devices/nm-device.c28
-rw-r--r--src/nm-iface-helper.c11
-rw-r--r--src/nm-ip4-config.c162
-rw-r--r--src/nm-ip4-config.h9
-rw-r--r--src/vpn/nm-vpn-connection.c16
5 files changed, 131 insertions, 95 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 6158cc917a..cd523b9dad 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -496,8 +496,8 @@ static void nm_device_set_proxy_config (NMDevice *self, const char *pac_url);
static gboolean nm_device_set_ip4_config (NMDevice *self,
NMIP4Config *config,
- guint32 default_route_metric,
- gboolean commit);
+ gboolean commit,
+ GPtrArray *ip4_dev_route_blacklist);
static gboolean ip4_config_merge_and_apply (NMDevice *self,
NMIP4Config *config,
gboolean commit);
@@ -3885,7 +3885,7 @@ nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config)
if (!unconfigure_ip_config)
return;
- nm_device_set_ip4_config (self, NULL, 0, FALSE);
+ nm_device_set_ip4_config (self, NULL, FALSE, NULL);
nm_device_set_ip6_config (self, NULL, FALSE);
}
@@ -5578,6 +5578,7 @@ ip4_config_merge_and_apply (NMDevice *self,
gboolean ignore_auto_dns = FALSE;
GSList *iter;
NMPlatformIP4Route default_route;
+ gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
/* Merge all the configs into the composite config */
if (config) {
@@ -5694,12 +5695,19 @@ ip4_config_merge_and_apply (NMDevice *self,
}
END_ADD_DEFAULT_ROUTE:
+
+ if (commit) {
+ nm_ip4_config_add_device_routes (composite,
+ default_route_metric,
+ &ip4_dev_route_blacklist);
+ }
+
if (commit) {
if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
}
- success = nm_device_set_ip4_config (self, composite, default_route_metric, commit);
+ success = nm_device_set_ip4_config (self, composite, commit, ip4_dev_route_blacklist);
g_object_unref (composite);
if (commit)
@@ -9739,8 +9747,8 @@ nm_device_get_ip4_config (NMDevice *self)
static gboolean
nm_device_set_ip4_config (NMDevice *self,
NMIP4Config *new_config,
- guint32 default_route_metric,
- gboolean commit)
+ gboolean commit,
+ GPtrArray *ip4_dev_route_blacklist)
{
NMDevicePrivate *priv;
NMIP4Config *old_config = NULL;
@@ -9766,8 +9774,10 @@ nm_device_set_ip4_config (NMDevice *self,
if (commit && new_config) {
_commit_mtu (self, new_config);
success = nm_ip4_config_commit (new_config,
- nm_device_get_platform (self),
- default_route_metric);
+ nm_device_get_platform (self));
+ nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self),
+ nm_ip4_config_get_ifindex (new_config),
+ ip4_dev_route_blacklist);
}
if (new_config) {
@@ -11986,7 +11996,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
/* Clean up IP configs; this does not actually deconfigure the
* interface; the caller must flush routes and addresses explicitly.
*/
- nm_device_set_ip4_config (self, NULL, 0, TRUE);
+ nm_device_set_ip4_config (self, NULL, TRUE, NULL);
nm_device_set_ip6_config (self, NULL, TRUE);
nm_clear_nmp_object (&priv->default_route4);
nm_clear_nmp_object (&priv->default_route6);
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 9f6ba72407..ae76ee94ef 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -107,6 +107,7 @@ dhcp4_state_changed (NMDhcpClient *client,
{
static NMIP4Config *last_config = NULL;
NMIP4Config *existing;
+ gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
@@ -123,11 +124,17 @@ dhcp4_state_changed (NMDhcpClient *client,
nm_ip4_config_subtract (existing, last_config);
nm_ip4_config_merge (existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
+ nm_ip4_config_add_device_routes (existing,
+ global_opt.priority_v4,
+ &ip4_dev_route_blacklist);
if (!nm_ip4_config_commit (existing,
- NM_PLATFORM_GET,
- global_opt.priority_v4))
+ NM_PLATFORM_GET))
_LOGW (LOGD_DHCP4, "failed to apply DHCPv4 config");
+ nm_platform_ip4_dev_route_blacklist_set (NM_PLATFORM_GET,
+ gl.ifindex,
+ ip4_dev_route_blacklist);
+
if (last_config)
g_object_unref (last_config);
last_config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 07e2f2e080..58127dafab 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -724,107 +724,113 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
return self;
}
-gboolean
-nm_ip4_config_commit (const NMIP4Config *self,
- NMPlatform *platform,
- guint32 default_route_metric)
+void
+nm_ip4_config_add_device_routes (NMIP4Config *self,
+ guint32 default_route_metric,
+ GPtrArray **out_ip4_dev_route_blacklist)
{
const NMIP4ConfigPrivate *priv;
- gs_unref_ptrarray GPtrArray *addresses = NULL;
- gs_unref_ptrarray GPtrArray *routes = NULL;
- gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
+ GPtrArray *ip4_dev_route_blacklist = NULL;
+ const NMPlatformIP4Address *addr;
int ifindex;
- guint i;
- gboolean success = TRUE;
+ NMDedupMultiIter iter;
- g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE);
+ g_return_if_fail (NM_IS_IP4_CONFIG (self));
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
ifindex = nm_ip4_config_get_ifindex (self);
- g_return_val_if_fail (ifindex > 0, FALSE);
+ g_return_if_fail (ifindex > 0);
- addresses = nm_dedup_multi_objs_to_ptr_array_head (nm_ip4_config_lookup_addresses (self),
- NULL, NULL);
+ /* For IPv6, we explicitly add the device-routes (onlink) to NMIP6Config.
+ * As we don't do that for IPv4, add it here shortly before syncing
+ * the routes. */
- routes = nm_dedup_multi_objs_to_ptr_array_head (nm_ip4_config_lookup_routes (self),
- NULL, NULL);
+ nm_ip_config_iter_ip4_address_for_each (&iter, self, &addr) {
+ nm_auto_nmpobj NMPObject *r = NULL;
+ NMPlatformIP4Route *route;
+ in_addr_t network;
- if (addresses) {
- /* For IPv6, we explicitly add the device-routes (onlink) to NMIP6Config.
- * As we don't do that for IPv4, add it here shortly before syncing
- * the routes. */
- for (i = 0; i < addresses->len; i++) {
- const NMPObject *o = addresses->pdata[i];
- const NMPlatformIP4Address *addr;
- nm_auto_nmpobj NMPObject *r = NULL;
- NMPlatformIP4Route *route;
- in_addr_t network;
-
- if (!o)
- continue;
-
- addr = NMP_OBJECT_CAST_IP4_ADDRESS (o);
- if (addr->plen == 0)
- continue;
-
- nm_assert (addr->plen <= 32);
-
- /* The destination network depends on the peer-address. */
- network = nm_utils_ip4_address_clear_host_address (addr->peer_address, addr->plen);
-
- if (_ipv4_is_zeronet (network)) {
- /* Kernel doesn't add device-routes for destinations that
- * start with 0.x.y.z. Skip them. */
- continue;
- }
+ if (addr->plen == 0)
+ continue;
+
+ nm_assert (addr->plen <= 32);
+
+ /* The destination network depends on the peer-address. */
+ network = nm_utils_ip4_address_clear_host_address (addr->peer_address, addr->plen);
+
+ if (_ipv4_is_zeronet (network)) {
+ /* Kernel doesn't add device-routes for destinations that
+ * start with 0.x.y.z. Skip them. */
+ continue;
+ }
+
+ r = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
+ route = NMP_OBJECT_CAST_IP4_ROUTE (r);
+
+ route->ifindex = ifindex;
+ route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
+ route->network = network;
+ route->plen = addr->plen;
+ route->pref_src = addr->address;
+ route->metric = default_route_metric;
+ route->scope_inv = nm_platform_route_scope_inv (NM_RT_SCOPE_LINK);
+
+ nm_platform_ip_route_normalize (AF_INET, (NMPlatformIPRoute *) route);
- r = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
- route = NMP_OBJECT_CAST_IP4_ROUTE (r);
+ if (_lookup_route (self,
+ r,
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
+ /* we already track this route. Don't add it again. */
+ } else
+ _add_route (self, nmp_object_ref (r), NULL, NULL);
- route->ifindex = ifindex;
- route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
- route->network = network;
- route->plen = addr->plen;
- route->pref_src = addr->address;
- route->metric = default_route_metric;
- route->scope_inv = nm_platform_route_scope_inv (NM_RT_SCOPE_LINK);
+ if ( out_ip4_dev_route_blacklist
+ && default_route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE) {
+ nm_auto_nmpobj NMPObject *r_dev = NULL;
+
+ r_dev = nmp_object_clone (r, FALSE);
+ route = NMP_OBJECT_CAST_IP4_ROUTE (r_dev);
+ route->metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
nm_platform_ip_route_normalize (AF_INET, (NMPlatformIPRoute *) route);
if (_lookup_route (self,
- r,
+ r_dev,
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
- /* we already track this route. Don't add it again. */
+ /* we track such a route explicitly. Don't blacklist it. */
} else {
- if (!routes)
- routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
- g_ptr_array_add (routes, (gpointer) nmp_object_ref (r));
+ if (!ip4_dev_route_blacklist)
+ ip4_dev_route_blacklist = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+
+ g_ptr_array_add (ip4_dev_route_blacklist,
+ g_steal_pointer (&r_dev));
}
+ }
+ }
- if (default_route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE) {
- nm_auto_nmpobj NMPObject *r_dev = NULL;
+ NM_SET_OUT (out_ip4_dev_route_blacklist, ip4_dev_route_blacklist);
+}
- r_dev = nmp_object_clone (r, FALSE);
- route = NMP_OBJECT_CAST_IP4_ROUTE (r_dev);
- route->metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
+gboolean
+nm_ip4_config_commit (const NMIP4Config *self,
+ NMPlatform *platform)
+{
+ gs_unref_ptrarray GPtrArray *addresses = NULL;
+ gs_unref_ptrarray GPtrArray *routes = NULL;
+ int ifindex;
+ gboolean success = TRUE;
- nm_platform_ip_route_normalize (AF_INET, (NMPlatformIPRoute *) route);
+ g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE);
- if (_lookup_route (self,
- r_dev,
- NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)) {
- /* we track such a route explicitly. Don't blacklist it. */
- } else {
- if (!ip4_dev_route_blacklist)
- ip4_dev_route_blacklist = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
+ ifindex = nm_ip4_config_get_ifindex (self);
+ g_return_val_if_fail (ifindex > 0, FALSE);
- g_ptr_array_add (ip4_dev_route_blacklist,
- g_steal_pointer (&r_dev));
- }
- }
- }
- }
+ addresses = nm_dedup_multi_objs_to_ptr_array_head (nm_ip4_config_lookup_addresses (self),
+ NULL, NULL);
+
+ routes = nm_dedup_multi_objs_to_ptr_array_head (nm_ip4_config_lookup_routes (self),
+ NULL, NULL);
nm_platform_ip4_address_sync (platform, ifindex, addresses);
@@ -836,10 +842,6 @@ nm_ip4_config_commit (const NMIP4Config *self,
NULL))
success = FALSE;
- nm_platform_ip4_dev_route_blacklist_set (platform,
- ifindex,
- ip4_dev_route_blacklist);
-
return success;
}
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index a8e22c2e59..49f119c614 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -150,9 +150,14 @@ int nm_ip4_config_get_ifindex (const NMIP4Config *self);
NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
+
+void nm_ip4_config_add_device_routes (NMIP4Config *self,
+ guint32 default_route_metric,
+ GPtrArray **out_ip4_dev_route_blacklist);
+
gboolean nm_ip4_config_commit (const NMIP4Config *self,
- NMPlatform *platform,
- guint32 default_route_metric);
+ NMPlatform *platform);
+
void nm_ip4_config_merge_setting (NMIP4Config *self, NMSettingIPConfig *setting, guint32 default_route_metric);
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *self);
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index 9e4189feb7..517e7eb97a 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -121,6 +121,8 @@ typedef struct {
NMNetns *netns;
+ GPtrArray *ip4_dev_route_blacklist;
+
GDBusProxy *proxy;
GCancellable *cancellable;
GVariant *connect_hash;
@@ -1147,9 +1149,11 @@ nm_vpn_connection_apply_config (NMVpnConnection *self)
if (priv->ip4_config) {
nm_assert (priv->ip_ifindex == nm_ip4_config_get_ifindex (priv->ip4_config));
if (!nm_ip4_config_commit (priv->ip4_config,
- nm_netns_get_platform (priv->netns),
- nm_vpn_connection_get_ip4_route_metric (self)))
+ nm_netns_get_platform (priv->netns)))
return FALSE;
+ nm_platform_ip4_dev_route_blacklist_set (nm_netns_get_platform (priv->netns),
+ priv->ip_ifindex,
+ priv->ip4_dev_route_blacklist);
}
if (priv->ip6_config) {
@@ -1601,6 +1605,12 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
nm_ip4_config_add_route (config, &r, NULL);
}
+ g_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
+
+ nm_ip4_config_add_device_routes (config,
+ nm_vpn_connection_get_ip4_route_metric (self),
+ &priv->ip4_dev_route_blacklist);
+
if (priv->ip4_config) {
nm_ip4_config_replace (priv->ip4_config, config, NULL);
g_object_unref (config);
@@ -2704,6 +2714,8 @@ dispose (GObject *object)
g_clear_pointer (&priv->connect_hash, g_variant_unref);
+ g_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
+
nm_clear_g_source (&priv->connect_timeout);
dispatcher_cleanup (self);