diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-10-06 08:27:18 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2019-10-07 09:10:35 +0200 |
commit | 84525174554e3402639ff99bbf7fcdaeec5591a3 (patch) | |
tree | b06910d811b7e50fedd6d84bac329910c2a59931 | |
parent | c6d53c550094163af8b7f91540162507e84b5639 (diff) | |
download | NetworkManager-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.c | 43 | ||||
-rw-r--r-- | src/dhcp/tests/test-dhcp-dhclient.c | 19 |
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" |