diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index 0abbca73a..16fb7e96b 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -247,6 +247,20 @@ dump_ip_to_props(const NML3ConfigData *l3cd, int addr_family, GVariantBuilder *b } g_variant_builder_add(builder, "{sv}", "addresses", g_variant_builder_end(&int_builder)); + /* We used to send name servers as a entry with key "nameservers" and binary + * value. That no longer works because name servers can be URIs. Send the + * value as an array of strings. + * To avoid problems when the NM and NM-dispatcher version don't match (right + * after an upgrade or downgrade), still send the old key in the old format, + * and introduce a new key for the new format. */ + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("as")); + strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &n); + for (i = 0; i < n; i++) + g_variant_builder_add(&int_builder, "s", strarr[i]); + g_variant_builder_add(builder, "{sv}", "nameservers-full", g_variant_builder_end(&int_builder)); + + /* Old format for nameservers. This can be removed in the future when it's + * expected that both NM and NM-dispatcher support the new format.*/ if (IS_IPv4) g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); else diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c index 6659936f4..030506e94 100644 --- a/src/nm-dispatcher/nm-dispatcher-utils.c +++ b/src/nm-dispatcher/nm-dispatcher-utils.c @@ -264,22 +264,43 @@ construct_ip_items(GPtrArray *items, int addr_family, GVariant *ip_config, const g_variant_unref(val); } - val = g_variant_lookup_value(ip_config, - "nameservers", - addr_family == AF_INET ? G_VARIANT_TYPE("au") - : G_VARIANT_TYPE("aay")); + /* For name servers, prefer the new key and fall back to the old one. */ + val = g_variant_lookup_value(ip_config, "nameservers-full", G_VARIANT_TYPE("as")); if (val) { - gs_strfreev char **v = NULL; + nm_auto_unref_ptrarray GPtrArray *arr = NULL; + GVariantIter iter; + const char *str; + + arr = g_ptr_array_new_full(g_variant_n_children(val) + 1, NULL); + g_variant_iter_init(&iter, val); + while (g_variant_iter_next(&iter, "&s", &str)) { + g_ptr_array_add(arr, (gpointer) str); + } + g_ptr_array_add(arr, NULL); - if (addr_family == AF_INET) - v = nm_utils_ip4_dns_from_variant(val); - else - v = nm_utils_ip6_dns_from_variant(val); _items_add_strv(items, prefix, addr_family == AF_INET ? "IP4_NAMESERVERS" : "IP6_NAMESERVERS", - NM_CAST_STRV_CC(v)); + (const char *const *) arr->pdata); g_variant_unref(val); + } else { + val = g_variant_lookup_value(ip_config, + "nameservers", + addr_family == AF_INET ? G_VARIANT_TYPE("au") + : G_VARIANT_TYPE("aay")); + if (val) { + gs_strfreev char **v = NULL; + + if (addr_family == AF_INET) + v = nm_utils_ip4_dns_from_variant(val); + else + v = nm_utils_ip6_dns_from_variant(val); + _items_add_strv(items, + prefix, + addr_family == AF_INET ? "IP4_NAMESERVERS" : "IP6_NAMESERVERS", + NM_CAST_STRV_CC(v)); + g_variant_unref(val); + } } val = g_variant_lookup_value(ip_config, "domains", G_VARIANT_TYPE_STRING_ARRAY);