diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nm-ip4-config.c | 45 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 1 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 45 | ||||
-rw-r--r-- | 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 4c3ea8bd27..6d8dfba834 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; gboolean metered; } NMIP4ConfigPrivate; @@ -219,6 +220,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. */ @@ -336,6 +341,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; @@ -344,6 +350,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); @@ -363,6 +371,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); @@ -431,6 +442,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 ()); @@ -446,6 +458,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++) { @@ -481,7 +494,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++) { @@ -524,11 +541,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 */ @@ -547,6 +568,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)); @@ -732,6 +758,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)); @@ -801,6 +829,7 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src) i++; } + /* ignore route_metric */ /* ignore nameservers */ /* default gateway */ @@ -877,6 +906,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); @@ -1165,6 +1199,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 @@ -1886,6 +1928,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 62a309fa08..fb072404f0 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 48aeb64aee..a528bf162a 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 66f15888c2..c7f3f519ae 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); |