diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/nm-linux-platform.c | 10 | ||||
| -rw-r--r-- | src/platform/nm-platform.c | 24 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 40 | ||||
| -rw-r--r-- | src/platform/tests/test-route.c | 4 |
4 files changed, 70 insertions, 8 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e2c45c88..710a6f91 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3257,14 +3257,16 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) rtm = nlmsg_data (nlh); /***************************************************************** - * only handle ~normal~ routes. + * only handle ~supported~ routes. *****************************************************************/ if (!NM_IN_SET (rtm->rtm_family, AF_INET, AF_INET6)) return NULL; - if (rtm->rtm_type != RTN_UNICAST) - return NULL; + if (!NM_IN_SET (rtm->rtm_type, + RTN_UNICAST, + RTN_LOCAL)) + return NULL; if (nlmsg_parse_arr (nlh, sizeof (struct rtmsg), @@ -4491,7 +4493,7 @@ _nl_msg_new_route (int nlmsg_type, .rtm_scope = is_v4 ? nm_platform_route_scope_inv (obj->ip4_route.scope_inv) : RT_SCOPE_NOWHERE, - .rtm_type = RTN_UNICAST, + .rtm_type = nm_platform_route_type_uncoerce (NMP_OBJECT_CAST_IP_ROUTE (obj)->type_coerced), .rtm_flags = obj->ip_route.r_rtm_flags & ((unsigned) (RTNH_F_ONLINK)), .rtm_dst_len = obj->ip_route.plen, .rtm_src_len = is_v4 diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index c023f435..c8b8c6e8 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -4518,8 +4518,12 @@ _ip_route_scope_inv_get_normalized (const NMPlatformIP4Route *route) * so that the default equals zero (~(RT_SCOPE_NOWHERE)). **/ if (route->scope_inv == 0) { - return nm_platform_route_scope_inv (!route->gateway - ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); + if (route->type_coerced == nm_platform_route_type_coerce (RTN_LOCAL)) + return nm_platform_route_scope_inv (RT_SCOPE_HOST); + else { + return nm_platform_route_scope_inv (!route->gateway + ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); + } } return route->scope_inv; } @@ -6079,6 +6083,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_type[30]; 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]; @@ -6093,6 +6098,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi _to_string_dev (NULL, route->ifindex, str_dev, sizeof (str_dev)); g_snprintf (buf, len, + "%s" /* type */ "%s" /* table */ "%s/%d" " via %s" @@ -6110,6 +6116,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi "%s" /* initrwnd */ "%s" /* mtu */ "", + route->type_coerced ? nm_sprintf_buf (str_type, "type %s ", nm_utils_route_type2str (nm_platform_route_type_uncoerce (route->type_coerced), NULL, 0)) : "", route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "", s_network, route->plen, @@ -6152,6 +6159,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi char s_pref_src[INET6_ADDRSTRLEN]; char s_src_all[INET6_ADDRSTRLEN + 40]; char s_src[INET6_ADDRSTRLEN]; + char str_type[30]; char str_table[30]; char str_pref[40]; char str_pref2[30]; @@ -6178,6 +6186,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" /* type */ "%s" /* table */ "%s/%d" " via %s" @@ -6195,6 +6204,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi "%s" /* mtu */ "%s" /* pref */ "", + route->type_coerced ? nm_sprintf_buf (str_type, "type %s ", nm_utils_route_type2str (nm_platform_route_type_uncoerce (route->type_coerced), NULL, 0)) : "", route->table_coerced ? nm_sprintf_buf (str_table, "table %u ", nm_platform_route_table_uncoerce (route->table_coerced, FALSE)) : "", s_network, route->plen, @@ -7274,6 +7284,7 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: nm_hash_update_vals (h, + obj->type_coerced, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), obj->plen, @@ -7301,6 +7312,7 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: nm_hash_update_vals (h, + obj->type_coerced, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), obj->ifindex, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen), @@ -7327,6 +7339,7 @@ nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: nm_hash_update_vals (h, + obj->type_coerced, obj->table_coerced, obj->ifindex, obj->network, @@ -7369,6 +7382,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route NM_CMP_FIELD (a, b, tos); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { NM_CMP_FIELD (a, b, ifindex); + NM_CMP_FIELD (a, b, type_coerced); NM_CMP_DIRECT (nmp_utils_ip_config_source_round_trip_rtprot (a->rt_source), nmp_utils_ip_config_source_round_trip_rtprot (b->rt_source)); NM_CMP_DIRECT (_ip_route_scope_inv_get_normalized (a), @@ -7392,6 +7406,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, type_coerced); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); @@ -7454,6 +7469,7 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: nm_hash_update_vals (h, + obj->type_coerced, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), obj->plen, @@ -7466,6 +7482,7 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: nm_hash_update_vals (h, + obj->type_coerced, nm_platform_route_table_uncoerce (obj->table_coerced, TRUE), obj->ifindex, *nm_utils_ip6_address_clear_host_address (&a1, &obj->network, obj->plen), @@ -7493,6 +7510,7 @@ nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRo break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: nm_hash_update_vals (h, + obj->type_coerced, obj->table_coerced, obj->ifindex, obj->network, @@ -7537,11 +7555,13 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route NM_CMP_FIELD (a, b, src_plen); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { NM_CMP_FIELD (a, b, ifindex); + NM_CMP_FIELD (a, b, type_coerced); NM_CMP_FIELD_IN6ADDR (a, b, gateway); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: + NM_CMP_FIELD (a, b, type_coerced); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) { NM_CMP_DIRECT (nm_platform_route_table_uncoerce (a->table_coerced, TRUE), nm_platform_route_table_uncoerce (b->table_coerced, TRUE)); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index aa3551a6..3e6ef84c 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -468,6 +468,13 @@ typedef union { * table. Use nm_platform_route_table_coerce()/nm_platform_route_table_uncoerce(). */ \ guint32 table_coerced; \ \ + /* rtm_type. + * + * This is not the original type, if type_coerced is 0 then + * it means RTN_UNSPEC otherwise the type value is preserved. + * */ \ + guint8 type_coerced; \ + \ /*end*/ typedef struct { @@ -1285,6 +1292,39 @@ _nm_platform_uint8_inv (guint8 scope) return (guint8) ~scope; } +/** + * nm_platform_route_type_coerce: + * @table: the route type, in its original value. + * + * Returns: returns the coerced type, that can be stored in + * NMPlatformIPRoute.type_coerced. + */ +static inline guint8 +nm_platform_route_type_coerce (guint8 type) +{ + switch (type) { + case 0 /* RTN_UNSPEC */: + return 1; + case 1 /* RTN_UNICAST */: + return 0; + default: + return type; + } +} + +/** + * nm_platform_route_type_uncoerce: + * @table: the type table, in its coerced value + * + * Returns: reverts the coerced type in NMPlatformIPRoute.type_coerced + * to the original value as kernel understands it. + */ +static inline guint8 +nm_platform_route_type_uncoerce (guint8 type_coerced) +{ + return nm_platform_route_type_coerce (type_coerced); +} + gboolean nm_platform_get_use_udev (NMPlatform *self); gboolean nm_platform_get_log_with_ptr (NMPlatform *self); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index f074ca69..19debfb5 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -328,13 +328,13 @@ test_ip6_route (void) g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, pref_src, 128, in6addr_any, NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0)); - accept_signals (route_added, 0, 1); + accept_signals (route_added, 0, 2); _wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 200, ifindex, 1, &pref_src); /* Add route to gateway */ nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, in6addr_any, metric, mss); - accept_signal (route_added); + accept_signals (route_added, 0, 3); /* Add route */ g_assert (!nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); |