all: allow route metrics to be "0"
authorDan Winship <danw@gnome.org>
Tue, 4 Nov 2014 20:48:48 +0000 (15:48 -0500)
committerDan Winship <danw@gnome.org>
Fri, 7 Nov 2014 12:49:41 +0000 (07:49 -0500)
Change NMIPRoute to use "-1" for "default", so that "0" is a valid
metric. Update everything for that.

16 files changed:
callouts/nm-dispatcher-utils.c
clients/cli/common.c
clients/cli/settings.c
clients/tui/nm-editor-bindings.c
libnm-core/nm-setting-ip-config.c
libnm-core/nm-setting-ip-config.h
libnm-core/nm-utils.c
src/nm-ip4-config.c
src/nm-ip6-config.c
src/settings/plugins/ifcfg-rh/reader.c
src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
src/settings/plugins/ifcfg-rh/writer.c
src/settings/plugins/ifnet/connection_parser.c
src/settings/plugins/keyfile/reader.c
src/settings/plugins/keyfile/tests/test-keyfile.c
src/settings/plugins/keyfile/writer.c

index 8feec72..8d72743 100644 (file)
@@ -185,11 +185,11 @@ construct_ip4_items (GSList *items, GVariant *ip4_config, const char *prefix)
                        if (!next_hop)
                                next_hop = "0.0.0.0";
 
-                       routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, i,
+                       routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %u", prefix, i,
                                                    nm_ip_route_get_dest (route),
                                                    nm_ip_route_get_prefix (route),
                                                    next_hop,
-                                                   nm_ip_route_get_metric (route));
+                                                   (guint32) MAX (0, nm_ip_route_get_metric (route)));
                        items = g_slist_prepend (items, routetmp);
                }
                items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, routes->len));
@@ -299,11 +299,11 @@ construct_ip6_items (GSList *items, GVariant *ip6_config, const char *prefix)
                        if (!next_hop)
                                next_hop = "::";
 
-                       routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, i,
+                       routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %u", prefix, i,
                                                    nm_ip_route_get_dest (route),
                                                    nm_ip_route_get_prefix (route),
                                                    next_hop,
-                                                   nm_ip_route_get_metric (route));
+                                                   (guint32) MAX (0, nm_ip_route_get_metric (route)));
                        items = g_slist_prepend (items, routetmp);
                }
                if (routes->len)
index 2003934..8539af2 100644 (file)
@@ -130,11 +130,12 @@ print_ip4_config (NMIPConfig *cfg4,
                        if (!next_hop)
                                next_hop = "0.0.0.0";
 
-                       route_arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u",
+                       route_arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s%c mt = %u",
                                                        nm_ip_route_get_dest (route),
                                                        nm_ip_route_get_prefix (route),
                                                        next_hop,
-                                                       nm_ip_route_get_metric (route));
+                                                       nm_ip_route_get_metric (route) == -1 ? '\0' : ',',
+                                                       (guint32) nm_ip_route_get_metric (route));
                }
                route_arr[i] = NULL;
        }
@@ -219,11 +220,12 @@ print_ip6_config (NMIPConfig *cfg6,
                        if (!next_hop)
                                next_hop = "::";
 
-                       route_arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u",
+                       route_arr[i] = g_strdup_printf ("dst = %s/%u, nh = %s%c mt = %u",
                                                        nm_ip_route_get_dest (route),
                                                        nm_ip_route_get_prefix (route),
                                                        next_hop,
-                                                       nm_ip_route_get_metric (route));
+                                                       nm_ip_route_get_metric (route) == -1 ? '\0' : ',',
+                                                       (guint32) nm_ip_route_get_metric (route));
                }
                route_arr[i] = NULL;
        }
@@ -417,7 +419,7 @@ nmc_parse_and_build_route (int family,
        char *dest = NULL, *plen = NULL;
        const char *next_hop = NULL;
        const char *canon_dest;
-       long int prefix = max_prefix, metric = 0;
+       long int prefix = max_prefix, metric = -1;
        NMIPRoute *route = NULL;
        gboolean success = FALSE;
        GError *local = NULL;
index 292a09b..e4d7589 100644 (file)
@@ -1263,8 +1263,8 @@ nmc_property_ipv4_get_routes (NMSetting *setting)
                                                nm_ip_route_get_next_hop (route));
                }
 
