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:36:41 +0200
commit30f53e7e22628fb04d80dec978123b9b3653b89d (patch)
tree3f9d14387073e46eb6e68650d03cf3d6281fab2e
parent951013d1e1182510366fb0de088179a3303ea65d (diff)
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 (cherry picked from commit f940428c659eb9bd797da4545dd000bfa18ca99c)
-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 bf2df1e034..008f8af2ba 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 0561d43c14..046dd7e242 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);