summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-10-06 08:27:18 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2019-10-07 09:10:35 +0200
commit84525174554e3402639ff99bbf7fcdaeec5591a3 (patch)
treeb06910d811b7e50fedd6d84bac329910c2a59931
parentc6d53c550094163af8b7f91540162507e84b5639 (diff)
downloadNetworkManager-bg/dhcp-conditionals-rh1758550.tar.gz
dhcp: include conditionals from existing dhclient configurationbg/dhcp-conditionals-rh1758550
Since commit 159ff23268b1 ('dhcp/dhclient-utils: skip over dhclient.conf blocks') we skip blocks enclosed in lines containing '{' and '}' because NM should ignore 'lease', 'alias' and other declarations. However, conditional statements seem useful and should not be skipped. https://bugzilla.redhat.com/show_bug.cgi?id=1758550
-rw-r--r--src/dhcp/nm-dhcp-dhclient-utils.c43
-rw-r--r--src/dhcp/tests/test-dhcp-dhclient.c19
2 files changed, 50 insertions, 12 deletions
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c
index 83b6f79445..229a90758b 100644
--- a/src/dhcp/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c
@@ -291,11 +291,13 @@ nm_dhcp_dhclient_create_config (const char *interface,
if (orig_contents) {
gs_free const char **lines = NULL;
gsize line_i;
- int nest = 0;
+ nm_auto_free_gstring GString *blocks_stack = NULL;
+ guint blocks_skip = 0;
gboolean in_alsoreq = FALSE;
gboolean in_req = FALSE;
char intf[IFNAMSIZ];
+ blocks_stack = g_string_new (NULL);
g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);
intf[0] = '\0';
@@ -313,19 +315,38 @@ nm_dhcp_dhclient_create_config (const char *interface,
if (in_req) {
/* pass */
} else if (strchr (p, '{')) {
- nest++;
- if ( !intf[0]
- && NM_STR_HAS_PREFIX (p, "interface"))
- if (read_interface (p, intf, sizeof (intf)))
- continue;
+ if ( NM_STR_HAS_PREFIX (p, "lease")
+ || NM_STR_HAS_PREFIX (p, "alias")
+ || NM_STR_HAS_PREFIX (p, "interface")
+ || NM_STR_HAS_PREFIX (p, "pseudo")) {
+ /* skip over these blocks, except 'interface' when it
+ * matches the current interface */
+ blocks_skip++;
+ g_string_append_c (blocks_stack, 'b');
+ if ( !intf[0]
+ && NM_STR_HAS_PREFIX (p, "interface")) {
+ if (read_interface (p, intf, sizeof (intf)))
+ continue;
+ }
+ } else {
+ /* allow other blocks (conditionals) */
+ if (!strchr (p, '}')) /* '} else {' */
+ g_string_append_c (blocks_stack, 'c');
+ }
} else if (strchr (p, '}')) {
- if (nest)
- nest--;
- intf[0] = '\0';
- continue;
+ if (blocks_stack->len > 0) {
+ if (blocks_stack->str[blocks_stack->len - 1] == 'b') {
+ g_string_truncate (blocks_stack, blocks_stack->len - 1);
+ nm_assert(blocks_skip > 0);
+ blocks_skip--;
+ intf[0] = '\0';
+ continue;
+ }
+ g_string_truncate (blocks_stack, blocks_stack->len - 1);
+ }
}
- if (nest && !intf[0])
+ if (blocks_skip > 0 && !intf[0])
continue;
if (intf[0] && !nm_streq (intf, interface))
diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c
index 8f45a36b28..a3320151b4 100644
--- a/src/dhcp/tests/test-dhcp-dhclient.c
+++ b/src/dhcp/tests/test-dhcp-dhclient.c
@@ -982,6 +982,11 @@ test_structured (void)
" request subnet-mask, broadcast-address, time-offset, routers,\n"
" domain-search, domain-name, domain-name-servers, host-name;\n"
" require subnet-mask, domain-name-servers;\n"
+ " if not option domain-name = \"example.org\" {\n"
+ " prepend domain-name-servers 127.0.0.1;\n"
+ " } else {\n"
+ " prepend domain-name-servers 127.0.0.2;\n"
+ " } \n"
" } \n"
"\n"
"pseudo \"secondary\" \"eth0\" { \n"
@@ -1008,7 +1013,13 @@ test_structured (void)
" interface \"eth0\";\n"
" fixed-address 192.0.2.2;\n"
" option subnet-mask 255.255.255.0;\n"
- " } \n";
+ " } \n"
+ "if not option domain-name = \"example.org\" {\n"
+ " prepend domain-name-servers 127.0.0.1;\n"
+ " if not option domain-name = \"useless.example.com\" {\n"
+ " prepend domain-name-servers 127.0.0.2;\n"
+ " }\n"
+ "}\n";
static const char *const expected = \
"# Created by NetworkManager\n"
@@ -1019,6 +1030,12 @@ test_structured (void)
"send dhcp-client-identifier \"sad-and-useless\";\n"
"send dhcp-lease-time 8086;\n"
"require subnet-mask;\n"
+ "if not option domain-name = \"example.org\" {\n"
+ "prepend domain-name-servers 127.0.0.1;\n"
+ "if not option domain-name = \"useless.example.com\" {\n"
+ "prepend domain-name-servers 127.0.0.2;\n"
+ "}\n"
+ "}\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"