summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@redhat.com>2014-12-03 11:10:17 -0500
committerDan Winship <danw@redhat.com>2014-12-03 16:31:50 -0500
commitcb025dba5b39ba40474d9dbb23fa651dc9aa8e01 (patch)
tree01a2e6438ff01c04c384d80d8ca0d22993434746
parent3cf2fbbf47dbb6a2f7a077b84d7bb50374f83f27 (diff)
downloadNetworkManager-cb025dba5b39ba40474d9dbb23fa651dc9aa8e01.tar.gz
libnm-core: fix the rule for parsing 'gateway' out of 'addresses' (rh #1170199)
We were always using the gateway field of the first address in ipv4.addresses / ipv6.addresses to set the gateway, but to be compatible with old behavior, we should actually be using the first non-0 gateway field (if the first one is 0).
-rw-r--r--libnm-core/nm-utils.c38
-rw-r--r--libnm-core/tests/test-general.c72
2 files changed, 84 insertions, 26 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 9ccb107c61..f1f5a9e8ca 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -1228,14 +1228,12 @@ nm_utils_ip4_addresses_from_variant (GVariant *value, char **out_gateway)
}
addr = nm_ip_address_new_binary (AF_INET, &addr_array[0], addr_array[1], &error);
- if (addresses->len == 0 && out_gateway) {
- if (addr_array[2])
- *out_gateway = g_strdup (nm_utils_inet4_ntop (addr_array[2], NULL));
- }
-
- if (addr)
+ if (addr) {
g_ptr_array_add (addresses, addr);
- else {
+
+ if (addr_array[2] && out_gateway && !*out_gateway)
+ *out_gateway = g_strdup (nm_utils_inet4_ntop (addr_array[2], NULL));
+ } else {
g_warning ("Ignoring invalid IP4 address: %s", error->message);
g_clear_error (&error);
}
@@ -1586,21 +1584,21 @@ nm_utils_ip6_addresses_from_variant (GVariant *value, char **out_gateway)
goto next;
}
- if (addresses->len == 0 && out_gateway) {
- gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1);
- if (gateway_len != 16) {
- g_warning ("%s: ignoring invalid IP6 address of length %d",
- __func__, (int) gateway_len);
- goto next;
- }
- if (!IN6_IS_ADDR_UNSPECIFIED (gateway_bytes))
- *out_gateway = g_strdup (nm_utils_inet6_ntop (gateway_bytes, NULL));
- }
-
addr = nm_ip_address_new_binary (AF_INET6, addr_bytes, prefix, &error);
- if (addr)
+ if (addr) {
g_ptr_array_add (addresses, addr);
- else {
+
+ if (out_gateway && !*out_gateway) {
+ gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1);
+ if (gateway_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) gateway_len);
+ goto next;
+ }
+ if (!IN6_IS_ADDR_UNSPECIFIED (gateway_bytes))
+ *out_gateway = g_strdup (nm_utils_inet6_ntop (gateway_bytes, NULL));
+ }
+ } else {
g_warning ("Ignoring invalid IP4 address: %s", error->message);
g_clear_error (&error);
}
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 1a0ee99d52..76d6d0ff80 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -3561,6 +3561,9 @@ test_setting_ip4_gateway (void)
GVariant *conn_dict, *ip4_dict, *value;
GVariantIter iter;
GVariant *addr_var;
+ guint32 addr_vals_0[] = { 0x0a01a8c0, 0x00000018, 0x00000000 };
+ guint32 addr_vals_1[] = { 0x0b01a8c0, 0x00000018, 0x0101a8c0 };
+ GVariantBuilder addrs_builder;
GError *error = NULL;
/* When serializing on the daemon side, ipv4.gateway is copied to the first
@@ -3610,8 +3613,8 @@ test_setting_ip4_gateway (void)
g_variant_unref (ip4_dict);
- /* When deserializing an old-style connection, the gateway from the first address
- * is copied to :gateway.
+ /* When deserializing an old-style connection, the first non-0 gateway in
+ * ipv4.addresses is copied to :gateway.
*/
NMTST_VARIANT_EDITOR (conn_dict,
NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME,
@@ -3621,13 +3624,35 @@ test_setting_ip4_gateway (void)
);
conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
- g_variant_unref (conn_dict);
g_assert_no_error (error);
s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1");
g_object_unref (conn);
+
+ /* Try again with the gateway in the second address. */
+ g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("aau"));
+ g_variant_builder_add (&addrs_builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ addr_vals_0, 3, 4));
+ g_variant_builder_add (&addrs_builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ addr_vals_1, 3, 4));
+
+ NMTST_VARIANT_EDITOR (conn_dict,
+ NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ "addresses", "aau", &addrs_builder);
+ );
+
+ conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
+ g_assert_no_error (error);
+ g_variant_unref (conn_dict);
+
+ s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn);
+ g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1");
+
+ g_object_unref (conn);
}
static void
@@ -3639,6 +3664,13 @@ test_setting_ip6_gateway (void)
GVariant *conn_dict, *ip6_dict, *value;
GVariantIter iter;
GVariant *gateway_var;
+ GVariantBuilder addrs_builder;
+ guint8 addr_bytes_0[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a };
+ guint8 addr_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b };
+ guint8 gateway_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
GError *error = NULL;
/* When serializing on the daemon side, ipv6.gateway is copied to the first
@@ -3687,8 +3719,8 @@ test_setting_ip6_gateway (void)
g_variant_unref (ip6_dict);
- /* When deserializing an old-style connection, the gateway from the first address
- * is copied to :gateway.
+ /* When deserializing an old-style connection, the first non-0 gateway in
+ * ipv6.addresses is copied to :gateway.
*/
NMTST_VARIANT_EDITOR (conn_dict,
NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
@@ -3698,13 +3730,41 @@ test_setting_ip6_gateway (void)
);
conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
- g_variant_unref (conn_dict);
g_assert_no_error (error);
s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1");
g_object_unref (conn);
+
+ /* Try again with the gateway in the second address. */
+ g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("a(ayuay)"));
+ g_variant_builder_add (&addrs_builder, "(@ayu@ay)",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ addr_bytes_0, 16, 1),
+ 64,
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ &in6addr_any, 16, 1));
+ g_variant_builder_add (&addrs_builder, "(@ayu@ay)",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ addr_bytes_1, 16, 1),
+ 64,
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ gateway_bytes_1, 16, 1));
+
+ NMTST_VARIANT_EDITOR (conn_dict,
+ NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ "addresses", "a(ayuay)", &addrs_builder);
+ );
+
+ conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
+ g_assert_no_error (error);
+ g_variant_unref (conn_dict);
+
+ s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn);
+ g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1");
+
+ g_object_unref (conn);
}
typedef struct {