summaryrefslogtreecommitdiff
path: root/src/nm-ip6-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-ip6-config.c')
-rw-r--r--src/nm-ip6-config.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index 48aeb64ae..9647268d0 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -34,6 +34,7 @@
#include "nm-ip6-config-glue.h"
#include "nm-route-manager.h"
#include "NetworkManagerUtils.h"
+#include "nm-macros-internal.h"
G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, G_TYPE_OBJECT)
@@ -50,6 +51,7 @@ typedef struct {
GPtrArray *domains;
GPtrArray *searches;
guint32 mss;
+ gint64 route_metric;
} NMIP6ConfigPrivate;
@@ -329,6 +331,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 +414,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 +424,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 +446,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 +512,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 +528,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 +568,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++) {
@@ -599,13 +617,17 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
/******************************************************************/
void
-nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src)
+nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags)
{
+ 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 */
@@ -621,16 +643,27 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src)
nm_ip6_config_set_gateway (dst, nm_ip6_config_get_gateway (src));
/* routes */
- 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 (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
+ 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 if (src_priv->route_metric != -1)
+ 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));
+ if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
+ 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));
+ }
/* dns searches */
- for (i = 0; i < nm_ip6_config_get_num_searches (src); i++)
- nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i));
+ if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_DNS)) {
+ for (i = 0; i < nm_ip6_config_get_num_searches (src); i++)
+ nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i));
+ }
if (nm_ip6_config_get_mss (src))
nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src));
@@ -776,6 +809,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 +859,7 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
i++;
}
+ /* ignore route_metric */
/* ignore nameservers */
/* default gateway */
@@ -902,6 +938,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 +1153,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 +1721,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