diff options
| author | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
| commit | 8bdf070ff046f482f6eb5e2b15ebc216f5d1e3da (patch) | |
| tree | f706478d189d54c6532e8863d4b0d5ff5575af60 /src/nm-initrd-generator | |
| parent | 818258cf34b83fbc754633295e1052d4752d7b15 (diff) | |
New upstream version 1.51.90 upstream/1.51.90
Diffstat (limited to 'src/nm-initrd-generator')
| -rw-r--r-- | src/nm-initrd-generator/nm-initrd-generator.c | 66 | ||||
| -rw-r--r-- | src/nm-initrd-generator/nm-initrd-generator.h | 5 | ||||
| -rw-r--r-- | src/nm-initrd-generator/nmi-cmdline-reader.c | 69 | ||||
| -rw-r--r-- | src/nm-initrd-generator/tests/test-cmdline-reader.c | 100 |
4 files changed, 208 insertions, 32 deletions
diff --git a/src/nm-initrd-generator/nm-initrd-generator.c b/src/nm-initrd-generator/nm-initrd-generator.c index d84e95e5..b89b4e41 100644 --- a/src/nm-initrd-generator/nm-initrd-generator.c +++ b/src/nm-initrd-generator/nm-initrd-generator.c @@ -11,6 +11,7 @@ #include "libnm-core-intern/nm-core-internal.h" #include "libnm-core-intern/nm-keyfile-internal.h" #include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" #include "libnm-log-core/nm-logging.h" /*****************************************************************************/ @@ -154,6 +155,9 @@ main(int argc, char *argv[]) gint64 carrier_timeout_sec = 0; gs_unref_array GArray *confs = NULL; guint i; + gs_strfreev char **global_dns_servers = NULL; + gs_free char *dns_backend = NULL; + gs_free char *dns_resolve_mode = NULL; option_context = g_option_context_new( "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " @@ -193,7 +197,10 @@ main(int argc, char *argv[]) sysfs_dir, (const char *const *) remaining, &hostname, - &carrier_timeout_sec); + &carrier_timeout_sec, + &global_dns_servers, + &dns_backend, + &dns_resolve_mode); confs = g_array_new(FALSE, FALSE, sizeof(NMUtilsNamedValue)); g_array_set_clear_func(confs, (GDestroyNotify) nm_utils_named_value_clear_with_g_free); @@ -226,13 +233,68 @@ main(int argc, char *argv[]) : "from \"rd.net.timeout.carrier\""); } - v = (NMUtilsNamedValue){ + v = (NMUtilsNamedValue) { .name = g_strdup_printf("%s/15-carrier-timeout.conf", run_config_dir), .value_str = g_key_file_to_data(keyfile, NULL, NULL), }; g_array_append_val(confs, v); } + if (global_dns_servers || dns_resolve_mode) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMUtilsNamedValue v; + gs_free char *dns_list = NULL; + + keyfile = g_key_file_new(); + g_key_file_set_list_separator(keyfile, NM_CONFIG_KEYFILE_LIST_SEPARATOR); + nm_key_file_add_group(keyfile, NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS); + + if (dns_resolve_mode) { + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS, + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE, + dns_resolve_mode); + } + + if (global_dns_servers) { + dns_list = g_strjoinv(",", global_dns_servers); + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "*", + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_SERVERS, + dns_list); + } + + if (!dump_to_stdout) { + add_keyfile_comment(keyfile, "from \"rd.net.dns\" and \"rd.net.dns-resolv-mode\""); + } + + v = (NMUtilsNamedValue) { + .name = g_strdup_printf("%s/16-global-dns.conf", run_config_dir), + .value_str = g_key_file_to_data(keyfile, NULL, NULL), + }; + g_array_append_val(confs, v); + } + + if (dns_backend) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMUtilsNamedValue v; + + keyfile = g_key_file_new(); + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_DNS, + dns_backend); + if (!dump_to_stdout) { + add_keyfile_comment(keyfile, "from \"rd.net.dns-backend\""); + } + + v = (NMUtilsNamedValue) { + .name = g_strdup_printf("%s/16-dns-backend.conf", run_config_dir), + .value_str = g_key_file_to_data(keyfile, NULL, NULL), + }; + g_array_append_val(confs, v); + } + if (dump_to_stdout) { nm_clear_g_free(&connections_dir); nm_clear_g_free(&initrd_dir); diff --git a/src/nm-initrd-generator/nm-initrd-generator.h b/src/nm-initrd-generator/nm-initrd-generator.h index 87db9fc6..c2baad4e 100644 --- a/src/nm-initrd-generator/nm-initrd-generator.h +++ b/src/nm-initrd-generator/nm-initrd-generator.h @@ -45,6 +45,9 @@ GHashTable *nmi_cmdline_reader_parse(const char *etc_connections_dir, const char *sysfs_dir, const char *const *argv, char **hostname, - gint64 *carrier_timeout_sec); + gint64 *carrier_timeout_sec, + char ***global_dns_servers, + char **dns_backend, + char **dns_resolve_mode); #endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c index 3703ff0c..d6dc1fcb 100644 --- a/src/nm-initrd-generator/nmi-cmdline-reader.c +++ b/src/nm-initrd-generator/nmi-cmdline-reader.c @@ -34,6 +34,9 @@ typedef struct { NMConnection *default_connection; /* connection not bound to any ifname */ char *hostname; GHashTable *znet_ifnames; + GPtrArray *global_dns; + char *dns_backend; + char *dns_resolve_mode; /* Parameters to be set for all connections */ gboolean ignore_auto_dns; @@ -50,7 +53,7 @@ reader_new(void) Reader *reader; reader = g_slice_new(Reader); - *reader = (Reader){ + *reader = (Reader) { .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), .explicit_ip_connections = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL), @@ -69,12 +72,15 @@ reader_destroy(Reader *reader, gboolean free_hash) g_ptr_array_unref(reader->array); g_ptr_array_unref(reader->vlan_parents); + nm_clear_pointer(&reader->global_dns, g_ptr_array_unref); g_hash_table_unref(reader->explicit_ip_connections); hash = g_steal_pointer(&reader->hash); nm_clear_g_free(&reader->hostname); g_hash_table_unref(reader->znet_ifnames); nm_clear_g_free(&reader->dhcp4_vci); nm_clear_g_free(&reader->dhcp_dscp); + nm_clear_g_free(&reader->dns_backend); + nm_clear_g_free(&reader->dns_resolve_mode); nm_g_slice_free(reader); if (!free_hash) return g_steal_pointer(&hash); @@ -1220,6 +1226,43 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames) } static void +reader_parse_global_dns(Reader *reader, char *argument) +{ + if (!nm_dns_uri_parse(AF_UNSPEC, argument, NULL)) { + _LOGW(LOGD_CORE, "rd.net.dns: invalid server '%s'", argument); + return; + } + + if (!reader->global_dns) { + reader->global_dns = g_ptr_array_new_with_free_func(g_free); + } + + g_ptr_array_add(reader->global_dns, g_strdup(argument)); +} + +static void +reader_parse_dns_backend(Reader *reader, const char *argument) +{ + if (!NM_IN_STRSET(argument, "none", "default", "systemd-resolved", "dnsmasq", "dnsconfd")) { + _LOGW(LOGD_CORE, "rd.net.dns-backend: invalid value '%s'", argument); + return; + } + + reader->dns_backend = g_strdup(argument); +} + +static void +reader_parse_dns_resolve_mode(Reader *reader, const char *argument) +{ + if (!NM_IN_STRSET(argument, "backup", "prefer", "exclusive")) { + _LOGW(LOGD_CORE, "rd.net.dns-resolve-mode: invalid value '%s'", argument); + return; + } + + reader->dns_resolve_mode = g_strdup(argument); +} + +static void reader_parse_ethtool(Reader *reader, char *argument) { NMConnection *connection; @@ -1392,7 +1435,10 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, const char *sysfs_dir, const char *const *argv, char **hostname, - gint64 *carrier_timeout_sec) + gint64 *carrier_timeout_sec, + char ***global_dns_servers, + char **dns_backend, + char **dns_resolve_mode) { Reader *reader; const char *tag; @@ -1509,6 +1555,12 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, bootif_val = g_strdup(argument); } else if (nm_streq(tag, "rd.ethtool")) { reader_parse_ethtool(reader, argument); + } else if (nm_streq(tag, "rd.net.dns")) { + reader_parse_global_dns(reader, argument); + } else if (nm_streq(tag, "rd.net.dns-backend")) { + reader_parse_dns_backend(reader, argument); + } else if (nm_streq(tag, "rd.net.dns-resolve-mode")) { + reader_parse_dns_resolve_mode(reader, argument); } } @@ -1623,8 +1675,19 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, g_hash_table_foreach(reader->hash, _normalize_conn, NULL); NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname)); - NM_SET_OUT(carrier_timeout_sec, reader->carrier_timeout_sec); + NM_SET_OUT(dns_backend, g_steal_pointer(&reader->dns_backend)); + NM_SET_OUT(dns_resolve_mode, g_steal_pointer(&reader->dns_resolve_mode)); + + if (reader->global_dns) { + if (global_dns_servers) { + g_ptr_array_add(reader->global_dns, NULL); + *global_dns_servers = (char **) g_ptr_array_free(reader->global_dns, FALSE); + reader->global_dns = NULL; + } + } else { + NM_SET_OUT(global_dns_servers, NULL); + } return reader_destroy(reader, FALSE); } diff --git a/src/nm-initrd-generator/tests/test-cmdline-reader.c b/src/nm-initrd-generator/tests/test-cmdline-reader.c index 33b83497..a0100764 100644 --- a/src/nm-initrd-generator/tests/test-cmdline-reader.c +++ b/src/nm-initrd-generator/tests/test-cmdline-reader.c @@ -23,7 +23,12 @@ /*****************************************************************************/ -#define _parse(ARGV, out_hostname, out_carrier_timeout_sec) \ +#define _parse(ARGV, \ + out_hostname, \ + out_carrier_timeout_sec, \ + _out_global_dns_servers, \ + _out_dns_backend, \ + _out_dns_resolve_mode) \ ({ \ const char *const *const _ARGV = (ARGV); \ char **const _out_hostname = (out_hostname); \ @@ -34,26 +39,31 @@ TEST_INITRD_DIR "/sysfs", \ _ARGV, \ _out_hostname, \ - _out_carrier_timeout_sec); \ - \ + _out_carrier_timeout_sec, \ + _out_global_dns_servers, \ + _out_dns_backend, \ + _out_dns_resolve_mode); \ g_assert(_connections); \ \ _connections; \ }) -#define _parse_cons(ARGV) \ - ({ \ - GHashTable *_con_connections; \ - gs_free char *_con_hostname = NULL; \ - gint64 _con_carrier_timeout_sec = 0; \ - \ - _con_connections = _parse((ARGV), \ - nmtst_get_rand_bool() ? &_con_hostname : NULL, \ - nmtst_get_rand_bool() ? &_con_carrier_timeout_sec : NULL); \ - g_assert_cmpstr(_con_hostname, ==, NULL); \ - g_assert_cmpint(_con_carrier_timeout_sec, ==, 0); \ - \ - _con_connections; \ +#define _parse_cons(ARGV) \ + ({ \ + GHashTable *_con_connections; \ + gs_free char *_con_hostname = NULL; \ + gint64 _con_carrier_timeout_sec = 0; \ + \ + _con_connections = _parse((ARGV), \ + nmtst_get_rand_bool() ? &_con_hostname : NULL, \ + nmtst_get_rand_bool() ? &_con_carrier_timeout_sec : NULL, \ + NULL, \ + NULL, \ + NULL); \ + g_assert_cmpstr(_con_hostname, ==, NULL); \ + g_assert_cmpint(_con_carrier_timeout_sec, ==, 0); \ + \ + _con_connections; \ }) #define _parse_con(ARGV, connection_name) \ @@ -154,7 +164,7 @@ test_dhcp_with_hostname(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "host1"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -424,7 +434,7 @@ test_if_ip4_manual(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "hostname1.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -505,7 +515,7 @@ test_if_ip4_auto(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "myhostname"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -596,7 +606,7 @@ test_if_ip6_manual(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -684,7 +694,7 @@ test_if_mac_ifname(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -1840,7 +1850,7 @@ test_rd_znet(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -1927,7 +1937,7 @@ test_rd_znet_legacy(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -2006,7 +2016,7 @@ test_rd_znet_ifnames(void) gint64 carrier_timeout_sec = 0; const char *const *v_subchannels; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); connection = g_hash_table_lookup(connections, "zeth0"); @@ -2281,7 +2291,7 @@ test_nameserver(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -2460,12 +2470,49 @@ test_carrier_timeout(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 0); g_assert_cmpstr(hostname, ==, NULL); g_assert_cmpint(carrier_timeout_sec, ==, 20); } +static void +test_global_dns(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *ARGV = NM_MAKE_STRV("rd.net.dns=dns+tls://8.8.8.8", + "rd.net.dns=1.1.1.1", + "rd.net.dns=foobar", + "rd.net.dns=dns+tls://[fd01::1]:35#name", + "rd.net.dns-backend=dnsconfd", + "rd.net.dns-resolve-mode=exclusive"); + gs_free char *hostname = NULL; + gs_strfreev char **global_dns_servers = NULL; + gs_free char *dns_backend = NULL; + gs_free char *dns_resolve_mode = NULL; + gint64 carrier_timeout_sec = 0; + + NMTST_EXPECT_NM_WARN("cmdline-reader: rd.net.dns: invalid server 'foobar'"); + connections = _parse(ARGV, + &hostname, + &carrier_timeout_sec, + &global_dns_servers, + &dns_backend, + &dns_resolve_mode); + g_test_assert_expected_messages(); + + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + g_assert(global_dns_servers != NULL); + g_assert_cmpstr(global_dns_servers[0], ==, "dns+tls://8.8.8.8"); + g_assert_cmpstr(global_dns_servers[1], ==, "1.1.1.1"); + g_assert_cmpstr(global_dns_servers[2], ==, "dns+tls://[fd01::1]:35#name"); + g_assert_cmpstr(global_dns_servers[3], ==, NULL); + g_assert_cmpstr(dns_backend, ==, "dnsconfd"); + g_assert_cmpstr(dns_resolve_mode, ==, "exclusive"); +} + #define _ethtool_check_inval(arg) \ G_STMT_START \ { \ @@ -2686,6 +2733,7 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/carrier_timeout", test_carrier_timeout); g_test_add_func("/initrd/cmdline/rd_ethtool", test_rd_ethtool); g_test_add_func("/initrd/cmdline/plain_equal_char", test_plain_equal_char); + g_test_add_func("/initrd/cmdline/global_dns", test_global_dns); return g_test_run(); } |