diff options
author | Thomas Haller <thaller@redhat.com> | 2017-08-21 23:17:12 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-08-24 10:55:51 +0200 |
commit | 10ac675299cb3d734ae9bb720919dff1d4f1abbf (patch) | |
tree | fc5188d452942369fc6fd5fa6182715ef2248cf5 | |
parent | 538a0dd2dc6da24bf068ea36aa95455ecb787d30 (diff) | |
download | NetworkManager-10ac675299cb3d734ae9bb720919dff1d4f1abbf.tar.gz |
platform: add support for routing tables to platform cache
The upper layers still ignore all routes outside the main table.
For now, just add support to NMPlatform.
-rw-r--r-- | src/devices/nm-device.c | 12 | ||||
-rw-r--r-- | src/nm-default-route-manager.c | 4 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 2 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 2 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 9 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 26 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 30 | ||||
-rw-r--r-- | src/platform/tests/test-common.h | 4 |
8 files changed, 74 insertions, 15 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 79738891b9..b7ff53d406 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2825,7 +2825,8 @@ _v4_has_shadowed_routes_detect (NMDevice *self) nm_assert (r->ifindex == ifindex); - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)) + if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r) + || r->table_coerced) continue; d = &data_arr[data_len++]; @@ -2845,7 +2846,8 @@ _v4_has_shadowed_routes_detect (NMDevice *self) IP4RPFilterData d; if ( r->ifindex == ifindex - || NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)) + || NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r) + || r->table_coerced) continue; d.network = nm_utils_ip4_address_clear_host_address (r->network, r->plen); @@ -5537,9 +5539,9 @@ _device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlat guint32 m; const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE (plobj); - if (r->ifindex != ifindex) - continue; - if (r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) + if ( r->ifindex != ifindex + || r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL + || r->table_coerced) continue; /* if there are several default routes, find the one with the best metric */ diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index 1f6342ccce..ea0eeeaa63 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -334,7 +334,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self, routes = nm_platform_lookup_route_default_clone (priv->platform, vtable->vt->obj_type, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL); if (!routes) return FALSE; @@ -515,7 +515,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c routes = nm_platform_lookup_route_default_clone (priv->platform, vtable->vt->obj_type, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL); assumed_metrics = _get_assumed_interface_metrics (vtable, self, routes); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 606bb342fc..cd3b9a8c14 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -820,7 +820,7 @@ nm_ip4_config_commit (const NMIP4Config *self, AF_INET, ifindex, routes, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL)) success = FALSE; diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 9f9e345637..d95398f6bb 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -538,7 +538,7 @@ nm_ip6_config_commit (const NMIP6Config *self, AF_INET6, ifindex, routes, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL)) success = FALSE; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 03585ab0d6..4ca3d94580 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2030,8 +2030,6 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) table = tb[RTA_TABLE] ? nla_get_u32 (tb[RTA_TABLE]) : (guint32) rtm->rtm_table; - if (table != RT_TABLE_MAIN) - goto errout; /*****************************************************************/ @@ -2148,6 +2146,7 @@ _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.ifindex = nh.ifindex; if (_check_addr_or_errout (tb, RTA_DST, addr_len)) @@ -2592,12 +2591,13 @@ _nl_msg_new_route (int nlmsg_type, const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj); gboolean is_v4 = klass->addr_family == AF_INET; const guint32 lock = ip_route_get_lock_flag (NMP_OBJECT_CAST_IP_ROUTE (obj)); + const guint32 table = nm_platform_route_table_coerce (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced); struct rtmsg rtmsg = { .rtm_family = klass->addr_family, .rtm_tos = is_v4 ? obj->ip4_route.tos : 0, - .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ + .rtm_table = table <= 0xFF ? table : RT_TABLE_UNSPEC, .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (obj->ip_route.rt_source), .rtm_scope = is_v4 ? nm_platform_route_scope_inv (obj->ip4_route.scope_inv) @@ -2638,6 +2638,9 @@ _nl_msg_new_route (int nlmsg_type, NLA_PUT_U32 (msg, RTA_PRIORITY, obj->ip_route.metric); + if (table > 0xFF) + NLA_PUT_U32 (msg, RTA_TABLE, table); + if (is_v4) { if (NMP_OBJECT_CAST_IP4_ROUTE (obj)->pref_src) NLA_PUT (msg, RTA_PREFSRC, addr_len, &obj->ip4_route.pref_src); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 665c5576a0..ba2cf7a76b 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -2899,6 +2899,16 @@ nm_platform_lookup (NMPlatform *self, } gboolean +nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel (const NMPObject *obj, + gpointer user_data) +{ + nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + return !obj->ip_route.table_coerced + && obj->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; +} + +gboolean nm_platform_lookup_predicate_routes_skip_rtprot_kernel (const NMPObject *obj, gpointer user_data) { @@ -3547,7 +3557,7 @@ nm_platform_ip_address_flush (NMPlatform *self, * @kernel_delete_predicate: (allow-none): if not %NULL, previously * existing routes already configured will only be deleted if the * predicate returns TRUE. This allows to preserve/ignore some - * routes. For example by passing @nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + * routes. For example by passing @nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, * routes with "proto kernel" will be left untouched. * @kernel_delete_userdata: user data for @kernel_delete_predicate. * @@ -4858,6 +4868,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; char s_pref_src[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_table[30]; char str_scope[30], s_source[50]; char str_tos[32], str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; @@ -4871,6 +4882,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi g_snprintf (buf, len, + "%s" /* table */ "%s/%d" " via %s" "%s" @@ -4887,6 +4899,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi "%s" /* initrwnd */ "%s" /* mtu */ "", + route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_coerce (route->table_coerced)) : "", s_network, route->plen, s_gateway, @@ -4925,6 +4938,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi { char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN], s_pref_src[INET6_ADDRSTRLEN]; char s_src_all[INET6_ADDRSTRLEN + 40], s_src[INET6_ADDRSTRLEN]; + char str_table[30]; char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50]; char str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; @@ -4942,6 +4956,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi _to_string_dev (NULL, route->ifindex, str_dev, sizeof (str_dev)); g_snprintf (buf, len, + "%s" /* table */ "%s/%d" " via %s" "%s" @@ -4957,6 +4972,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi "%s" /* initrwnd */ "%s" /* mtu */ "", + route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_coerce (route->table_coerced)) : "", s_network, route->plen, s_gateway, @@ -5403,6 +5419,7 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + h = NM_HASH_COMBINE (h, obj->table_coerced); h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); h = NM_HASH_COMBINE (h, obj->plen); h = NM_HASH_COMBINE (h, obj->metric); @@ -5428,6 +5445,7 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + h = NM_HASH_COMBINE (h, obj->table_coerced); h = NM_HASH_COMBINE (h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen)); @@ -5474,6 +5492,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD (a, b, table_coerced); NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen)); NM_CMP_FIELD (a, b, plen); NM_CMP_FIELD (a, b, metric); @@ -5501,6 +5520,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD (a, b, table_coerced); NM_CMP_FIELD (a, b, ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen)); @@ -5550,6 +5570,7 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + h = NM_HASH_COMBINE (h, obj->table_coerced); h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen); h = NM_HASH_COMBINE (h, obj->plen); h = NM_HASH_COMBINE (h, nm_utils_ip6_route_metric_normalize (obj->metric)); @@ -5562,6 +5583,7 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + h = NM_HASH_COMBINE (h, obj->table_coerced); h = NM_HASH_COMBINE (h, obj->ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen); @@ -5612,6 +5634,7 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: + NM_CMP_FIELD (a, b, table_coerced); NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen)); NM_CMP_FIELD (a, b, plen); NM_CMP_DIRECT (nm_utils_ip6_route_metric_normalize (a->metric), nm_utils_ip6_route_metric_normalize (b->metric)); @@ -5624,6 +5647,7 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD (a, b, table_coerced); NM_CMP_FIELD (a, b, ifindex); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen)); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index d75b9143c0..e14c71512d 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -424,6 +424,13 @@ typedef union { /* RTA_PRIORITY (iproute2: metric) */ \ guint32 metric; \ \ + /* rtm_table, RTA_TABLE. + * + * This is not the original table ID. Instead, 254 (RT_TABLE_MAIN) and + * zero (RT_TABLE_UNSPEC) are swapped, so that the default is the main + * table. Use nm_platform_route_table_coerce(). */ \ + guint32 table_coerced; \ + \ /*end*/ @@ -853,6 +860,27 @@ NMPlatform *nm_platform_get (void); /*****************************************************************************/ /** + * nm_platform_route_table_coerce: + * @table: the route table, either its original value, or its coerced. + * + * Returns: returns the coerced table id. If the table id is like + * RTA_TABLE, it returns a value for NMPlatformIPRoute.table_coerced + * and vice versa. + */ +static inline guint32 +nm_platform_route_table_coerce (guint32 table) +{ + switch (table) { + case 0 /* RT_TABLE_UNSPEC */: + return 254; + case 254 /* RT_TABLE_MAIN */: + return 0; + default: + return table; + } +} + +/** * nm_platform_route_scope_inv: * @scope: the route scope, either its original value, or its inverse. * @@ -930,6 +958,8 @@ struct _NMPLookup; const struct _NMDedupMultiHeadEntry *nm_platform_lookup (NMPlatform *platform, const struct _NMPLookup *lookup); +gboolean nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel (const NMPObject *obj, + gpointer user_data); gboolean nm_platform_lookup_predicate_routes_skip_rtprot_kernel (const NMPObject *obj, gpointer user_data); diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index ad58e141a9..4010aa2f83 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -230,7 +230,7 @@ nmtstp_ip4_route_get_all (NMPlatform *platform, return nm_platform_lookup_addrroute_clone (platform, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL); } @@ -241,7 +241,7 @@ nmtstp_ip6_route_get_all (NMPlatform *platform, return nm_platform_lookup_addrroute_clone (platform, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex, - nm_platform_lookup_predicate_routes_skip_rtprot_kernel, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, NULL); } |