summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-05-27 13:33:50 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-05-31 14:33:23 +0200
commitf940428c659eb9bd797da4545dd000bfa18ca99c (patch)
tree56ef655b75bf25a7f0874b26fca39ecbdd2c60ae
parentd43a0459bc4fe4ccbfc092465dec76b7ee8260aa (diff)
downloadNetworkManager-f940428c659eb9bd797da4545dd000bfa18ca99c.tar.gz
dhcp: let users override FQDN dhclient options
When the ipv4.dhcp-fqdn property is set, NM adds the following options to dhclient.conf: send fqdn.fqdn "foo.bar"; send fqdn.encoded on; send fqdn.server-update on; which enable the S (server-update) and E (encoded) flags in DHCP option 81, since they are sensible default values and dhclient requires a "send fqdn.server-update [on|off]" directive in order to send the option. Users may want to change these flags according to their server's configuration, but this is not possible at the moment since NM options are placed after user's ones, overriding them. To fix this, collect user's fqdn options and add them after NM configuration; note that the fqdn.fqdn option still can't be overridden by users, as NM must control the FQDN sent to server. Fixes: c3573ebf2bb4958ee2ebf08e7ebac351765b92ef
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.c26
-rw-r--r--src/dhcp-manager/tests/test-dhcp-dhclient.c41
2 files changed, 64 insertions, 3 deletions
diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
index 72bd00a444..8d4c54ae15 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
@@ -36,8 +36,9 @@
#define HOSTNAME4_TAG "send host-name"
#define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager"
-#define FQDN_TAG "send fqdn.fqdn"
-#define FQDN_FORMAT FQDN_TAG " \"%s\"; # added by NetworkManager"
+#define FQDN_TAG_PREFIX "send fqdn."
+#define FQDN_TAG FQDN_TAG_PREFIX "fqdn"
+#define FQDN_FORMAT FQDN_TAG " \"%s\"; # added by NetworkManager"
#define ALSOREQ_TAG "also request "
@@ -205,13 +206,14 @@ nm_dhcp_dhclient_create_config (const char *interface,
GBytes **out_new_client_id)
{
GString *new_contents;
- GPtrArray *alsoreq;
+ GPtrArray *alsoreq, *fqdn_opts;
int i;
g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL);
new_contents = g_string_new (_("# Created by NetworkManager\n"));
alsoreq = g_ptr_array_sized_new (5);
+ fqdn_opts = g_ptr_array_sized_new (5);
if (orig_contents) {
char **lines, **line;
@@ -244,6 +246,14 @@ nm_dhcp_dhclient_create_config (const char *interface,
continue;
}
+ /* To let user's FQDN options (except "fqdn.fqdn") override the
+ * default ones set by NM, add them later
+ */
+ if (!strncmp (p, FQDN_TAG_PREFIX, NM_STRLEN (FQDN_TAG_PREFIX))) {
+ g_ptr_array_add (fqdn_opts, g_strdup (p + NM_STRLEN (FQDN_TAG_PREFIX)));
+ continue;
+ }
+
/* Ignore 'script' since we pass our own */
if (g_str_has_prefix (p, "script "))
continue;
@@ -320,6 +330,16 @@ nm_dhcp_dhclient_create_config (const char *interface,
}
g_ptr_array_free (alsoreq, TRUE);
+ for (i = 0; i < fqdn_opts->len; i++) {
+ char *t = g_ptr_array_index (fqdn_opts, i);
+
+ if (i == 0)
+ g_string_append_printf (new_contents, "\n# FQDN options from %s\n", orig_path);
+ g_string_append_printf (new_contents, FQDN_TAG_PREFIX "%s\n", t);
+ g_free (t);
+ }
+ g_ptr_array_free (fqdn_opts, TRUE);
+
g_string_append_c (new_contents, '\n');
if (anycast_addr) {
diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c
index 76c9ff5002..77849c8c38 100644
--- a/src/dhcp-manager/tests/test-dhcp-dhclient.c
+++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c
@@ -334,6 +334,46 @@ test_fqdn (void)
NULL);
}
+static const char *fqdn_options_override_orig = \
+ "\n"
+ "send fqdn.fqdn \"foobar.com\"\n" /* NM must ignore this ... */
+ "send fqdn.encoded off;\n" /* ... and honor these */
+ "send fqdn.server-update off;\n";
+
+static const char *fqdn_options_override_expected = \
+ "# Created by NetworkManager\n"
+ "# Merged from /path/to/dhclient.conf\n"
+ "\n"
+ "send fqdn.fqdn \"example2.com\"; # added by NetworkManager\n"
+ "send fqdn.encoded on;\n"
+ "send fqdn.server-update on;\n"
+ "\n"
+ "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+ "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+ "option wpad code 252 = string;\n"
+ "\n"
+ "also request rfc3442-classless-static-routes;\n"
+ "also request ms-classless-static-routes;\n"
+ "also request static-routes;\n"
+ "also request wpad;\n"
+ "also request ntp-servers;\n"
+ "\n"
+ "# FQDN options from /path/to/dhclient.conf\n"
+ "send fqdn.encoded off;\n"
+ "send fqdn.server-update off;\n\n";
+
+static void
+test_fqdn_options_override (void)
+{
+ test_config (fqdn_options_override_orig,
+ fqdn_options_override_expected,
+ FALSE, NULL,
+ "example2.com", NULL,
+ NULL,
+ "eth0",
+ NULL);
+}
+
/*******************************************/
static const char *override_hostname_orig = \
@@ -804,6 +844,7 @@ main (int argc, char **argv)
g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
g_test_add_func ("/dhcp/dhclient/fqdn", test_fqdn);
+ g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);
g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname);
g_test_add_func ("/dhcp/dhclient/override_hostname6", test_override_hostname6);
g_test_add_func ("/dhcp/dhclient/nonfqdn_hostname6", test_nonfqdn_hostname6);