-               if (nm_ip_route_get_metric (route))
-                       g_string_append_printf (printable, ", mt = %u", nm_ip_route_get_metric (route));
+               if (nm_ip_route_get_metric (route) != -1)
+                       g_string_append_printf (printable, ", mt = %u", (guint32) nm_ip_route_get_metric (route));
 
                g_string_append (printable, " }");
        }
@@ -1314,8 +1314,8 @@ nmc_property_ipv6_get_routes (NMSetting *setting)
                                                nm_ip_route_get_next_hop (route));
                }
 
-               if (nm_ip_route_get_metric (route))
-                       g_string_append_printf (printable, ", mt = %u", nm_ip_route_get_metric (route));
+               if (nm_ip_route_get_metric (route) != -1)
+                       g_string_append_printf (printable, ", mt = %u", (guint32) nm_ip_route_get_metric (route));
 
                g_string_append (printable, " }");
        }
@@ -3332,7 +3332,7 @@ nmc_property_ipv4_describe_routes (NMSetting *setting, const char *prop)
                 "  ip[/prefix] [next-hop] [metric],...\n\n"
                 "Missing prefix is regarded as a prefix of 32.\n"
                 "Missing next-hop is regarded as 0.0.0.0.\n"
-                "Missing metric or 0 means a default metric (NM/kernel will set a default value).\n\n"
+                "Missing metric means default (NM/kernel will set a default value).\n\n"
                 "Examples: 192.168.2.0/24 192.168.2.1 3, 10.1.0.0/16 10.0.0.254\n"
                 "          10.1.2.0/24\n");
 }
@@ -3638,7 +3638,7 @@ nmc_property_ipv6_describe_routes (NMSetting *setting, const char *prop)
                 "  ip[/prefix] [next-hop] [metric],...\n\n"
                 "Missing prefix is regarded as a prefix of 128.\n"
                 "Missing next-hop is regarded as \"::\".\n"
-                "Missing metric or 0 means a default metric (NM/kernel will set a default value).\n\n"
+                "Missing metric means default (NM/kernel will set a default value).\n\n"
                 "Examples: 2001:db8:beef:2::/64 2001:db8:beef::2, 2001:db8:beef:3::/64 2001:db8:beef::3 2\n"
                 "          abbe::/64 55\n");
 }
