From a7a867bbd902e7f26925e325f6014afb01d713c0 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 22 Jul 2015 16:05:36 +0200 Subject: [PATCH] Add a missing patch --- ...e-metric-when-creating-nm-generated-.patch | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 0001-core-detect-route-metric-when-creating-nm-generated-.patch diff --git a/0001-core-detect-route-metric-when-creating-nm-generated-.patch b/0001-core-detect-route-metric-when-creating-nm-generated-.patch new file mode 100644 index 0000000..2783a90 --- /dev/null +++ b/0001-core-detect-route-metric-when-creating-nm-generated-.patch @@ -0,0 +1,369 @@ +From 9588c4633a07147875d933556212716779e32a36 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Thu, 4 Jun 2015 15:57:42 +0200 +Subject: [PATCH] core: detect route-metric when creating nm-generated-assumed + connection + +When generating a connection to assume it, also record the route-metric. +Do that by looking at the metric of the (best) default-route. + +This is especially important since d51975ed921a5876b76e081b8f3df4e2ca1f1ca9. +Now NM would also manage the default-route for assumed connections. +So the generated assumed connection would have a route metric based on +the device type, which might differ from the external configuration. +This caused NM to replace the externally configured default-route. + +https://bugzilla.gnome.org/show_bug.cgi?id=750405 +(cherry picked from commit bc75cd53a8c5ba525016bfddc1644be59a45ed41) +--- + src/nm-ip4-config.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + src/nm-ip4-config.h | 1 + + src/nm-ip6-config.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + src/nm-ip6-config.h | 1 + + 4 files changed, 90 insertions(+), 2 deletions(-) + +diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c +index db8c4b4..e5cb6c7 100644 +--- a/src/nm-ip4-config.c ++++ b/src/nm-ip4-config.c +@@ -56,6 +56,7 @@ typedef struct { + GArray *wins; + guint32 mtu; + NMIPConfigSource mtu_source; ++ gint64 route_metric; + } NMIP4ConfigPrivate; + + /* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */ +@@ -218,6 +219,10 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) + i++; + } + ++ /* we detect the route metric based on the default route. All non-default ++ * routes have their route metrics explicitly set. */ ++ priv->route_metric = has_gateway ? (gint64) lowest_metric : (gint64) -1; ++ + /* If there is a host route to the gateway, ignore that route. It is + * automatically added by NetworkManager when needed. + */ +@@ -335,6 +340,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu + void + nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric) + { ++ NMIP4ConfigPrivate *priv; + guint naddresses, nroutes, nnameservers, nsearches; + int i; + +@@ -343,6 +349,8 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu + + g_return_if_fail (NM_IS_SETTING_IP4_CONFIG (setting)); + ++ priv = NM_IP4_CONFIG_GET_PRIVATE (config); ++ + g_object_freeze_notify (G_OBJECT (config)); + + naddresses = nm_setting_ip_config_get_num_addresses (setting); +@@ -362,6 +370,9 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu + nm_ip4_config_set_gateway (config, gateway); + } + ++ if (priv->route_metric == -1) ++ priv->route_metric = nm_setting_ip_config_get_route_metric (setting); ++ + /* Addresses */ + for (i = 0; i < naddresses; i++) { + NMIPAddress *s_addr = nm_setting_ip_config_get_address (setting, i); +@@ -430,6 +441,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) + guint naddresses, nroutes, nnameservers, nsearches; + const char *method = NULL; + int i; ++ gint64 route_metric; + + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); + +@@ -445,6 +457,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) + nroutes = nm_ip4_config_get_num_routes (config); + nnameservers = nm_ip4_config_get_num_nameservers (config); + nsearches = nm_ip4_config_get_num_searches (config); ++ route_metric = nm_ip4_config_get_route_metric (config); + + /* Addresses */ + for (i = 0; i < naddresses; i++) { +@@ -480,7 +493,11 @@ nm_ip4_config_create_setting (const NMIP4Config *config) + /* Use 'disabled' if the method wasn't previously set */ + if (!method) + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; +- g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, method, NULL); ++ ++ g_object_set (s_ip4, ++ NM_SETTING_IP_CONFIG_METHOD, method, ++ NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) route_metric, ++ NULL); + + /* Routes */ + for (i = 0; i < nroutes; i++) { +@@ -523,11 +540,15 @@ nm_ip4_config_create_setting (const NMIP4Config *config) + void + nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src) + { ++ NMIP4ConfigPrivate *dst_priv, *src_priv; + guint32 i; + + g_return_if_fail (src != NULL); + g_return_if_fail (dst != NULL); + ++ dst_priv = NM_IP4_CONFIG_GET_PRIVATE (dst); ++ src_priv = NM_IP4_CONFIG_GET_PRIVATE (src); ++ + g_object_freeze_notify (G_OBJECT (dst)); + + /* addresses */ +@@ -546,6 +567,11 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src) + for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) + nm_ip4_config_add_route (dst, nm_ip4_config_get_route (src, i)); + ++ if (dst_priv->route_metric == -1) ++ dst_priv->route_metric = src_priv->route_metric; ++ else ++ dst_priv->route_metric = MIN (dst_priv->route_metric, src_priv->route_metric); ++ + /* domains */ + for (i = 0; i < nm_ip4_config_get_num_domains (src); i++) + nm_ip4_config_add_domain (dst, nm_ip4_config_get_domain (src, i)); +@@ -727,6 +753,8 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src) + if (!nm_ip4_config_get_num_addresses (dst)) + nm_ip4_config_set_gateway (dst, 0); + ++ /* ignore route_metric */ ++ + /* routes */ + for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) { + idx = _routes_get_index (dst, nm_ip4_config_get_route (src, i)); +@@ -796,6 +824,7 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src) + i++; + } + ++ /* ignore route_metric */ + /* ignore nameservers */ + + /* default gateway */ +@@ -872,6 +901,11 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev + has_relevant_changes = TRUE; + } + ++ if (src_priv->route_metric != dst_priv->route_metric) { ++ dst_priv->route_metric = src_priv->route_metric; ++ has_minor_changes = TRUE; ++ } ++ + /* addresses */ + num = nm_ip4_config_get_num_addresses (src); + are_equal = num == nm_ip4_config_get_num_addresses (dst); +@@ -1153,6 +1187,14 @@ nm_ip4_config_get_gateway (const NMIP4Config *config) + return priv->gateway; + } + ++gint64 ++nm_ip4_config_get_route_metric (const NMIP4Config *config) ++{ ++ NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); ++ ++ return priv->route_metric; ++} ++ + /******************************************************************/ + + void +@@ -1856,6 +1898,7 @@ nm_ip4_config_init (NMIP4Config *config) + priv->searches = g_ptr_array_new_with_free_func (g_free); + priv->nis = g_array_new (FALSE, TRUE, sizeof (guint32)); + priv->wins = g_array_new (FALSE, TRUE, sizeof (guint32)); ++ priv->route_metric = -1; + } + + static void +diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h +index 4636752..ea8320d 100644 +--- a/src/nm-ip4-config.h ++++ b/src/nm-ip4-config.h +@@ -81,6 +81,7 @@ void nm_ip4_config_set_never_default (NMIP4Config *config, gboolean never_defaul + gboolean nm_ip4_config_get_never_default (const NMIP4Config *config); + void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway); + guint32 nm_ip4_config_get_gateway (const NMIP4Config *config); ++gint64 nm_ip4_config_get_route_metric (const NMIP4Config *config); + + /* Addresses */ + void nm_ip4_config_reset_addresses (NMIP4Config *config); +diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c +index 48aeb64..a528bf1 100644 +--- a/src/nm-ip6-config.c ++++ b/src/nm-ip6-config.c +@@ -50,6 +50,7 @@ typedef struct { + GPtrArray *domains; + GPtrArray *searches; + guint32 mss; ++ gint64 route_metric; + } NMIP6ConfigPrivate; + + +@@ -329,6 +330,10 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co + i++; + } + ++ /* we detect the route metric based on the default route. All non-default ++ * routes have their route metrics explicitly set. */ ++ priv->route_metric = has_gateway ? (gint64) lowest_metric : (gint64) -1; ++ + /* If there is a host route to the gateway, ignore that route. It is + * automatically added by NetworkManager when needed. + */ +@@ -408,6 +413,7 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_fu + void + nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric) + { ++ NMIP6ConfigPrivate *priv; + guint naddresses, nroutes, nnameservers, nsearches; + const char *gateway_str; + int i; +@@ -417,6 +423,8 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu + + g_return_if_fail (NM_IS_SETTING_IP6_CONFIG (setting)); + ++ priv = NM_IP6_CONFIG_GET_PRIVATE (config); ++ + naddresses = nm_setting_ip_config_get_num_addresses (setting); + nroutes = nm_setting_ip_config_get_num_routes (setting); + nnameservers = nm_setting_ip_config_get_num_dns (setting); +@@ -437,6 +445,9 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu + nm_ip6_config_set_gateway (config, &gateway); + } + ++ if (priv->route_metric == -1) ++ priv->route_metric = nm_setting_ip_config_get_route_metric (setting); ++ + /* Addresses */ + for (i = 0; i < naddresses; i++) { + NMIPAddress *s_addr = nm_setting_ip_config_get_address (setting, i); +@@ -500,6 +511,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) + guint naddresses, nroutes, nnameservers, nsearches; + const char *method = NULL; + int i; ++ gint64 route_metric; + + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); + +@@ -515,6 +527,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) + nroutes = nm_ip6_config_get_num_routes (config); + nnameservers = nm_ip6_config_get_num_nameservers (config); + nsearches = nm_ip6_config_get_num_searches (config); ++ route_metric = nm_ip6_config_get_route_metric (config); + + /* Addresses */ + for (i = 0; i < naddresses; i++) { +@@ -554,7 +567,11 @@ nm_ip6_config_create_setting (const NMIP6Config *config) + /* Use 'ignore' if the method wasn't previously set */ + if (!method) + method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; +- g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, method, NULL); ++ ++ g_object_set (s_ip6, ++ NM_SETTING_IP_CONFIG_METHOD, method, ++ NM_SETTING_IP_CONFIG_ROUTE_METRIC, (gint64) route_metric, ++ NULL); + + /* Routes */ + for (i = 0; i < nroutes; i++) { +@@ -601,11 +618,15 @@ nm_ip6_config_create_setting (const NMIP6Config *config) + void + nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src) + { ++ NMIP6ConfigPrivate *dst_priv, *src_priv; + guint32 i; + + g_return_if_fail (src != NULL); + g_return_if_fail (dst != NULL); + ++ dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst); ++ src_priv = NM_IP6_CONFIG_GET_PRIVATE (src); ++ + g_object_freeze_notify (G_OBJECT (dst)); + + /* addresses */ +@@ -624,6 +645,11 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src) + for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) + nm_ip6_config_add_route (dst, nm_ip6_config_get_route (src, i)); + ++ if (dst_priv->route_metric == -1) ++ dst_priv->route_metric = src_priv->route_metric; ++ else ++ dst_priv->route_metric = MIN (dst_priv->route_metric, src_priv->route_metric); ++ + /* domains */ + for (i = 0; i < nm_ip6_config_get_num_domains (src); i++) + nm_ip6_config_add_domain (dst, nm_ip6_config_get_domain (src, i)); +@@ -776,6 +802,8 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) + if (!nm_ip6_config_get_num_addresses (dst)) + nm_ip6_config_set_gateway (dst, NULL); + ++ /* ignore route_metric */ ++ + /* routes */ + for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) { + idx = _routes_get_index (dst, nm_ip6_config_get_route (src, i)); +@@ -824,6 +852,7 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src) + i++; + } + ++ /* ignore route_metric */ + /* ignore nameservers */ + + /* default gateway */ +@@ -902,6 +931,11 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev + has_relevant_changes = TRUE; + } + ++ if (src_priv->route_metric != dst_priv->route_metric) { ++ dst_priv->route_metric = src_priv->route_metric; ++ has_minor_changes = TRUE; ++ } ++ + /* addresses */ + num = nm_ip6_config_get_num_addresses (src); + are_equal = num == nm_ip6_config_get_num_addresses (dst); +@@ -1112,6 +1146,14 @@ nm_ip6_config_get_gateway (const NMIP6Config *config) + return IN6_IS_ADDR_UNSPECIFIED (&priv->gateway) ? NULL : &priv->gateway; + } + ++gint64 ++nm_ip6_config_get_route_metric (const NMIP6Config *config) ++{ ++ NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); ++ ++ return priv->route_metric; ++} ++ + /******************************************************************/ + + void +@@ -1672,6 +1714,7 @@ nm_ip6_config_init (NMIP6Config *config) + priv->nameservers = g_array_new (FALSE, TRUE, sizeof (struct in6_addr)); + priv->domains = g_ptr_array_new_with_free_func (g_free); + priv->searches = g_ptr_array_new_with_free_func (g_free); ++ priv->route_metric = -1; + } + + static void +diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h +index 66f1588..c7f3f51 100644 +--- a/src/nm-ip6-config.h ++++ b/src/nm-ip6-config.h +@@ -81,6 +81,7 @@ void nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_defaul + gboolean nm_ip6_config_get_never_default (const NMIP6Config *config); + void nm_ip6_config_set_gateway (NMIP6Config *config, const struct in6_addr *); + const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *config); ++gint64 nm_ip6_config_get_route_metric (const NMIP6Config *config); + + /* Addresses */ + void nm_ip6_config_reset_addresses (NMIP6Config *config); +-- +2.4.3 +