summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-09-28 14:40:12 +0200
committerThomas Haller <thaller@redhat.com>2017-10-09 22:06:25 +0200
commit01930c96b853f2fc776a02cd394167b99ab6a8ea (patch)
tree96c7c1755303d9bc522c8c1255bf10c12ab740bd
parentcc1ee1d286a3de84fcebc33088d12fee21145d8a (diff)
downloadNetworkManager-01930c96b853f2fc776a02cd394167b99ab6a8ea.tar.gz
core: use ipv4.route-table setting for other IPv4 routes
Including device-routes, default-route, DHCPv4, IPv4LL.
-rw-r--r--clients/common/settings-docs.c.in4
-rw-r--r--libnm-core/nm-setting-ip-config.c6
-rw-r--r--src/devices/nm-device.c6
-rw-r--r--src/devices/wwan/nm-modem-ofono.c3
-rw-r--r--src/dhcp/nm-dhcp-client.c22
-rw-r--r--src/dhcp/nm-dhcp-client.h4
-rw-r--r--src/dhcp/nm-dhcp-dhclient.c1
-rw-r--r--src/dhcp/nm-dhcp-manager.c17
-rw-r--r--src/dhcp/nm-dhcp-manager.h3
-rw-r--r--src/dhcp/nm-dhcp-systemd.c6
-rw-r--r--src/dhcp/nm-dhcp-utils.c16
-rw-r--r--src/dhcp/nm-dhcp-utils.h1
-rw-r--r--src/dhcp/tests/test-dhcp-utils.c3
-rw-r--r--src/nm-iface-helper.c3
-rw-r--r--src/nm-ip4-config.c6
-rw-r--r--src/nm-ip4-config.h1
-rw-r--r--src/vpn/nm-vpn-connection.c12
17 files changed, 94 insertions, 20 deletions
diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in
index 4860de10ad..0aea10b171 100644
--- a/clients/common/settings-docs.c.in
+++ b/clients/common/settings-docs.c.in
@@ -224,7 +224,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_NEVER_DEFAULT N_("If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.")
-#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This currently only affects static routes (ipv4.routes and ipv6.routes). However, each static route can individually overwrite the table setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTES N_("Array of IP routes.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE N_("Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are: \"eui64\", or \"stable-privacy\". If the property is set to \"eui64\", the addresses will be generated using the interface tokens derived from hardware address. This makes the host part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the interface hardware is replaced. The value of \"stable-privacy\" enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable when the network interface hardware is replaced. On D-Bus, the absence of an addr-gen-mode setting equals enabling \"stable-privacy\". For keyfile plugin, the absence of the setting on disk means \"eui64\" so that the property doesn't change on upgrade from older versions. Note that this setting is distinct from the Privacy Extensions as configured by \"ip6-privacy\" property and it does not affect the temporary addresses configured with this option.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES N_("Array of IP addresses.")
@@ -245,7 +245,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_NEVER_DEFAULT N_("If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.")
-#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This currently only affects static routes (ipv4.routes and ipv6.routes). However, each static route can individually overwrite the table setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTES N_("Array of IP routes.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_TOKEN N_("Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.")
#define DESCRIBE_DOC_NM_SETTING_MACSEC_ENCRYPT N_("Whether the transmitted traffic must be encrypted.")
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index 1ca7a0f976..f079c7522d 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -3057,9 +3057,9 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
*
* Enable policy routing (source routing) and set the routing table used when adding routes.
*
- * This currently only affects static routes (ipv4.routes and ipv6.routes). However,
- * each static route can individually overwrite the table setting by explicitly
- * specifying a non-zero routing table.
+ * This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes
+ * and static routes. But note that static routes can individually overwrite the setting
+ * by explicitly specifying a non-zero routing table.
*
* If the table setting is left at zero, it is eligible to be overwritten via global
* configuration. If the property is zero even after applying the global configuration
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 04b0d0923b..d5307377da 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -5522,6 +5522,7 @@ ipv4ll_get_ip4_config (NMDevice *self, guint32 lla)
route.network = htonl (0xE0000000L);
route.plen = 4;
route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL;
+ route.table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (self, AF_INET, TRUE));
route.metric = nm_device_get_route_metric (self, AF_INET);
nm_ip4_config_add_route (config, &route, NULL);
@@ -5865,6 +5866,7 @@ ip4_config_merge_and_apply (NMDevice *self,
memset (&default_route, 0, sizeof (default_route));
default_route.rt_source = NM_IP_CONFIG_SOURCE_USER;
default_route.gateway = gateway;
+ default_route.table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (self, AF_INET, TRUE));
default_route.metric = route_metric_with_penalty (self, default_route_metric);
default_route.mss = nm_ip4_config_get_mss (composite);
nm_clear_nmp_object (&priv->default_route4);
@@ -5892,6 +5894,7 @@ END_ADD_DEFAULT_ROUTE:
if (commit) {
nm_ip4_config_add_device_routes (composite,
+ nm_device_get_route_table (self, AF_INET, TRUE),
default_route_metric,
&ip4_dev_route_blacklist);
}
@@ -6148,6 +6151,7 @@ dhcp4_start (NMDevice *self)
nm_device_get_ip_ifindex (self),
tmp,
nm_connection_get_uuid (connection),
+ nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET),
nm_setting_ip_config_get_dhcp_send_hostname (s_ip4),
nm_setting_ip_config_get_dhcp_hostname (s_ip4),
@@ -6915,6 +6919,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection)
tmp,
&ll_addr->address,
nm_connection_get_uuid (connection),
+ nm_device_get_route_table (self, AF_INET6, TRUE),
nm_device_get_route_metric (self, AF_INET6),
nm_setting_ip_config_get_dhcp_send_hostname (s_ip6),
nm_setting_ip_config_get_dhcp_hostname (s_ip6),
@@ -10873,6 +10878,7 @@ find_ip4_lease_config (NMDevice *self,
ip_iface,
ip_ifindex,
nm_connection_get_uuid (connection),
+ nm_device_get_route_table (self, AF_INET, TRUE),
nm_device_get_route_metric (self, AF_INET));
for (liter = leases; liter && !found; liter = liter->next) {
NMIP4Config *lease_config = liter->data;
diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c
index 095f71bccc..a689550cf2 100644
--- a/src/devices/wwan/nm-modem-ofono.c
+++ b/src/devices/wwan/nm-modem-ofono.c
@@ -988,6 +988,9 @@ context_property_changed (GDBusProxy *proxy,
.metric = 1,
};
+ /* FIXME: does not handle ipv4.route-table setting and always adds the
+ * route to RT_TABLE_MAIN table. */
+
nm_ip4_config_add_route (priv->ip4_config, &mms_route, NULL);
} else {
_LOGW ("invalid MessageProxy: %s", s);
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 307108e1c2..b9d4ce72fe 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <uuid/uuid.h>
+#include <linux/rtnetlink.h>
#include "nm-utils/nm-dedup-multi.h"
@@ -56,6 +57,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_IFINDEX,
PROP_HWADDR,
PROP_UUID,
+ PROP_ROUTE_TABLE,
PROP_ROUTE_METRIC,
PROP_TIMEOUT,
);
@@ -73,6 +75,7 @@ typedef struct _NMDhcpClientPrivate {
guint watch_id;
int addr_family;
int ifindex;
+ guint32 route_table;
guint32 route_metric;
guint32 timeout;
NMDhcpState state;
@@ -151,6 +154,14 @@ nm_dhcp_client_get_hw_addr (NMDhcpClient *self)
}
guint32
+nm_dhcp_client_get_route_table (NMDhcpClient *self)
+{
+ g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), RT_TABLE_MAIN);
+
+ return NM_DHCP_CLIENT_GET_PRIVATE (self)->route_table;
+}
+
+guint32
nm_dhcp_client_get_route_metric (NMDhcpClient *self)
{
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), G_MAXUINT32);
@@ -789,6 +800,7 @@ nm_dhcp_client_handle_event (gpointer unused,
priv->ifindex,
priv->iface,
str_options,
+ priv->route_table,
priv->route_metric);
} else {
prefix = nm_dhcp_utils_ip6_prefix_from_options (str_options);
@@ -899,6 +911,10 @@ set_property (GObject *object, guint prop_id,
/* construct-only */
priv->uuid = g_value_dup_string (value);
break;
+ case PROP_ROUTE_TABLE:
+ /* construct-only */
+ priv->route_table = g_value_get_uint (value);
+ break;
case PROP_ROUTE_METRIC:
/* construct-only */
priv->route_metric = g_value_get_uint (value);
@@ -1010,6 +1026,12 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_ROUTE_TABLE] =
+ g_param_spec_uint (NM_DHCP_CLIENT_ROUTE_TABLE, "", "",
+ 0, G_MAXUINT32, RT_TABLE_MAIN,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
obj_properties[PROP_ROUTE_METRIC] =
g_param_spec_uint (NM_DHCP_CLIENT_ROUTE_METRIC, "", "",
0, G_MAXUINT32, 0,
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h
index 98f7e4ab5b..9c9be1605c 100644
--- a/src/dhcp/nm-dhcp-client.h
+++ b/src/dhcp/nm-dhcp-client.h
@@ -39,6 +39,7 @@
#define NM_DHCP_CLIENT_IFINDEX "ifindex"
#define NM_DHCP_CLIENT_HWADDR "hwaddr"
#define NM_DHCP_CLIENT_UUID "uuid"
+#define NM_DHCP_CLIENT_ROUTE_TABLE "route-table"
#define NM_DHCP_CLIENT_ROUTE_METRIC "route-metric"
#define NM_DHCP_CLIENT_TIMEOUT "timeout"
#define NM_DHCP_CLIENT_MULTI_IDX "multi-idx"
@@ -122,6 +123,8 @@ const GByteArray *nm_dhcp_client_get_duid (NMDhcpClient *self);
const GByteArray *nm_dhcp_client_get_hw_addr (NMDhcpClient *self);
+guint32 nm_dhcp_client_get_route_table (NMDhcpClient *self);
+
guint32 nm_dhcp_client_get_route_metric (NMDhcpClient *self);
guint32 nm_dhcp_client_get_timeout (NMDhcpClient *self);
@@ -185,6 +188,7 @@ typedef struct {
const char *iface,
int ifindex,
const char *uuid,
+ guint32 route_table,
guint32 route_metric);
} NMDhcpClientFactory;
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c
index 2143067c1f..6259fb5b17 100644
--- a/src/dhcp/nm-dhcp-dhclient.c
+++ b/src/dhcp/nm-dhcp-dhclient.c
@@ -164,6 +164,7 @@ nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx,
const char *iface,
int ifindex,
const char *uuid,
+ guint32 route_table,
guint32 route_metric)
{
char *contents = NULL;
diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c
index 9614fb021c..f5c7c84b76 100644
--- a/src/dhcp/nm-dhcp-manager.c
+++ b/src/dhcp/nm-dhcp-manager.c
@@ -158,6 +158,7 @@ client_start (NMDhcpManager *self,
int ifindex,
const GByteArray *hwaddr,
const char *uuid,
+ guint32 route_table,
guint32 route_metric,
const struct in6_addr *ipv6_ll_addr,
const char *dhcp_client_id,
@@ -202,7 +203,8 @@ client_start (NMDhcpManager *self,
NM_DHCP_CLIENT_IFINDEX, ifindex,
NM_DHCP_CLIENT_HWADDR, hwaddr,
NM_DHCP_CLIENT_UUID, uuid,
- NM_DHCP_CLIENT_ROUTE_METRIC, route_metric,
+ NM_DHCP_CLIENT_ROUTE_TABLE, (guint) route_table,
+ NM_DHCP_CLIENT_ROUTE_METRIC, (guint) route_metric,
NM_DHCP_CLIENT_TIMEOUT, (guint) timeout,
NULL);
g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client));
@@ -229,6 +231,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
int ifindex,
const GByteArray *hwaddr,
const char *uuid,
+ guint32 route_table,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
@@ -270,7 +273,8 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
}
}
- return client_start (self, AF_INET, multi_idx, iface, ifindex, hwaddr, uuid, route_metric, NULL,
+ return client_start (self, AF_INET, multi_idx, iface, ifindex, hwaddr, uuid,
+ route_table, route_metric, NULL,
dhcp_client_id, timeout, dhcp_anycast_addr, hostname,
use_fqdn, FALSE, 0, last_ip_address, 0);
}
@@ -284,6 +288,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
const GByteArray *hwaddr,
const struct in6_addr *ll_addr,
const char *uuid,
+ guint32 route_table,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
@@ -303,8 +308,9 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
/* Always prefer the explicit dhcp-hostname if given */
hostname = dhcp_hostname ? dhcp_hostname : priv->default_hostname;
}
- return client_start (self, AF_INET6, multi_idx, iface, ifindex, hwaddr, uuid, route_metric,
- ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only,
+ return client_start (self, AF_INET6, multi_idx, iface, ifindex, hwaddr, uuid,
+ route_table, route_metric, ll_addr,
+ NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only,
privacy, NULL, needed_prefixes);
}
@@ -329,6 +335,7 @@ nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self,
const char *iface,
int ifindex,
const char *uuid,
+ guint32 route_table,
guint32 route_metric)
{
NMDhcpManagerPrivate *priv;
@@ -342,7 +349,7 @@ nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self,
priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
if ( priv->client_factory
&& priv->client_factory->get_lease_ip_configs)
- return priv->client_factory->get_lease_ip_configs (multi_idx, addr_family, iface, ifindex, uuid, route_metric);
+ return priv->client_factory->get_lease_ip_configs (multi_idx, addr_family, iface, ifindex, uuid, route_table, route_metric);
return NULL;
}
diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h
index 57fbd4a7e5..6e9bcaf6e8 100644
--- a/src/dhcp/nm-dhcp-manager.h
+++ b/src/dhcp/nm-dhcp-manager.h
@@ -51,6 +51,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager,
int ifindex,
const GByteArray *hwaddr,
const char *uuid,
+ guint32 route_table,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
@@ -67,6 +68,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager,
const GByteArray *hwaddr,
const struct in6_addr *ll_addr,
const char *uuid,
+ guint32 route_table,
guint32 route_metric,
gboolean send_hostname,
const char *dhcp_hostname,
@@ -82,6 +84,7 @@ GSList * nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self,
const char *iface,
int ifindex,
const char *uuid,
+ guint32 route_table,
guint32 route_metric);
/* For testing only */
diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c
index 3cf95cec54..5e0370db55 100644
--- a/src/dhcp/nm-dhcp-systemd.c
+++ b/src/dhcp/nm-dhcp-systemd.c
@@ -221,6 +221,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
int ifindex,
sd_dhcp_lease *lease,
GHashTable *options,
+ guint32 route_table,
guint32 route_metric,
gboolean log_lease,
GError **error)
@@ -357,6 +358,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
if (route.plen) {
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = route_metric;
+ route.table_coerced = nm_platform_route_table_coerce (route_table);
nm_ip4_config_add_route (ip4_config, &route, NULL);
s = nm_utils_inet4_ntop (route.network, buf);
@@ -440,6 +442,7 @@ nm_dhcp_systemd_get_lease_ip_configs (NMDedupMultiIndex *multi_idx,
const char *iface,
int ifindex,
const char *uuid,
+ guint32 route_table,
guint32 route_metric)
{
GSList *leases = NULL;
@@ -454,7 +457,7 @@ nm_dhcp_systemd_get_lease_ip_configs (NMDedupMultiIndex *multi_idx,
path = get_leasefile_path (addr_family, iface, uuid);
r = dhcp_lease_load (&lease, path);
if (r == 0 && lease) {
- ip4_config = lease_to_ip4_config (multi_idx, iface, ifindex, lease, NULL, route_metric, FALSE, NULL);
+ ip4_config = lease_to_ip4_config (multi_idx, iface, ifindex, lease, NULL, route_table, route_metric, FALSE, NULL);
if (ip4_config)
leases = g_slist_append (leases, ip4_config);
sd_dhcp_lease_unref (lease);
@@ -513,6 +516,7 @@ bound4_handle (NMDhcpSystemd *self)
nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)),
lease,
options,
+ nm_dhcp_client_get_route_table (NM_DHCP_CLIENT (self)),
nm_dhcp_client_get_route_metric (NM_DHCP_CLIENT (self)),
TRUE,
&error);
diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c
index 7c5f1b9784..9e1e75a470 100644
--- a/src/dhcp/nm-dhcp-utils.c
+++ b/src/dhcp/nm-dhcp-utils.c
@@ -38,6 +38,7 @@
static gboolean
ip4_process_dhcpcd_rfc3442_routes (const char *iface,
const char *str,
+ guint32 route_table,
guint32 route_metric,
NMIP4Config *ip4_config,
guint32 *gwaddr)
@@ -91,6 +92,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *iface,
route.gateway = rt_route;
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = route_metric;
+ route.table_coerced = nm_platform_route_table_coerce (route_table);
nm_ip4_config_add_route (ip4_config, &route, NULL);
}
}
@@ -166,6 +168,7 @@ error:
static gboolean
ip4_process_dhclient_rfc3442_routes (const char *iface,
const char *str,
+ guint32 route_table,
guint32 route_metric,
NMIP4Config *ip4_config,
guint32 *gwaddr)
@@ -199,6 +202,7 @@ ip4_process_dhclient_rfc3442_routes (const char *iface,
/* normal route */
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = route_metric;
+ route.table_coerced = nm_platform_route_table_coerce (route_table);
nm_ip4_config_add_route (ip4_config, &route, NULL);
_LOG2I (LOGD_DHCP4, iface, " classless static route %s/%d gw %s",
@@ -215,6 +219,7 @@ out:
static gboolean
ip4_process_classless_routes (const char *iface,
GHashTable *options,
+ guint32 route_table,
guint32 route_metric,
NMIP4Config *ip4_config,
guint32 *gwaddr)
@@ -271,15 +276,16 @@ ip4_process_classless_routes (const char *iface,
if (strchr (str, '/')) {
/* dhcpcd format */
- return ip4_process_dhcpcd_rfc3442_routes (iface, str, route_metric, ip4_config, gwaddr);
+ return ip4_process_dhcpcd_rfc3442_routes (iface, str, route_table, route_metric, ip4_config, gwaddr);
}
- return ip4_process_dhclient_rfc3442_routes (iface, str, route_metric, ip4_config, gwaddr);
+ return ip4_process_dhclient_rfc3442_routes (iface, str, route_table, route_metric, ip4_config, gwaddr);
}
static void
process_classful_routes (const char *iface,
GHashTable *options,
+ guint32 route_table,
guint32 route_metric,
NMIP4Config *ip4_config)
{
@@ -325,6 +331,7 @@ process_classful_routes (const char *iface,
route.gateway = rt_route;
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
route.metric = route_metric;
+ route.table_coerced = nm_platform_route_table_coerce (route_table);
route.network = nm_utils_ip4_address_clear_host_address (route.network, route.plen);
@@ -390,6 +397,7 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
int ifindex,
const char *iface,
GHashTable *options,
+ guint32 route_table,
guint32 route_metric)
{
NMIP4Config *ip4_config = NULL;
@@ -426,8 +434,8 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
/* Routes: if the server returns classless static routes, we MUST ignore
* the 'static_routes' option.
*/
- if (!ip4_process_classless_routes (iface, options, route_metric, ip4_config, &gwaddr))
- process_classful_routes (iface, options, route_metric, ip4_config);
+ if (!ip4_process_classless_routes (iface, options, route_table, route_metric, ip4_config, &gwaddr))
+ process_classful_routes (iface, options, route_table, route_metric, ip4_config);
if (gwaddr) {
_LOG2I (LOGD_DHCP4, iface, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL));
diff --git a/src/dhcp/nm-dhcp-utils.h b/src/dhcp/nm-dhcp-utils.h
index b2757ed27c..32140f481d 100644
--- a/src/dhcp/nm-dhcp-utils.h
+++ b/src/dhcp/nm-dhcp-utils.h
@@ -28,6 +28,7 @@ NMIP4Config *nm_dhcp_utils_ip4_config_from_options (struct _NMDedupMultiIndex *m
int ifindex,
const char *iface,
GHashTable *options,
+ guint32 route_table,
guint32 route_metric);
NMIP6Config *nm_dhcp_utils_ip6_config_from_options (struct _NMDedupMultiIndex *multi_idx,
diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c
index 907fb5d892..1ffadcd810 100644
--- a/src/dhcp/tests/test-dhcp-utils.c
+++ b/src/dhcp/tests/test-dhcp-utils.c
@@ -22,6 +22,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
+#include <linux/rtnetlink.h>
#include "nm-utils/nm-dedup-multi.h"
#include "nm-utils.h"
@@ -40,7 +41,7 @@ _ip4_config_from_options (int ifindex,
nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new ();
NMIP4Config *config;
- config = nm_dhcp_utils_ip4_config_from_options (multi_idx, ifindex, iface, options, route_metric);
+ config = nm_dhcp_utils_ip4_config_from_options (multi_idx, ifindex, iface, options, RT_TABLE_MAIN, route_metric);
g_assert (config);
return config;
}
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 7f32ef6dc7..66bebbbc6f 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -31,6 +31,7 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <signal.h>
+#include <linux/rtnetlink.h>
#include "main-utils.h"
#include "NetworkManagerUtils.h"
@@ -125,6 +126,7 @@ dhcp4_state_changed (NMDhcpClient *client,
nm_ip4_config_merge (existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
nm_ip4_config_add_device_routes (existing,
+ RT_TABLE_MAIN,
global_opt.priority_v4,
&ip4_dev_route_blacklist);
if (!nm_ip4_config_commit (existing,
@@ -454,6 +456,7 @@ main (int argc, char *argv[])
gl.ifindex,
hwaddr,
global_opt.uuid,
+ RT_TABLE_MAIN,
global_opt.priority_v4,
!!global_opt.dhcp4_hostname,
global_opt.dhcp4_hostname,
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 498d60dbec..fe32358081 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -675,6 +675,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
void
nm_ip4_config_add_device_routes (NMIP4Config *self,
+ guint32 route_table,
guint32 route_metric,
GPtrArray **out_ip4_dev_route_blacklist)
{
@@ -721,6 +722,7 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
route->network = network;
route->plen = addr->plen;
route->pref_src = addr->address;
+ route->table_coerced = nm_platform_route_table_coerce (route_table);
route->metric = route_metric;
route->scope_inv = nm_platform_route_scope_inv (NM_RT_SCOPE_LINK);
@@ -734,11 +736,13 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
_add_route (self, nmp_object_ref (r), NULL, NULL);
if ( out_ip4_dev_route_blacklist
- && route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE) {
+ && ( route_table != RT_TABLE_MAIN
+ || 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->table_coerced = nm_platform_route_table_coerce (RT_TABLE_MAIN);
route->metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
nm_platform_ip_route_normalize (AF_INET, (NMPlatformIPRoute *) route);
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 68c9ef30a8..230cee6a1b 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -152,6 +152,7 @@ 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 route_table,
guint32 route_metric,
GPtrArray **out_ip4_dev_route_blacklist);
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index d19007c1e0..1ace03ae35 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -741,8 +741,9 @@ add_ip4_vpn_gateway_route (NMIP4Config *config,
* In which case, it pretends the destination is directly reachable.
*
* So, only accept direct routes, if @vpn_gw is a private network. */
- if ( r->gateway
- || nm_utils_ip_is_site_local (AF_INET, &vpn_gw)) {
+ if ( nm_platform_route_table_is_main (r->table_coerced)
+ && ( r->gateway
+ || nm_utils_ip_is_site_local (AF_INET, &vpn_gw))) {
parent_gw = r->gateway;
has_parent_gw = TRUE;
}
@@ -1472,6 +1473,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
NMPlatformIP4Address address;
NMIP4Config *config;
guint32 u32, route_metric;
+ guint32 route_table;
GVariantIter *iter;
const char *str;
GVariant *v;
@@ -1571,6 +1573,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
g_variant_iter_free (iter);
}
+ route_table = get_route_table (self, AF_INET, TRUE);
route_metric = nm_vpn_connection_get_ip4_route_metric (self);
if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b)
@@ -1596,6 +1599,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
g_variant_get_child (v, 1, "u", &plen);
g_variant_get_child (v, 2, "u", &route.gateway);
/* 4th item is unused route metric */
+ route.table_coerced = nm_platform_route_table_coerce (route_table);
route.metric = route_metric;
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
@@ -1626,7 +1630,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
/* Merge in user overrides from the NMConnection's IPv4 setting */
nm_ip4_config_merge_setting (config,
nm_connection_get_setting_ip4_config (_get_applied_connection (self)),
- get_route_table (self, AF_INET, TRUE),
+ route_table,
route_metric);
if (!nm_ip4_config_get_never_default (config)) {
@@ -1634,6 +1638,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
.ifindex = ip_ifindex,
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
.gateway = nm_ip4_config_get_gateway (config),
+ .table_coerced = nm_platform_route_table_coerce (route_table),
.metric = route_metric,
.mss = nm_ip4_config_get_mss (config),
};
@@ -1644,6 +1649,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
g_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
nm_ip4_config_add_device_routes (config,
+ route_table,
nm_vpn_connection_get_ip4_route_metric (self),
&priv->ip4_dev_route_blacklist);