index 9db44c9..5560f83 100644 (file)
@@ -327,7 +327,7 @@ ip_route_transform_to_metric_string (GBinding     *binding,
        char *string;
 
        route = g_value_get_boxed (source_value);
-       if (route && nm_ip_route_get_dest (route)) {
+       if (route && nm_ip_route_get_dest (route) && nm_ip_route_get_metric (route) != -1) {
                string = g_strdup_printf ("%lu", (gulong) nm_ip_route_get_metric (route));
                g_value_take_string (target_value, string);
        } else
@@ -400,10 +400,13 @@ ip_route_transform_from_metric_string (GBinding     *binding,
 {
        NMIPRoute *route;
        const char *text;
-       guint32 metric;
+       gint64 metric;
 
        text = g_value_get_string (source_value);
-       metric = strtoul (text, NULL, 10);
+       if (*text)
+               metric = strtoul (text, NULL, 10);
+       else
+               metric = -1;
 
        /* Fetch the original property value */
        g_object_get (g_binding_get_source (binding),
index 30e7b26..8d0504e 100644 (file)
@@ -96,6 +96,24 @@ valid_prefix (int family, guint prefix, GError **error)
        return TRUE;
 }
 
+static gboolean
+valid_metric (gint64 metric, GError **error)
+{
+       if (metric < -1 || metric > G_MAXUINT32) {
+               if (error) {
+                       char buf[64];
+
+                       /* We can't concatenate G_GINT64_FORMAT into a translatable string */
+                       g_snprintf (buf, sizeof (buf), "%" G_GINT64_FORMAT, metric);
+                       g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
+                                    _("Invalid routing metric '%s'"), buf);
+               }
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 
 G_DEFINE_BOXED_TYPE (NMIPAddress, nm_ip_address, nm_ip_address_dup, nm_ip_address_unref)
 
@@ -495,7 +513,7 @@ struct NMIPRoute {
        char *dest;
        guint prefix;
        char *next_hop;
-       guint32 metric;
+       gint64 metric;
 
        GHashTable *attributes;
 };
@@ -506,7 +524,7 @@ struct NMIPRoute {
  * @dest: the IP address of the route's destination
  * @prefix: the address prefix length
  * @next_hop: (allow-none): the IP address of the next hop (or %NULL)
- * @metric: the route metric (or 0 for "default")
+ * @metric: the route metric (or -1 for "default")
  * @error: location to store error, or %NULL
  *
  * Creates a new #NMIPRoute object.
@@ -518,7 +536,7 @@ nm_ip_route_new (int family,
                  const char *dest,
                  guint prefix,
                  const char *next_hop,
-                 guint metric,
+                 gint64 metric,
                  GError **error)
 {
        NMIPRoute *route;
@@ -531,6 +549,8 @@ nm_ip_route_new (int family,
                return NULL;
        if (next_hop && !valid_ip (family, next_hop, error))
                return NULL;
+       if (!valid_metric (metric, error))
+               return NULL;
 
        route = g_slice_new0 (NMIPRoute);
        route->refcount = 1;
@@ -550,7 +570,7 @@ nm_ip_route_new (int family,
  * @dest: the IP address of the route's destination
  * @prefix: the address prefix length
  * @next_hop: (allow-none): the IP address of the next hop (or %NULL)
- * @metric: the route metric (or 0 for "default")
+ * @metric: the route metric (or -1 for "default")
  * @error: location to store error, or %NULL
  *
  * Creates a new #NMIPRoute object. @dest and @next_hop (if non-%NULL) must
@@ -563,7 +583,7 @@ nm_ip_route_new_binary (int family,
                         gconstpointer dest,
                         guint prefix,
                         gconstpointer next_hop,
-                        guint metric,
+                        gint64 metric,
                         GError **error)
 {
        NMIPRoute *route;
@@ -573,6 +593,8 @@ nm_ip_route_new_binary (int family,
 
        if (!valid_prefix (family, prefix, error))
                return NULL;
+       if (!valid_metric (metric, error))
+               return NULL;
 
        route = g_slice_new0 (NMIPRoute);
        route->refcount = 1;
@@ -916,12 +938,12 @@ nm_ip_route_set_next_hop_binary (NMIPRoute *route,
  * @route: the #NMIPRoute
  *
  * Gets the route metric property of this route object; lower values
- * indicate "better" or more preferred routes; 0 indicates "default"
+ * indicate "better" or more preferred routes; -1 indicates "default"
  * (meaning NetworkManager will set it appropriately).
  *
  * Returns: the route metric
  **/
-guint32
+gint64
 nm_ip_route_get_metric (NMIPRoute *route)
 {
        g_return_val_if_fail (route != NULL, 0);
@@ -933,15 +955,16 @@ nm_ip_route_get_metric (NMIPRoute *route)
 /**
  * nm_ip_route_set_metric:
  * @route: the #NMIPRoute
- * @metric: the route metric
+ * @metric: the route metric (or -1 for "default")
  *
  * Sets the metric property of this route object.
  **/
 void
 nm_ip_route_set_metric (NMIPRoute *route,
-                        guint32 metric)
+                        gint64 metric)
 {
        g_return_if_fail (route != NULL);
+       g_return_if_fail (valid_metric (metric, NULL));
 
        route->metric = metric;
 }
index 3743776..fba226c 100644 (file)
@@ -78,13 +78,13 @@ NMIPRoute   *nm_ip_route_new                 (int family,
                                               const char *dest,
                                               guint prefix,
                                               const char *next_hop,
-                                              guint metric,
+                                              gint64 metric,
                                               GError **error);
 NMIPRoute   *nm_ip_route_new_binary          (int family,
                                               gconstpointer dest,
                                               guint prefix,
                                               gconstpointer next_hop,
-                                              guint metric,
+                                              gint64 metric,
                                               GError **error);
 
 void         nm_ip_route_ref                 (NMIPRoute  *route);
@@ -111,9 +111,9 @@ gboolean     nm_ip_route_get_next_hop_binary (NMIPRoute  *route,
                                               gpointer next_hop);
 void         nm_ip_route_set_next_hop_binary (NMIPRoute  *route,
                                               gconstpointer next_hop);
-guint32      nm_ip_route_get_metric          (NMIPRoute  *route);
+gint64       nm_ip_route_get_metric          (NMIPRoute  *route);
 void         nm_ip_route_set_metric          (NMIPRoute  *route,
-                                              guint32 metric);
+                                              gint64 metric);
 
 char       **nm_ip_route_get_attribute_names (NMIPRoute   *route);
 GVariant    *nm_ip_route_get_attribute       (NMIPRoute   *route,
index f8105da..5356399 100644 (file)
@@ -1269,7 +1269,8 @@ nm_utils_ip4_routes_to_variant (GPtrArray *routes)
                        nm_ip_route_get_dest_binary (route, &array[0]);
                        array[1] = nm_ip_route_get_prefix (route);
                        nm_ip_route_get_next_hop_binary (route, &array[2]);
-                       array[3] = nm_ip_route_get_metric (route);
+                       /* The old routes format uses "0" for default, not "-1" */
+                       array[3] = MAX (0, nm_ip_route_get_metric (route));
 
                        g_variant_builder_add (&builder, "@au",
                                               g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
@@ -1317,8 +1318,11 @@ nm_utils_ip4_routes_from_variant (GVariant *value)
                }
 
                route = nm_ip_route_new_binary (AF_INET,
-                                               &route_array[0], route_array[1],
-                                               &route_array[2], route_array[3],
+                                               &route_array[0],
+                                               route_array[1],
+                                               &route_array[2],
+                                               /* The old routes format uses "0" for default, not "-1" */
+                                               route_array[3] ? (gint64) route_array[3] : -1,
                                                &error);
                if (route)
                        g_ptr_array_add (routes, route);
@@ -1636,7 +1640,8 @@ nm_utils_ip6_routes_to_variant (GPtrArray *routes)
                        prefix = nm_ip_route_get_prefix (route);
                        nm_ip_route_get_next_hop_binary (route, &next_hop_bytes);
                        next_hop = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &next_hop_bytes, 16, 1);
-                       metric = nm_ip_route_get_metric (route);
+                       /* The old routes format uses "0" for default, not "-1" */
+                       metric = MAX (0, nm_ip_route_get_metric (route));
 
                        g_variant_builder_add (&builder, "(@ayu@ayu)", dest, prefix, next_hop, metric);
                }
@@ -1695,7 +1700,9 @@ nm_utils_ip6_routes_from_variant (GVariant *value)
                        goto next;
                }
 
-               route = nm_ip_route_new_binary (AF_INET6, dest, prefix, next_hop, metric, &error);
+               route = nm_ip_route_new_binary (AF_INET6, dest, prefix, next_hop,
+                                               metric ? (gint64) metric : -1,
+                                               &error);
                if (route)
                        g_ptr_array_add (routes, route);
                else {
@@ -1861,10 +1868,10 @@ nm_utils_ip_routes_to_variant (GPtrArray *routes)
                                                       "next-hop",
                                                       g_variant_new_string (nm_ip_route_get_next_hop (route)));
                        }
-                       if (nm_ip_route_get_metric (route)) {
+                       if (nm_ip_route_get_metric (route) != -1) {
                                g_variant_builder_add (&route_builder, "{sv}",
                                                       "metric",
-                                                      g_variant_new_uint32 (nm_ip_route_get_metric (route)));
+                                                      g_variant_new_uint32 ((guint32) nm_ip_route_get_metric (route)));
                        }
 
                        names = nm_ip_route_get_attribute_names (route);
@@ -1903,7 +1910,8 @@ nm_utils_ip_routes_from_variant (GVariant *value,
        GVariantIter iter, attrs_iter;
        GVariant *route_var;
        const char *dest, *next_hop;
-       guint32 prefix, metric;
+       guint32 prefix, metric32;
+       gint64 metric;
        const char *attr_name;
        GVariant *attr_val;
        NMIPRoute *route;
@@ -1923,8 +1931,10 @@ nm_utils_ip_routes_from_variant (GVariant *value,
                }
                if (!g_variant_lookup (route_var, "next-hop", "&s", &next_hop))
                        next_hop = NULL;
-               if (!g_variant_lookup (route_var, "metric", "u", &metric))
-                       metric = 0;
+               if (g_variant_lookup (route_var, "metric", "u", &metric32))
+                       metric = metric32;
+               else
+                       metric = -1;
 
                route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &error);
                if (!route) {
index 74a7556..604d627 100644 (file)
@@ -178,7 +178,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
        NMIP4Config *config;
        NMIP4ConfigPrivate *priv;
        guint i;
-       guint lowest_metric = G_MAXUINT;
+       guint32 lowest_metric = G_MAXUINT32;
        guint32 old_gateway = 0;
        gboolean has_gateway = FALSE;
 
@@ -361,9 +361,10 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, in
                nm_ip_route_get_dest_binary (s_route, &route.network);
                route.plen = nm_ip_route_get_prefix (s_route);
                nm_ip_route_get_next_hop_binary (s_route, &route.gateway);
-               route.metric = nm_ip_route_get_metric (s_route);
-               if (!route.metric)
+               if (nm_ip_route_get_metric (s_route) == -1)
                        route.metric = default_route_metric;
+               else
+                       route.metric = nm_ip_route_get_metric (s_route);
                route.source = NM_IP_CONFIG_SOURCE_USER;
 
                nm_ip4_config_add_route (config, &route);
@@ -1802,8 +1803,8 @@ get_property (GObject *object, guint prop_id,
                                g_value_array_append (array, &val);
                                g_value_unset (&val);
 
-                               g_value_init (&val, G_TYPE_UINT);
-                               g_value_set_uint (&val, route->metric);
+                               g_value_init (&val, G_TYPE_INT64);
+                               g_value_set_int64 (&val, route->metric);
                                g_value_array_append (array, &val);
                                g_value_unset (&val);
 
index 19552e0..13db237 100644 (file)
@@ -287,7 +287,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co
        NMIP6Config *config;
        NMIP6ConfigPrivate *priv;
        guint i;
-       guint lowest_metric = G_MAXUINT;
+       guint32 lowest_metric = G_MAXUINT32;
        struct in6_addr old_gateway = IN6ADDR_ANY_INIT;
        gboolean has_gateway = FALSE;
        gboolean notify_nameservers = FALSE;
@@ -463,9 +463,10 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, in
                nm_ip_route_get_dest_binary (s_route, &route.network);
                route.plen = nm_ip_route_get_prefix (s_route);
                nm_ip_route_get_next_hop_binary (s_route, &route.gateway);
-               route.metric = nm_ip_route_get_metric (s_route);
-               if (!route.metric)
+               if (nm_ip_route_get_metric (s_route) == -1)
                        route.metric = default_route_metric;
+               else
+                       route.metric = nm_ip_route_get_metric (s_route);
                route.source = NM_IP_CONFIG_SOURCE_USER;
 
                nm_ip6_config_add_route (config, &route);
@@ -1695,8 +1696,8 @@ get_property (GObject *object, guint prop_id,
                                g_value_array_append (array, &val);
                                g_value_unset (&val);
 
-                               g_value_init (&val, G_TYPE_UINT);
-                               g_value_set_uint (&val, route->metric);
+                               g_value_init (&val, G_TYPE_INT64);
+                               g_value_set_int64 (&val, route->metric);
                                g_value_array_append (array, &val);
                                g_value_unset (&val);
 
index 9c3e9b0..5243d77 100644 (file)
@@ -443,7 +443,7 @@ read_one_ip4_route (shvarFile *ifcfg,
 {
        char *ip_tag, *netmask_tag, *gw_tag, *metric_tag, *value;
        char *dest = NULL, *next_hop = NULL;
-       long prefix, metric;
+       gint64 prefix, metric;
        gboolean success = FALSE;
 
        g_return_val_if_fail (ifcfg != NULL, FALSE);
@@ -510,7 +510,7 @@ read_one_ip4_route (shvarFile *ifcfg,
                }
                g_free (value);
        } else
-               metric = 0;
+               metric = -1;
 
        *out_route = nm_ip_route_new (AF_INET, dest, prefix, next_hop, metric, error);
        if (*out_route)
@@ -536,7 +536,7 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError *
        GMatchInfo *match_info;
        NMIPRoute *route = NULL;
        char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
-       long int prefix_int, metric_int;
+       gint64 prefix_int, metric_int;
        gboolean success = FALSE;
 
        const char *pattern_empty = "^\\s*(\\#.*)?$";
@@ -633,7 +633,7 @@ read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError *
 
                /* Metric */
                g_regex_match (regex_metric, *iter, 0, &match_info);
-               metric_int = 0;
+               metric_int = -1;
                if (g_match_info_matches (match_info)) {
                        metric = g_match_info_fetch (match_info, 1);
                        errno = 0;
@@ -745,7 +745,7 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error
        GMatchInfo *match_info;
        NMIPRoute *route = NULL;
        char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
-       long int prefix_int, metric_int;
+       gint64 prefix_int, metric_int;
        gboolean success = FALSE;
 
        const char *pattern_empty = "^\\s*(\\#.*)?$";
@@ -840,7 +840,7 @@ read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error
 
                /* Metric */
                g_regex_match (regex_metric, *iter, 0, &match_info);
-               metric_int = 0;
+               metric_int = -1;
                if (g_match_info_matches (match_info)) {
                        metric = g_match_info_fetch (match_info, 1);
                        errno = 0;
index 4511878..9964254 100644 (file)
@@ -1158,7 +1158,7 @@ test_read_wired_static_routes (void)
        g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "11.22.33.0");
        g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 24);
        g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.5");
-       g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 0);
+       g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1);
 
        ip4_route = nm_setting_ip_config_get_route (s_ip4, 1);
        g_assert (ip4_route);
@@ -1279,7 +1279,7 @@ test_read_wired_static_routes_legacy (void)
        g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "32.42.52.62");
        g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32);
        g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "8.8.8.8");
-       g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 0);
+       g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1);
 
        /* Route #3 */
        ip4_route = nm_setting_ip_config_get_route (s_ip4, 2);
index 559342d..6857c1f 100644 (file)
@@ -1747,7 +1747,8 @@ write_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError
        char **route_items;
        char *route_contents;
        NMIPRoute *route;
-       guint32 prefix, metric;
+       guint32 prefix;
+       gint64 metric;
        guint32 i, num;
        gboolean success = FALSE;
 
@@ -1771,7 +1772,10 @@ write_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError
                next_hop = nm_ip_route_get_next_hop (route);
                metric = nm_ip_route_get_metric (route);
 
-               route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric);
+               if (metric == -1)
+                       route_items[i] = g_strdup_printf ("%s/%u via %s\n", dest, prefix, next_hop);
+               else
+                       route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, (guint32) metric);
        }
        route_items[num] = NULL;
        route_contents = g_strjoinv (NULL, route_items);
@@ -2033,7 +2037,8 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
                for (i = 0; i < 256; i++) {
                        char buf[INET_ADDRSTRLEN];
                        NMIPRoute *route;
-                       guint32 netmask, metric;
+                       guint32 netmask;
+                       gint64 metric;
 
                        addr_key = g_strdup_printf ("ADDRESS%d", i);
                        netmask_key = g_strdup_printf ("NETMASK%d", i);
@@ -2059,10 +2064,10 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 
                                memset (buf, 0, sizeof (buf));
                                metric = nm_ip_route_get_metric (route);
-                               if (metric == 0)
+                               if (metric == -1)
                                        svSetValue (routefile, metric_key, NULL, FALSE);
                                else {
-                                       tmp = g_strdup_printf ("%u", metric);
+                                       tmp = g_strdup_printf ("%u", (guint32) metric);
                                        svSetValue (routefile, metric_key, tmp, FALSE);
                                        g_free (tmp);
                                }
@@ -2204,11 +2209,19 @@ write_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **erro
        route_items = g_malloc0 (sizeof (char*) * (num + 1));
        for (i = 0; i < num; i++) {
                route = nm_setting_ip_config_get_route (s_ip6, i);
-               route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n",
-                                                 nm_ip_route_get_dest (route),
-                                                 nm_ip_route_get_prefix (route),
-                                                 nm_ip_route_get_next_hop (route),
-                                                 nm_ip_route_get_metric (route));
+
+               if (nm_ip_route_get_metric (route) == -1) {
+                       route_items[i] = g_strdup_printf ("%s/%u via %s\n",
+                                                         nm_ip_route_get_dest (route),
+                                                         nm_ip_route_get_prefix (route),
+                                                         nm_ip_route_get_next_hop (route));
+               } else {
+                       route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n",
+                                                         nm_ip_route_get_dest (route),
+                                                         nm_ip_route_get_prefix (route),
+                                                         nm_ip_route_get_next_hop (route),
+                                                         (guint32) nm_ip_route_get_metric (route));
+               }
        }
        route_items[num] = NULL;
        route_contents = g_strjoinv (NULL, route_items);
index 3880e8f..5ffc060 100644 (file)
@@ -30,6 +30,7 @@
 #include "nm-system-config-interface.h"
 #include "nm-logging.h"
 #include "nm-core-internal.h"
+#include "NetworkManagerUtils.h"
 
 #include "net_utils.h"
 #include "wpa_parser.h"
@@ -692,21 +693,21 @@ make_ip4_setting (NMConnection *connection,
                ip_block *current_iblock = iblock;
                const char *metric_str;
                char *stripped;
-               long int metric;
+               gint64 metric;
                NMIPRoute *route;
                GError *local = NULL;
 
                if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
-                       metric = strtol (metric_str, NULL, 10);
+                       metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1);
                } else {
                        metric_str = ifnet_get_global_data ("metric");
                        if (metric_str) {
                                stripped = g_strdup (metric_str);
                                strip_string (stripped, '"');
-                               metric = strtol (metric_str, NULL, 10);
+                               metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1);
                                g_free (stripped);
                        } else
