Blame SOURCES/1000-dhclient-include-conditionals-rh1758550.patch

8e0e54
From 7a5509053a78bf92511626ca06fdb61c2977693f Mon Sep 17 00:00:00 2001
8e0e54
From: Beniamino Galvani <bgalvani@redhat.com>
8e0e54
Date: Sun, 6 Oct 2019 08:27:18 +0200
8e0e54
Subject: [PATCH] dhcp: include conditionals from existing dhclient
8e0e54
 configuration
8e0e54
8e0e54
Since commit 159ff23268b1 ('dhcp/dhclient-utils: skip over
8e0e54
dhclient.conf blocks') we skip blocks enclosed in lines containing '{'
8e0e54
and '}' because NM should ignore 'lease', 'alias' and other
8e0e54
declarations. However, conditional statements seem useful and should
8e0e54
not be skipped.
8e0e54
8e0e54
https://bugzilla.redhat.com/show_bug.cgi?id=1758550
8e0e54
(cherry picked from commit b58e4d311da630ea8d14f60ca3667710877e455d)
8e0e54
(cherry picked from commit 58ffded2d0a317c3a480821272b41780aff0e64e)
8e0e54
(cherry picked from commit 497101fd1e44128496d14a3b8b7496de7febe2f0)
8e0e54
---
8e0e54
 src/dhcp/nm-dhcp-dhclient-utils.c   | 43 +++++++++++++++++++++--------
8e0e54
 src/dhcp/tests/test-dhcp-dhclient.c | 19 ++++++++++++-
8e0e54
 2 files changed, 50 insertions(+), 12 deletions(-)
8e0e54
8e0e54
diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c
8e0e54
index 3338fbff2..01d0fc020 100644
8e0e54
--- a/src/dhcp/nm-dhcp-dhclient-utils.c
8e0e54
+++ b/src/dhcp/nm-dhcp-dhclient-utils.c
8e0e54
@@ -275,11 +275,13 @@ nm_dhcp_dhclient_create_config (const char *interface,
8e0e54
 	if (orig_contents) {
8e0e54
 		gs_free const char **lines = NULL;
8e0e54
 		gsize line_i;
8e0e54
-		int nest = 0;
8e0e54
+		nm_auto_free_gstring GString *blocks_stack = NULL;
8e0e54
+		guint blocks_skip = 0;
8e0e54
 		gboolean in_alsoreq = FALSE;
8e0e54
 		gboolean in_req = FALSE;
8e0e54
 		char intf[IFNAMSIZ];
8e0e54
 
8e0e54
+		blocks_stack = g_string_new (NULL);
8e0e54
 		g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);
8e0e54
 		intf[0] = '\0';
8e0e54
 
8e0e54
@@ -297,19 +299,38 @@ nm_dhcp_dhclient_create_config (const char *interface,
8e0e54
 			if (in_req) {
8e0e54
 				/* pass */
8e0e54
 			} else if (strchr (p, '{')) {
8e0e54
-				nest++;
8e0e54
-				if (   !intf[0]
8e0e54
-				    && NM_STR_HAS_PREFIX (p, "interface"))
8e0e54
-					if (read_interface (p, intf, sizeof (intf)))
8e0e54
-						continue;
8e0e54
+				if (   NM_STR_HAS_PREFIX (p, "lease")
8e0e54
+				    || NM_STR_HAS_PREFIX (p, "alias")
8e0e54
+				    || NM_STR_HAS_PREFIX (p, "interface")
8e0e54
+				    || NM_STR_HAS_PREFIX (p, "pseudo")) {
8e0e54
+					/* skip over these blocks, except 'interface' when it
8e0e54
+					 * matches the current interface */
8e0e54
+					blocks_skip++;
8e0e54
+					g_string_append_c (blocks_stack, 'b');
8e0e54
+					if (   !intf[0]
8e0e54
+					    && NM_STR_HAS_PREFIX (p, "interface")) {
8e0e54
+						if (read_interface (p, intf, sizeof (intf)))
8e0e54
+							continue;
8e0e54
+					}
8e0e54
+				} else {
8e0e54
+					/* allow other blocks (conditionals) */
8e0e54
+					if (!strchr (p, '}')) /* '} else {'  */
8e0e54
+						g_string_append_c (blocks_stack, 'c');
8e0e54
+				}
8e0e54
 			} else if (strchr (p, '}')) {
8e0e54
-				if (nest)
8e0e54
-					nest--;
8e0e54
-				intf[0] = '\0';
8e0e54
-				continue;
8e0e54
+				if (blocks_stack->len > 0) {
8e0e54
+					if (blocks_stack->str[blocks_stack->len - 1] == 'b') {
8e0e54
+						g_string_truncate (blocks_stack, blocks_stack->len - 1);
8e0e54
+						nm_assert(blocks_skip > 0);
8e0e54
+						blocks_skip--;
8e0e54
+						intf[0] = '\0';
8e0e54
+						continue;
8e0e54
+					}
8e0e54
+					g_string_truncate (blocks_stack, blocks_stack->len - 1);
8e0e54
+				}
8e0e54
 			}
8e0e54
 
8e0e54
-			if (nest && !intf[0])
8e0e54
+			if (blocks_skip > 0 && !intf[0])
8e0e54
 				continue;
8e0e54
 
8e0e54
 			if (intf[0] && !nm_streq (intf, interface))
8e0e54
diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c
8e0e54
index f6267cd28..90480955f 100644
8e0e54
--- a/src/dhcp/tests/test-dhcp-dhclient.c
8e0e54
+++ b/src/dhcp/tests/test-dhcp-dhclient.c
8e0e54
@@ -900,6 +900,11 @@ test_structured (void)
8e0e54
 		"    request subnet-mask, broadcast-address, time-offset, routers,\n"
8e0e54
 		"        domain-search, domain-name, domain-name-servers, host-name;\n"
8e0e54
 		"    require subnet-mask, domain-name-servers;\n"
8e0e54
+		"    if not option domain-name = \"example.org\" {\n"
8e0e54
+		"        prepend domain-name-servers 127.0.0.1;\n"
8e0e54
+		"    } else {\n"
8e0e54
+		"        prepend domain-name-servers 127.0.0.2;\n"
8e0e54
+		"    }  \n"
8e0e54
 		"    }  \n"
8e0e54
 		"\n"
8e0e54
 		"pseudo \"secondary\" \"eth0\"   {  \n"
8e0e54
@@ -926,7 +931,13 @@ test_structured (void)
8e0e54
 		"    interface \"eth0\";\n"
8e0e54
 		"    fixed-address 192.0.2.2;\n"
8e0e54
 		"    option subnet-mask 255.255.255.0;\n"
8e0e54
-		"  }  \n";
8e0e54
+		"  }  \n"
8e0e54
+		"if not option domain-name = \"example.org\" {\n"
8e0e54
+		"  prepend domain-name-servers 127.0.0.1;\n"
8e0e54
+		"  if not option domain-name = \"useless.example.com\" {\n"
8e0e54
+		"    prepend domain-name-servers 127.0.0.2;\n"
8e0e54
+		"  }\n"
8e0e54
+		"}\n";
8e0e54
 
8e0e54
 	static const char *const expected = \
8e0e54
 		"# Created by NetworkManager\n"
8e0e54
@@ -937,6 +948,12 @@ test_structured (void)
8e0e54
 		"send dhcp-client-identifier \"sad-and-useless\";\n"
8e0e54
 		"send dhcp-lease-time 8086;\n"
8e0e54
 		"require subnet-mask;\n"
8e0e54
+		"if not option domain-name = \"example.org\" {\n"
8e0e54
+		"prepend domain-name-servers 127.0.0.1;\n"
8e0e54
+		"if not option domain-name = \"useless.example.com\" {\n"
8e0e54
+		"prepend domain-name-servers 127.0.0.2;\n"
8e0e54
+		"}\n"
8e0e54
+		"}\n"
8e0e54
 		"\n"
8e0e54
 		"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
8e0e54
 		"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
8e0e54
-- 
8e0e54
2.21.0
8e0e54