summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-09-13 17:42:41 +0200
committerThomas Haller <thaller@redhat.com>2017-09-26 11:47:54 +0200
commit5fec3f32e5d01d2cf5d9b79ac510d79f89ec12e1 (patch)
tree52b5ddf327135108285dcb573a74d01d365da731
parentec51853492cad913bd70a0b05d7a1c887a234adf (diff)
downloadNetworkManager-th/policy-routing-pt1-rh1436531.tar.gz
libnm,core: add TABLE attribute for routes settingsth/policy-routing-pt1-rh1436531
https://bugzilla.redhat.com/show_bug.cgi?id=1436531
-rw-r--r--libnm-core/nm-setting-ip-config.c1
-rw-r--r--libnm-core/nm-setting-ip-config.h1
-rw-r--r--src/devices/nm-device.c44
-rw-r--r--src/nm-core-utils.h2
-rw-r--r--src/nm-iface-helper.c8
-rw-r--r--src/nm-ip4-config.c21
-rw-r--r--src/nm-ip4-config.h3
-rw-r--r--src/nm-ip6-config.c19
-rw-r--r--src/nm-ip6-config.h1
-rw-r--r--src/platform/nm-linux-platform.c11
-rw-r--r--src/platform/nm-platform.c72
-rw-r--r--src/platform/nm-platform.h3
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c8
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c2
-rw-r--r--src/vpn/nm-vpn-connection.c32
15 files changed, 189 insertions, 39 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index ce46cd8cb6..d06457bbe6 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -1187,6 +1187,7 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
&(NMVariantAttributeSpec) { name, type, v4, v6, str_type }
static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
+ ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, FALSE, TRUE, 'p'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, FALSE, 0 ),
diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h
index c933c28735..a3e4007c9e 100644
--- a/libnm-core/nm-setting-ip-config.h
+++ b/libnm-core/nm-setting-ip-config.h
@@ -131,6 +131,7 @@ gboolean nm_ip_route_attribute_validate (const char *name,
gboolean *known,
GError **error);
+#define NM_IP_ROUTE_ATTRIBUTE_TABLE "table"
#define NM_IP_ROUTE_ATTRIBUTE_SRC "src"
#define NM_IP_ROUTE_ATTRIBUTE_FROM "from"
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index e20f7fb478..86e2f9d36d 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1700,6 +1700,46 @@ out:
return nm_utils_ip_route_metric_normalize (addr_family, route_metric);
}
+static NMIPRouteTableSyncMode
+get_route_table_sync (NMDevice *self, int addr_family)
+{
+ NMConnection *connection;
+ NMSettingIPConfig *s_ip;
+ NMIPRouteTableSyncMode route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT;
+
+ nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+
+ connection = nm_device_get_applied_connection (self);
+ if (connection) {
+ if (addr_family == AF_INET)
+ s_ip = nm_connection_get_setting_ip4_config (connection);
+ else
+ s_ip = nm_connection_get_setting_ip6_config (connection);
+
+ if (s_ip)
+ route_table_sync = nm_setting_ip_config_get_route_table_sync (s_ip);
+ }
+
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT) {
+ gs_free char *value = NULL;
+
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ addr_family == AF_INET
+ ? "ipv4.route-table-sync"
+ : "ipv6.route-table-sync",
+ self);
+ route_table_sync = _nm_utils_ascii_str_to_int64 (value, 10,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT);
+
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT)
+ route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN;
+ }
+
+ return route_table_sync;
+}
+
const NMPObject *
nm_device_get_best_default_route (NMDevice *self,
int addr_family)
@@ -9902,7 +9942,8 @@ 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));
+ nm_device_get_platform (self),
+ get_route_table_sync (self, AF_INET));
nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self),
nm_ip4_config_get_ifindex (new_config),
ip4_dev_route_blacklist);
@@ -10075,6 +10116,7 @@ nm_device_set_ip6_config (NMDevice *self,
success = nm_ip6_config_commit (new_config,
nm_device_get_platform (self),
+ get_route_table_sync (self, AF_INET6),
&temporary_not_available);
if (!_rt6_temporary_not_available_set (self, temporary_not_available))
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 2561b6ec6b..256e699b54 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -31,6 +31,8 @@
#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32
+#define NM_IP_ROUTE_TABLE_SYNC_MODE_ALL ((NMIPRouteTableSyncMode) -1)
+
#define NM_DEFINE_SINGLETON_INSTANCE(TYPE) \
static TYPE *singleton_instance
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 873b6c9668..7f32ef6dc7 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -128,7 +128,8 @@ dhcp4_state_changed (NMDhcpClient *client,
global_opt.priority_v4,
&ip4_dev_route_blacklist);
if (!nm_ip4_config_commit (existing,
- NM_PLATFORM_GET))
+ NM_PLATFORM_GET,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN))
_LOGW (LOGD_DHCP4, "failed to apply DHCPv4 config");
nm_platform_ip4_dev_route_blacklist_set (NM_PLATFORM_GET,
@@ -228,7 +229,10 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT);
nm_ip6_config_add_device_routes (existing,
global_opt.priority_v6);
- if (!nm_ip6_config_commit (existing, NM_PLATFORM_GET, NULL))
+ if (!nm_ip6_config_commit (existing,
+ NM_PLATFORM_GET,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
+ NULL))
_LOGW (LOGD_IP6, "failed to apply IPv6 config");
}
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index b1fe9097c8..91e72686a4 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -705,8 +705,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
priv->has_gateway = TRUE;
}
- if (route->table_coerced)
- continue;
_add_route (self, plobj, NULL, NULL);
}
@@ -821,7 +819,8 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
gboolean
nm_ip4_config_commit (const NMIP4Config *self,
- NMPlatform *platform)
+ NMPlatform *platform,
+ NMIPRouteTableSyncMode route_table_sync)
{
gs_unref_ptrarray GPtrArray *addresses = NULL;
gs_unref_ptrarray GPtrArray *routes = NULL;
@@ -842,7 +841,8 @@ nm_ip4_config_commit (const NMIP4Config *self,
routes_prune = nm_platform_ip_route_get_prune_list (platform,
AF_INET,
- ifindex);
+ ifindex,
+ route_table_sync);
nm_platform_ip4_address_sync (platform, ifindex, addresses);
@@ -868,6 +868,10 @@ merge_route_attributes (NMIPRoute *s_route, NMPlatformIP4Route *r)
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_ ## variant_type)) \
r->field = g_variant_get_ ## type (variant);
+ r->table_coerced = 254 /* RT_TABLE_MAIN */;
+ GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, table_coerced, UINT32, uint32);
+ r->table_coerced = nm_platform_route_table_coerce (r->table_coerced);
+
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TOS, tos, BYTE, byte);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, window, UINT32, uint32);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, cwnd, UINT32, uint32);
@@ -3050,11 +3054,18 @@ out_addresses_cached:
"metric",
g_variant_new_uint32 (route->metric));
+ if (!nm_platform_route_table_is_main (route->table_coerced)) {
+ g_variant_builder_add (&route_builder, "{sv}",
+ "table",
+ g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE)));
+ }
+
g_variant_builder_add (&builder_data, "a{sv}", &route_builder);
/* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the
* plen is positive. Skip the default routes not to break older clients. */
- if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
+ if ( nm_platform_route_table_is_main (route->table_coerced)
+ && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
const guint32 dbus_route[4] = {
route->network,
route->plen,
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 49f119c614..fcd04beaa5 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -156,7 +156,8 @@ void nm_ip4_config_add_device_routes (NMIP4Config *self,
GPtrArray **out_ip4_dev_route_blacklist);
gboolean nm_ip4_config_commit (const NMIP4Config *self,
- NMPlatform *platform);
+ NMPlatform *platform,
+ NMIPRouteTableSyncMode route_table_sync);
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/nm-ip6-config.c b/src/nm-ip6-config.c
index 1c0094d94c..699c60d3b2 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -502,8 +502,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
has_gateway = TRUE;
}
- if (route->table_coerced)
- continue;
_add_route (self, plobj, NULL, NULL);
}
@@ -604,6 +602,7 @@ nm_ip6_config_add_device_routes (NMIP6Config *self,
gboolean
nm_ip6_config_commit (const NMIP6Config *self,
NMPlatform *platform,
+ NMIPRouteTableSyncMode route_table_sync,
GPtrArray **out_temporary_not_available)
{
gs_unref_ptrarray GPtrArray *addresses = NULL;
@@ -625,7 +624,8 @@ nm_ip6_config_commit (const NMIP6Config *self,
routes_prune = nm_platform_ip_route_get_prune_list (platform,
AF_INET6,
- ifindex);
+ ifindex,
+ route_table_sync);
nm_platform_ip6_address_sync (platform, ifindex, addresses, TRUE);
@@ -651,6 +651,10 @@ merge_route_attributes (NMIPRoute *s_route, NMPlatformIP6Route *r)
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_ ## variant_type)) \
r->field = g_variant_get_ ## type (variant);
+ r->table_coerced = 254 /* RT_TABLE_MAIN */;
+ GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_TABLE, table_coerced, UINT32, uint32);
+ r->table_coerced = nm_platform_route_table_coerce (r->table_coerced);
+
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, window, UINT32, uint32);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_CWND, cwnd, UINT32, uint32);
GET_ATTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, initcwnd, UINT32, uint32);
@@ -2714,11 +2718,18 @@ out_addresses_cached:
"metric",
g_variant_new_uint32 (route->metric));
+ if (!nm_platform_route_table_is_main (route->table_coerced)) {
+ g_variant_builder_add (&route_builder, "{sv}",
+ "table",
+ g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE)));
+ }
+
g_variant_builder_add (&builder_data, "a{sv}", &route_builder);
/* legacy versions of nm_ip6_route_set_prefix() in libnm-util assert that the
* plen is positive. Skip the default routes not to break older clients. */
- if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
+ if ( nm_platform_route_table_is_main (route->table_coerced)
+ && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
g_variant_builder_add (&builder_legacy, "(@ayu@ayu)",
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
&route->network, 16, 1),
diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h
index 03dee47b27..ef828d5c0d 100644
--- a/src/nm-ip6-config.h
+++ b/src/nm-ip6-config.h
@@ -113,6 +113,7 @@ void nm_ip6_config_add_device_routes (NMIP6Config *self,
gboolean nm_ip6_config_commit (const NMIP6Config *self,
NMPlatform *platform,
+ NMIPRouteTableSyncMode route_table_sync,
GPtrArray **out_temporary_not_available);
void nm_ip6_config_merge_setting (NMIP6Config *self, NMSettingIPConfig *setting, guint32 default_route_metric);
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *self);
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 7245d16e77..0ce4ab31ab 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -1988,6 +1988,7 @@ static NMPObject *
_new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
{
static struct nla_policy policy[RTA_MAX+1] = {
+ [RTA_TABLE] = { .type = NLA_U32 },
[RTA_IIF] = { .type = NLA_U32 },
[RTA_OIF] = { .type = NLA_U32 },
[RTA_PRIORITY] = { .type = NLA_U32 },
@@ -2010,7 +2011,6 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
} nh;
guint32 mss;
guint32 window = 0, cwnd = 0, initcwnd = 0, initrwnd = 0, mtu = 0, lock = 0;
- guint32 table;
if (!nlmsg_valid_hdr (nlh, sizeof (*rtm)))
return NULL;
@@ -2030,10 +2030,6 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
if (err < 0)
goto errout;
- table = tb[RTA_TABLE]
- ? nla_get_u32 (tb[RTA_TABLE])
- : (guint32) rtm->rtm_table;
-
/*****************************************************************/
is_v4 = rtm->rtm_family == AF_INET;
@@ -2149,7 +2145,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
obj = nmp_object_new (is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
- obj->ip_route.table_coerced = nm_platform_route_table_coerce (table);
+ obj->ip_route.table_coerced = nm_platform_route_table_coerce ( tb[RTA_TABLE]
+ ? nla_get_u32 (tb[RTA_TABLE])
+ : (guint32) rtm->rtm_table);
+
obj->ip_route.ifindex = nh.ifindex;
if (_check_addr_or_errout (tb, RTA_DST, addr_len))
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 824c27a852..61c4b95572 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -3592,18 +3592,56 @@ _err_inval_due_to_ipv6_tentative_pref_src (NMPlatform *self, const NMPObject *ob
GPtrArray *
nm_platform_ip_route_get_prune_list (NMPlatform *self,
int addr_family,
- int ifindex)
+ int ifindex,
+ NMIPRouteTableSyncMode route_table_sync)
{
+ NMPLookup lookup;
+ GPtrArray *routes_prune;
+ const NMDedupMultiHeadEntry *head_entry;
+ CList *iter;
+
nm_assert (NM_IS_PLATFORM (self));
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+ nm_assert (NM_IN_SET (route_table_sync, NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL));
+
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_NONE)
+ return NULL;
+
+ nmp_lookup_init_addrroute (&lookup,
+ addr_family == AF_INET
+ ? NMP_OBJECT_TYPE_IP4_ROUTE
+ : NMP_OBJECT_TYPE_IP6_ROUTE,
+ ifindex);
+ head_entry = nm_platform_lookup (self, &lookup);
+ if (!head_entry)
+ return NULL;
+
+ routes_prune = g_ptr_array_new_full (head_entry->len,
+ (GDestroyNotify) nm_dedup_multi_obj_unref);
+
+ c_list_for_each (iter, &head_entry->lst_entries_head) {
+ const NMPObject *obj = c_list_entry (iter, NMDedupMultiEntry, lst_entries)->obj;
- return nm_platform_lookup_addrroute_clone (self,
- addr_family == AF_INET
- ? NMP_OBJECT_TYPE_IP4_ROUTE
- : NMP_OBJECT_TYPE_IP6_ROUTE,
- ifindex,
- nm_platform_lookup_predicate_routes_main,
- NULL);
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_FULL) {
+ if (nm_platform_route_table_uncoerce (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced, TRUE) == (RT_TABLE_LOCAL))
+ continue;
+ } else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) {
+ if (!nm_platform_route_table_is_main (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced))
+ continue;
+ } else
+ nm_assert (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
+
+ g_ptr_array_add (routes_prune, (gpointer) nmp_object_ref (obj));
+ }
+
+ if (routes_prune->len == 0) {
+ g_ptr_array_unref (routes_prune);
+ return NULL;
+ }
+ return routes_prune;
}
/**
@@ -3800,21 +3838,19 @@ nm_platform_ip_route_flush (NMPlatform *self,
if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET)) {
gs_unref_ptrarray GPtrArray *routes_prune = NULL;
- routes_prune = nm_platform_lookup_addrroute_clone (self,
- NMP_OBJECT_TYPE_IP4_ROUTE,
- ifindex,
- NULL,
- NULL);
+ routes_prune = nm_platform_ip_route_get_prune_list (self,
+ AF_INET,
+ ifindex,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
success &= nm_platform_ip_route_sync (self, AF_INET, ifindex, NULL, routes_prune, NULL);
}
if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET6)) {
gs_unref_ptrarray GPtrArray *routes_prune = NULL;
- routes_prune = nm_platform_lookup_addrroute_clone (self,
- NMP_OBJECT_TYPE_IP6_ROUTE,
- ifindex,
- NULL,
- NULL);
+ routes_prune = nm_platform_ip_route_get_prune_list (self,
+ AF_INET6,
+ ifindex,
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
success &= nm_platform_ip_route_sync (self, AF_INET6, ifindex, NULL, routes_prune, NULL);
}
return success;
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 72b061edd2..0f953f122d 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -1219,7 +1219,8 @@ gboolean nm_platform_ip_route_delete (NMPlatform *self, const NMPObject *route);
GPtrArray *nm_platform_ip_route_get_prune_list (NMPlatform *self,
int addr_family,
- int ifindex);
+ int ifindex,
+ NMIPRouteTableSyncMode route_table_sync);
gboolean nm_platform_ip_route_sync (NMPlatform *self,
int addr_family,
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index dc2c408906..f2ac73fb5d 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -468,6 +468,7 @@ typedef struct {
enum {
/* route attributes */
+ PARSE_LINE_ATTR_ROUTE_TABLE,
PARSE_LINE_ATTR_ROUTE_SRC,
PARSE_LINE_ATTR_ROUTE_FROM,
PARSE_LINE_ATTR_ROUTE_TOS,
@@ -530,6 +531,8 @@ parse_route_line (const char *line,
char buf1[256];
char buf2[256];
ParseLineInfo infos[] = {
+ [PARSE_LINE_ATTR_ROUTE_TABLE] = { .key = NM_IP_ROUTE_ATTRIBUTE_TABLE,
+ .type = PARSE_LINE_TYPE_UINT32, },
[PARSE_LINE_ATTR_ROUTE_SRC] = { .key = NM_IP_ROUTE_ATTRIBUTE_SRC,
.type = PARSE_LINE_TYPE_ADDR, },
[PARSE_LINE_ATTR_ROUTE_FROM] = { .key = NM_IP_ROUTE_ATTRIBUTE_FROM,
@@ -816,6 +819,11 @@ next:
info->key,
g_variant_new_byte (info->v.uint8));
break;
+ case PARSE_LINE_TYPE_UINT32:
+ nm_ip_route_set_attribute (route,
+ info->key,
+ g_variant_new_uint32 (info->v.uint32));
+ break;
case PARSE_LINE_TYPE_UINT32_WITH_LOCK:
if (info->v.uint32_with_lock.lock) {
nm_ip_route_set_attribute (route,
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 658526abe9..58b65ec03e 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -1868,6 +1868,8 @@ get_route_attributes_string (NMIPRoute *route, int family)
}
} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) {
g_string_append_printf (str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte (attr));
+ } else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TABLE)) {
+ g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_uint32 (attr));
} else if ( nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC)
|| nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_FROM)) {
char *arg = nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SRC) ? "src" : "from";
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index e0f6698ef3..acb8228d74 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -186,6 +186,8 @@ static void get_secrets (NMVpnConnection *self,
SecretsReq secrets_idx,
const char **hints);
+static NMIPRouteTableSyncMode get_route_table_sync (NMVpnConnection *self, int addr_family);
+
static void plugin_interactive_secrets_required (NMVpnConnection *self,
const char *message,
const char **secrets);
@@ -1149,7 +1151,8 @@ 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_netns_get_platform (priv->netns),
+ get_route_table_sync (self, AF_INET)))
return FALSE;
nm_platform_ip4_dev_route_blacklist_set (nm_netns_get_platform (priv->netns),
priv->ip_ifindex,
@@ -1160,6 +1163,7 @@ nm_vpn_connection_apply_config (NMVpnConnection *self)
nm_assert (priv->ip_ifindex == nm_ip6_config_get_ifindex (priv->ip6_config));
if (!nm_ip6_config_commit (priv->ip6_config,
nm_netns_get_platform (priv->netns),
+ get_route_table_sync (self, AF_INET6),
NULL))
return FALSE;
}
@@ -1431,6 +1435,32 @@ nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *self)
return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT;
}
+static NMIPRouteTableSyncMode
+get_route_table_sync (NMVpnConnection *self, int addr_family)
+{
+ NMConnection *connection;
+ NMSettingIPConfig *s_ip;
+ NMIPRouteTableSyncMode route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT;
+
+ nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
+
+ connection = _get_applied_connection (self);
+ if (connection) {
+ if (addr_family == AF_INET)
+ s_ip = nm_connection_get_setting_ip4_config (connection);
+ else
+ s_ip = nm_connection_get_setting_ip6_config (connection);
+
+ if (s_ip)
+ route_table_sync = nm_setting_ip_config_get_route_table_sync (s_ip);
+ }
+
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_DEFAULT)
+ route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN;
+
+ return route_table_sync;
+}
+
static void
nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
{