-                               metric = 0;
+                               metric = -1;
                }
 
                route = nm_ip_route_new (AF_INET, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local);
@@ -830,22 +831,20 @@ make_ip6_setting (NMConnection *connection,
                ip_block *current_iblock = iblock;
                const char *metric_str;
                char *stripped;
-               long int metric;
+               gint64 metric;
                NMIPRoute *route;
                GError *local = NULL;
 
                /* metric is not per routes configuration right now
                 * global metric is also supported (metric="x") */
-               if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
-                       metric = strtol (metric_str, NULL, 10);
-                       nm_ip_route_set_metric (route, (guint32) metric);
-               } else {
+               if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL)
+                       metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1);
+               else {
                        metric_str = ifnet_get_global_data ("metric");
                        if (metric_str) {
                                stripped = g_strdup (metric_str);
                                strip_string (stripped, '"');
-                               metric = strtol (metric_str, NULL, 10);
-                               nm_ip_route_set_metric (route, (guint32) metric);
+                               metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1);
                                g_free (stripped);
                        } else
                                metric = 1;
index 793e485..9d65539 100644 (file)
@@ -167,7 +167,9 @@ build_route (int family,
                        return NULL;
        }
 
-       route = nm_ip_route_new (family, dest_str, plen, gateway_str, metric, &error);
+       route = nm_ip_route_new (family, dest_str, plen, gateway_str,
+                                metric ? (gint64) metric : -1,
+                                &error);
        if (!route) {
                nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s route: %s", __func__,
                             family == AF_INET ? "IPv4" : "IPv6",
index 2e0b619..a38a3bd 100644 (file)
@@ -49,7 +49,7 @@ check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int p
 
 static void
 check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int plen,
-                const char *next_hop, int metric)
+                const char *next_hop, gint64 metric)
 {
        NMIPRoute *route = nm_setting_ip_config_get_route (config, idx);
 
@@ -261,17 +261,17 @@ test_read_valid_wired_connection (void)
 
        /* IPv4 routes */
        g_assert (nm_setting_ip_config_get_num_routes (s_ip4) == 12);
-       check_ip_route (s_ip4, 0, "5.6.7.8", 32, NULL, 0);
+       check_ip_route (s_ip4, 0, "5.6.7.8", 32, NULL, -1);
        check_ip_route (s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99);
-       check_ip_route (s_ip4, 2, "1.1.1.2", 12, NULL, 0);
-       check_ip_route (s_ip4, 3, "1.1.1.3", 13, NULL, 0);
-       check_ip_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", 0);
-       check_ip_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", 0);
-       check_ip_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0);
-       check_ip_route (s_ip4, 7, "1.1.1.7", 17, NULL, 0);
-       check_ip_route (s_ip4, 8, "1.1.1.8", 18, NULL, 0);
-       check_ip_route (s_ip4, 9, "1.1.1.9", 19, NULL, 0);
-       check_ip_route (s_ip4, 10, "1.1.1.10", 20, NULL, 0);
+       check_ip_route (s_ip4, 2, "1.1.1.2", 12, NULL, -1);
+       check_ip_route (s_ip4, 3, "1.1.1.3", 13, NULL, -1);
+       check_ip_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", -1);
+       check_ip_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", -1);
+       check_ip_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", -1);
+       check_ip_route (s_ip4, 7, "1.1.1.7", 17, NULL, -1);
+       check_ip_route (s_ip4, 8, "1.1.1.8", 18, NULL, -1);
+       check_ip_route (s_ip4, 9, "1.1.1.9", 19, NULL, -1);
+       check_ip_route (s_ip4, 10, "1.1.1.10", 20, NULL, -1);
        check_ip_route (s_ip4, 11, "1.1.1.11", 21, NULL, 21);
 
        /* ===== IPv6 SETTING ===== */
