diff options
author | Thomas Haller <thaller@redhat.com> | 2015-01-11 13:34:56 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-01-11 13:35:15 +0100 |
commit | 1bb1bfe6e7c8206ba5e157b15b1a4db81b24fd80 (patch) | |
tree | 9a9515997755876d3d9e75a93ff984ce9f07441c | |
parent | 207ab013a11bb4c730297a2eedf8600e33f33e23 (diff) | |
parent | 41e6c4fac1890e4302e4bfd1aa21be362cce51f2 (diff) | |
download | NetworkManager-1bb1bfe6e7c8206ba5e157b15b1a4db81b24fd80.tar.gz |
core: merge branch 'th/route-fixes-bgo741871'
https://bugzilla.gnome.org/show_bug.cgi?id=741871
-rw-r--r-- | libnm-core/nm-setting-ip4-config.c | 9 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip6-config.c | 9 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 23 | ||||
-rw-r--r-- | src/platform/tests/test-route.c | 7 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 4 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open | 2 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 13 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 14 |
8 files changed, 75 insertions, 6 deletions
diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 686192678a..81cc1f8889 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -571,6 +571,15 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) * ---end--- */ + /* ---ifcfg-rh--- + * property: route-metric + * variable: IPV4_ROUTE_METRIC(+) + * default: -1 + * description: IPV4_ROUTE_METRIC is the default IPv4 metric for routes on this connection. + * If set to -1, a default metric based on the device type is used. + * ---end--- + */ + /** * NMSettingIP4Config:dhcp-client-id: * diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index f5d903340c..29ca551525 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -488,6 +488,15 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) * ---end--- */ + /* ---ifcfg-rh--- + * property: route-metric + * variable: IPV6_ROUTE_METRIC(+) + * default: -1 + * description: IPV6_ROUTE_METRIC is the default IPv6 metric for routes on this connection. + * If set to -1, a default metric based on the device type is used. + * ---end--- + */ + /** * NMSettingIP6Config:ip6-privacy: * diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 5d1522ce98..0c35376cdb 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3845,6 +3845,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, guint32 metric, guint32 mss) { + metric = nm_utils_ip6_route_metric_normalize (metric); + return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, NULL, metric, mss)); } @@ -3863,7 +3865,7 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void if (!_route_match (rtnlroute, family, ifindex, FALSE)) continue; - if (metric && metric != rtnl_route_get_priority (rtnlroute)) + if (metric != rtnl_route_get_priority (rtnlroute)) continue; dst = rtnl_route_get_dst (rtnlroute); @@ -3884,7 +3886,7 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void } static gboolean -refresh_route (NMPlatform *platform, int family, int ifindex, const void *network, int plen, int metric) +refresh_route (NMPlatform *platform, int family, int ifindex, const void *network, int plen, guint32 metric) { struct nl_cache *cache; auto_nl_object struct rtnl_route *cached_object = NULL; @@ -3910,6 +3912,19 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen cache = choose_cache_by_type (platform, OBJECT_TYPE_IP4_ROUTE); + if (metric == 0) { + /* Deleting an IPv4 route with metric 0 does not only delete an exectly matching route. + * If no route with metric 0 exists, it might delete another route to the same destination. + * For nm_platform_ip4_route_delete() we don't want this semantic. + * + * Instead, re-fetch the route from kernel, and if that fails, there is nothing to do. + * On success, there is still a race that we might end up deleting the wrong route. */ + if (!refresh_object (platform, (struct nl_object *) route, FALSE, NM_PLATFORM_REASON_INTERNAL)) { + rtnl_route_put ((struct rtnl_route *) route); + return TRUE; + } + } + /* when deleting an IPv4 route, several fields of the provided route must match. * Lookup in the cache so that we hopefully get the right values. */ cached_object = (struct rtnl_route *) nl_cache_search (cache, route); @@ -3962,6 +3977,8 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in { struct in6_addr gateway = IN6ADDR_ANY_INIT; + metric = nm_utils_ip6_route_metric_normalize (metric); + return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN ,&network, plen, &gateway, NULL, metric, 0), FALSE) && refresh_route (platform, AF_INET6, ifindex, &network, plen, metric); } @@ -3989,6 +4006,8 @@ ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen static gboolean ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { + metric = nm_utils_ip6_route_metric_normalize (metric); + return ip_route_exists (platform, AF_INET6, ifindex, &network, plen, metric); } diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 2c70b412bb..9ccca0a0f6 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -2,6 +2,7 @@ #include "test-common.h" #include "nm-test-utils.h" +#include "NetworkManagerUtils.h" #define DEVICE_NAME "nm-test-device" @@ -205,21 +206,21 @@ test_ip6_route (void) rts[0].plen = 128; rts[0].ifindex = ifindex; rts[0].gateway = in6addr_any; - rts[0].metric = metric; + rts[0].metric = nm_utils_ip6_route_metric_normalize (metric); rts[0].mss = mss; rts[1].source = NM_IP_CONFIG_SOURCE_USER; rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; - rts[1].metric = metric; + rts[1].metric = nm_utils_ip6_route_metric_normalize (metric); rts[1].mss = mss; rts[2].source = NM_IP_CONFIG_SOURCE_USER; rts[2].network = in6addr_any; rts[2].plen = 0; rts[2].ifindex = ifindex; rts[2].gateway = gateway; - rts[2].metric = metric; + rts[2].metric = nm_utils_ip6_route_metric_normalize (metric); rts[2].mss = mss; g_assert_cmpint (routes->len, ==, 3); g_assert (!memcmp (routes->data, rts, sizeof (rts))); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index fe8112baae..e892394dcf 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -960,6 +960,8 @@ make_ip4_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV4_ROUTE_METRIC", 10, + -1, G_MAXUINT32, -1), NULL); if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) @@ -1356,6 +1358,8 @@ make_ip6_setting (shvarFile *ifcfg, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_ROUTE_METRIC, svGetValueInt64 (ifcfg, "IPV6_ROUTE_METRIC", 10, + -1, G_MAXUINT32, -1), NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val, NULL); diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open index 48db45b25d..b089103dae 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open @@ -12,3 +12,5 @@ ONBOOT=yes USERCTL=yes PEERDNS=yes IPV6INIT=no +IPV4_ROUTE_METRIC=104 +IPV6_ROUTE_METRIC=106 diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index fecacaed40..e05a4ccb20 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -2439,7 +2439,7 @@ test_read_wifi_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip4, *s_ip6; GError *error = NULL; const char *tmp; GBytes *ssid; @@ -2584,6 +2584,8 @@ test_read_wifi_open (void) TEST_IFCFG_WIFI_OPEN, NM_SETTING_IP4_CONFIG_SETTING_NAME); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip4), ==, 104); + /* Method */ tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, @@ -2592,6 +2594,10 @@ test_read_wifi_open (void) NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert( s_ip6); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (s_ip6), ==, 106); + g_object_unref (connection); } @@ -5775,6 +5781,7 @@ test_write_wired_static (void) NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 204, NULL); addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); @@ -5800,6 +5807,7 @@ test_write_wired_static (void) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) 206, NULL); /* Add addresses */ @@ -5883,6 +5891,9 @@ test_write_wired_static (void) nm_setting_ip_config_remove_dns_search (reread_s_ip4, 3); nm_setting_ip_config_remove_dns_search (reread_s_ip4, 2); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip4), ==, 204); + g_assert_cmpint (nm_setting_ip_config_get_route_metric (reread_s_ip6), ==, 206); + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "wired-static-write", "written and re-read connection weren't the same."); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index f4ffffd6a8..300b0c1665 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -1806,6 +1806,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) char *route_path = NULL; gint32 j; guint32 i, n, num; + gint64 route_metric; GString *searches; gboolean success = FALSE; gboolean fake_ip4 = FALSE; @@ -2015,6 +2016,11 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) nm_setting_ip_config_get_may_fail (s_ip4) ? "no" : "yes", FALSE); + route_metric = nm_setting_ip_config_get_route_metric (s_ip4); + tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL; + svSetValue (ifcfg, "IPV4_ROUTE_METRIC", tmp, FALSE); + g_free (tmp); + /* Static routes - route-<name> file */ route_path = utils_get_route_path (ifcfg->fileName); if (!route_path) { @@ -2249,10 +2255,12 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) NMSettingIPConfig *s_ip4; const char *value; char *addr_key; + char *tmp; guint32 i, num, num4; GString *searches; NMIPAddress *addr; const char *dns; + gint64 route_metric; GString *ip_str1, *ip_str2, *ip_ptr; char *route6_path; @@ -2266,6 +2274,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "IPV6_PEERDNS", "yes", FALSE); svSetValue (ifcfg, "IPV6_PEERROUTES", "yes", FALSE); svSetValue (ifcfg, "IPV6_FAILURE_FATAL", "no", FALSE); + svSetValue (ifcfg, "IPV6_ROUTE_METRIC", NULL, FALSE); return TRUE; } @@ -2380,6 +2389,11 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) nm_setting_ip_config_get_may_fail (s_ip6) ? "no" : "yes", FALSE); + route_metric = nm_setting_ip_config_get_route_metric (s_ip6); + tmp = route_metric != -1 ? g_strdup_printf ("%"G_GINT64_FORMAT, route_metric) : NULL; + svSetValue (ifcfg, "IPV6_ROUTE_METRIC", tmp, FALSE); + g_free (tmp); + /* IPv6 Privacy Extensions */ svSetValue (ifcfg, "IPV6_PRIVACY", NULL, FALSE); svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", NULL, FALSE); |