@@ -354,13 +354,13 @@ test_read_valid_wired_connection (void)
 
        /* Route #1 */
        g_assert (nm_setting_ip_config_get_num_routes (s_ip6) == 7);
-       check_ip_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", 0);
+       check_ip_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", -1);
        check_ip_route (s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99);
-       check_ip_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, 0);
+       check_ip_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, -1);
        check_ip_route (s_ip6, 3, "6:7:8:9:0:1:2:3", 126, NULL, 1);
        check_ip_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5);
        check_ip_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6);
-       check_ip_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, 0);
+       check_ip_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1);
        g_object_unref (connection);
 }
 
@@ -384,7 +384,7 @@ add_one_ip_route (NMSettingIPConfig *s_ip,
                   const char *dest,
                   const char *nh,
                   guint32 prefix,
-                  guint32 metric)
+                  gint64 metric)
 {
        NMIPRoute *route;
        GError *error = NULL;
@@ -484,7 +484,7 @@ test_write_wired_connection (void)
        /* Routes */
        add_one_ip_route (s_ip4, route1, route1_nh, 24, 3);
        add_one_ip_route (s_ip4, route2, route2_nh, 8, 1);
-       add_one_ip_route (s_ip4, route3, route3_nh, 7, 0);
+       add_one_ip_route (s_ip4, route3, route3_nh, 7, -1);
        add_one_ip_route (s_ip4, route4, route4_nh, 6, 4);
 
        /* DNS servers */
@@ -508,7 +508,7 @@ test_write_wired_connection (void)
        add_one_ip_route (s_ip6, route6_1, route6_1_nh, 64, 3);
        add_one_ip_route (s_ip6, route6_2, route6_2_nh, 56, 1);
        add_one_ip_route (s_ip6, route6_3, route6_3_nh, 63, 5);
-       add_one_ip_route (s_ip6, route6_4, route6_4_nh, 62, 0);
+       add_one_ip_route (s_ip6, route6_4, route6_4_nh, 62, -1);
 
        /* DNS servers */
        nm_setting_ip_config_add_dns (s_ip6, dns6_1);
index 24d7aba..77c9960 100644 (file)
@@ -142,7 +142,7 @@ write_ip_values (GKeyFile *file,
                        addr = nm_ip_route_get_dest (route);
                        plen = nm_ip_route_get_prefix (route);
                        gw = nm_ip_route_get_next_hop (route);
-                       metric = nm_ip_route_get_metric (route);
+                       metric = MAX (0, nm_ip_route_get_metric (route));
                } else {
                        NMIPAddress *address = array->pdata[i];