diff --git a/.dhcp.metadata b/.dhcp.metadata
new file mode 100644
index 0000000..9b87ec1
--- /dev/null
+++ b/.dhcp.metadata
@@ -0,0 +1 @@
+e4338f80bd2118ba1578e4bd3c2c154ec9c12ce0 SOURCES/dhcp-4.4.2b1.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ff94719
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/dhcp-4.4.2b1.tar.gz
diff --git a/SOURCES/0001-change-bug-url.patch b/SOURCES/0001-change-bug-url.patch
new file mode 100644
index 0000000..b6afa57
--- /dev/null
+++ b/SOURCES/0001-change-bug-url.patch
@@ -0,0 +1,78 @@
+From 23dfbc560028bf7429196db1a3826f8b80c19d3e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:09:57 +0100
+Subject: [PATCH 01/26] change bug url
+Cc: pzhukov@redhat.com
+
+---
+ omapip/errwarn.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 42 insertions(+), 5 deletions(-)
+
+diff --git a/omapip/errwarn.c b/omapip/errwarn.c
+index e30f8a0..09a3004 100644
+--- a/omapip/errwarn.c
++++ b/omapip/errwarn.c
+@@ -48,6 +48,41 @@ void (*log_cleanup) (void);
+ static char mbuf [CVT_BUF_MAX + 1];
+ static char fbuf [CVT_BUF_MAX + 1];
+ 
++// get BUG_REPORT_URL from /etc/os-release
++char * bug_report_url(void) {
++    FILE * file = fopen("/etc/os-release", "r");
++    size_t len;
++    char * line = NULL;
++    char * url = NULL;
++    size_t url_len = 256;
++
++    url = (char *) malloc(url_len * sizeof(char));
++    strcpy(url, "https://bugzilla.redhat.com/");
++
++    if (!file)
++        return url;
++
++    while ((getline(&line, &len, file)) != -1) {
++        if (strstr(line, "BUG_REPORT_URL") != NULL) {
++            char * start = strchr(line, '=');
++            char * rquotes = strrchr(line, '"');
++
++            if (rquotes != NULL) {
++                *rquotes = '\0';
++                strncpy(url, start+2, url_len);
++            } else {
++                strncpy(url, start+1, url_len);
++            }
++            url[url_len-1] = '\0';
++            fclose(file);
++            return url;
++        }
++    }
++    fclose(file);
++    return url;
++}
++
++
+ /* Log an error message, then exit... */
+ 
+ void log_fatal (const char * fmt, ... )
+@@ -74,11 +109,13 @@ void log_fatal (const char * fmt, ... )
+   }
+ 
+   log_error ("%s", "");
+-  log_error ("If you think you have received this message due to a bug rather");
+-  log_error ("than a configuration issue please read the section on submitting");
+-  log_error ("bugs on either our web page at www.isc.org or in the README file");
+-  log_error ("before submitting a bug.  These pages explain the proper");
+-  log_error ("process and the information we find helpful for debugging.");
++  log_error ("This version of ISC DHCP is based on the release available");
++  log_error ("on ftp.isc.org. Features have been added and other changes");
++  log_error ("have been made to the base software release in order to make");
++  log_error ("it work better with this distribution.");
++  log_error ("%s", "");
++  log_error ("Please report issues with this software via: ");
++  log_error ("%s", bug_report_url());
+   log_error ("%s", "");
+   log_error ("exiting.");
+ 
+-- 
+2.14.5
+
diff --git a/SOURCES/0002-additional-dhclient-options.patch b/SOURCES/0002-additional-dhclient-options.patch
new file mode 100644
index 0000000..d700c00
--- /dev/null
+++ b/SOURCES/0002-additional-dhclient-options.patch
@@ -0,0 +1,468 @@
+From a26161b0fd45cdbeed3038ac63ff04e3b727248f Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:19:47 +0100
+Subject: [PATCH 02/26] additional dhclient options
+Cc: pzhukov@redhat.com
+
+---
+ client/clparse.c    |  10 +-
+ client/dhclient.8   |  27 ++++++
+ client/dhclient.c   | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ common/conflex.c    |   2 +
+ includes/dhcpd.h    |   3 +
+ includes/dhctoken.h |   1 +
+ 6 files changed, 308 insertions(+), 6 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index eaf48a8..7212e3a 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -189,6 +189,7 @@ isc_result_t read_client_conf ()
+ 	/* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
+ 	 */
+ 	top_level_config.requested_lease = 7200;
++	top_level_config.bootp_broadcast_always = 0;
+ 
+ 	group_allocate (&top_level_config.on_receipt, MDL);
+ 	if (!top_level_config.on_receipt)
+@@ -394,7 +395,8 @@ void read_client_leases ()
+ 	interface-declaration |
+ 	LEASE client-lease-statement |
+ 	ALIAS client-lease-statement |
+-	KEY key-definition */
++	KEY key-definition |
++	BOOTP_BROADCAST_ALWAYS */
+ 
+ void parse_client_statement (cfile, ip, config)
+ 	struct parse *cfile;
+@@ -817,6 +819,12 @@ void parse_client_statement (cfile, ip, config)
+ 		parse_lease_id_format(cfile);
+ 		break;
+ 
++	      case BOOTP_BROADCAST_ALWAYS:
++		token = next_token(&val, (unsigned*)0, cfile);
++		config -> bootp_broadcast_always = 1;
++		parse_semi (cfile);
++		return;
++
+ 
+ 	      default:
+ 		lose = 0;
+diff --git a/client/dhclient.8 b/client/dhclient.8
+index ebc750f..6d7fbdb 100644
+--- a/client/dhclient.8
++++ b/client/dhclient.8
+@@ -134,6 +134,33 @@ dhclient - Dynamic Host Configuration Protocol Client
+ .B -w
+ ]
+ [
++.B -B
++]
++[
++.B -C
++.I dhcp-client-identifier
++]
++[
++.B -H
++.I host-name
++]
++[
++.B -F
++.I fqdn.fqdn
++]
++[
++.B -V
++.I vendor-class-identifier
++]
++[
++.B --request-options
++.I request-option-list
++]
++[
++.B --timeout
++.I timeout
++]
++[
+ .B --dad-wait-time
+ .I seconds
+ ]
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 825ab00..26a333c 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -41,6 +41,12 @@
+ #include <sys/wait.h>
+ #include <limits.h>
+ 
++/*
++ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
++ * that when building ISC code.
++ */
++extern int asprintf(char **strp, const char *fmt, ...);
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+ 
+@@ -110,6 +116,10 @@ char *mockup_relay = NULL;
+ 
+ char *progname = NULL;
+ 
++int bootp_broadcast_always = 0;
++
++extern struct option *default_requested_options[];
++
+ void run_stateless(int exit_mode, u_int16_t port);
+ 
+ static isc_result_t write_duid(struct data_string *duid);
+@@ -183,8 +193,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
+ "                [-s server-addr] [-cf config-file]\n" \
+ "                [-df duid-file] [-lf lease-file]\n" \
+ "                [-pf pid-file] [--no-pid] [-e VAR=val]\n" \
+-"                [-sf script-file] [interface]*"
+-
++"                [-sf script-file] [interface]*\n" \
++"                [-C <dhcp-client-identifier>] [-B]\n" \
++"                [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" \
++"                [-V <vendor-class-identifier>]\n" \
++"                [--request-options <request option list>]"
++  
+ #define DHCLIENT_USAGEH "{--version|--help|-h}"
+ 
+ static void
+@@ -243,6 +257,16 @@ main(int argc, char **argv) {
+ #else
+ 	progname = argv[0];
+ #endif
++        char *dhcp_client_identifier_arg = NULL;
++        char *dhcp_host_name_arg = NULL;
++	char *dhcp_fqdn_arg = NULL;
++	char *dhcp_vendor_class_identifier_arg = NULL;
++	char *dhclient_request_options = NULL;
++
++	int timeout_arg = 0;
++	char *arg_conf = NULL;
++	int arg_conf_len = 0;
++
+ 	/* Initialize client globals. */
+ 	memset(&default_duid, 0, sizeof(default_duid));
+ 
+@@ -558,6 +582,89 @@ main(int argc, char **argv) {
+ 			std_dhcid = 1;
+ 		} else if (!strcmp(argv[i], "-v")) {
+ 			quiet = 0;
++		} else if (!strcmp(argv[i], "-C")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++				log_error("-C option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++				exit(1);
++			}
++
++			dhcp_client_identifier_arg = argv[i];
++		} else if (!strcmp(argv[i], "-B")) {
++			bootp_broadcast_always = 1;
++		} else if (!strcmp(argv[i], "-H")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++				log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++				exit(1);
++			}
++
++			if (dhcp_host_name_arg != NULL) {
++				log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
++				exit(1);
++			}
++
++			dhcp_host_name_arg = argv[i];
++		} else if (!strcmp(argv[i], "-F")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++				log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++				exit(1);
++			}
++
++			if (dhcp_fqdn_arg != NULL) {
++				log_error("Only one -F <fqdn> argument can be specified");
++				exit(1);
++			}
++
++			if (dhcp_host_name_arg != NULL) {
++				log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
++				exit(1);
++			}
++
++			dhcp_fqdn_arg = argv[i];
++		} else if (!strcmp(argv[i], "--timeout")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			if ((timeout_arg = atoi(argv[i])) <= 0) {
++				log_error("timeout option must be > 0 - bad value: %s",argv[i]);
++				exit(1);
++			}
++		} else if (!strcmp(argv[i], "-V")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++				log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++				exit(1);
++			}
++
++			dhcp_vendor_class_identifier_arg = argv[i];
++		} else if (!strcmp(argv[i], "--request-options")) {
++			if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++				usage(use_noarg, argv[i-1]);
++				exit(1);
++			}
++
++			dhclient_request_options = argv[i];
++
+ 		} else if (argv[i][0] == '-') {
+ 			usage("Unknown command: %s", argv[i]);
+ 		} else if (interfaces_requested < 0) {
+@@ -754,6 +861,156 @@ main(int argc, char **argv) {
+ 	/* Parse the dhclient.conf file. */
+ 	read_client_conf();
+ 
++	/* Parse any extra command line configuration arguments: */
++	if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
++		arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
++
++		if ((arg_conf == 0) || (arg_conf_len <= 0))
++			log_fatal("Unable to send -C option dhcp-client-identifier");
++	}
++
++	if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
++		if (arg_conf == 0) {
++			arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to send -H option host-name");
++		} else {
++			char *last_arg_conf = arg_conf;
++			arg_conf = NULL;
++			arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to send -H option host-name");
++
++			free(last_arg_conf);
++		}
++	}
++
++	if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
++		if (arg_conf == 0) {
++			arg_conf_len = asprintf(&arg_conf,  "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to send -F option fqdn.fqdn");
++		} else {
++			char *last_arg_conf = arg_conf;
++			arg_conf = NULL;
++			arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
++
++			if ((arg_conf == 0)  || (arg_conf_len <= 0))
++				log_fatal("Unable to send -F option fqdn.fqdn");
++
++			free(last_arg_conf);
++		}
++	}
++
++	if (timeout_arg) {
++		if (arg_conf == 0) {
++			arg_conf_len = asprintf(&arg_conf,  "timeout %d;", timeout_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to process --timeout timeout argument");
++		} else {
++			char *last_arg_conf = arg_conf;
++			arg_conf = NULL;
++			arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len == 0))
++				log_fatal("Unable to process --timeout timeout argument");
++
++			free(last_arg_conf);
++		}
++	}
++
++	if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
++		if (arg_conf == 0) {
++			arg_conf_len = asprintf(&arg_conf,  "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to send -V option vendor-class-identifier");
++		} else {
++			char *last_arg_conf = arg_conf;
++			arg_conf = NULL;
++			arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to send -V option vendor-class-identifier");
++
++			free(last_arg_conf);
++		}
++	}
++
++	if (dhclient_request_options != NULL) {
++		if (arg_conf == 0) {
++			arg_conf_len = asprintf(&arg_conf,  "request %s;", dhclient_request_options);
++
++			if ((arg_conf == 0) || (arg_conf_len <= 0))
++				log_fatal("Unable to parse --request-options <request options list> argument");
++		} else {
++			char *last_arg_conf = arg_conf;
++			arg_conf = NULL;
++			arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
++
++			if ((arg_conf == 0)  || (arg_conf_len <= 0))
++				log_fatal("Unable to parse --request-options <request options list> argument");
++
++			free(last_arg_conf);
++		}
++	}
++
++	if (arg_conf) {
++		if (arg_conf_len == 0)
++			if ((arg_conf_len = strlen(arg_conf)) == 0)
++				/* huh ? cannot happen ! */
++				log_fatal("Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
++
++		/* parse the extra dhclient.conf configuration arguments
++		 * into top level config: */
++		struct parse *cfile = (struct parse *)0;
++		const char *val = NULL;
++		int token;
++
++		status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
++
++		if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
++			log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
++		/* more detailed parse failures will be logged */
++
++		do {
++			token = peek_token(&val, (unsigned *)0, cfile);
++			if (token == END_OF_FILE)
++				break;
++
++			parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);
++		} while (1);
++
++		if (cfile -> warnings_occurred)
++			log_fatal("Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
++		end_parse(&cfile);
++
++		if (timeout_arg) {
++			/* we just set the toplevel timeout, but per-client
++			 * timeouts may still be at defaults.
++			 */
++			for (ip=interfaces; ip; ip = ip->next) {
++				if (ip->client->config->timeout == 60)
++					ip->client->config->timeout = timeout_arg;
++			}
++		}
++
++		if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
++			for (ip=interfaces; ip; ip = ip->next) {
++				if (ip->client->config->requested_options == default_requested_options)
++					ip->client->config->requested_options = top_level_config.requested_options;
++			}
++		}
++
++		free(arg_conf);
++		arg_conf = NULL;
++		arg_conf_len = 0;
++	}
++
+ 	/* Parse the lease database. */
+ 	read_client_leases();
+ 
+@@ -3226,7 +3483,8 @@ void make_discover (client, lease)
+ 	client -> packet.xid = random ();
+ 	client -> packet.secs = 0; /* filled in by send_discover. */
+ 
+-	if (can_receive_unicast_unconfigured (client -> interface))
++	if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))
++	    && can_receive_unicast_unconfigured(client->interface))
+ 		client -> packet.flags = 0;
+ 	else
+ 		client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -3311,7 +3569,9 @@ void make_request (client, lease)
+ 	} else {
+ 		memset (&client -> packet.ciaddr, 0,
+ 			sizeof client -> packet.ciaddr);
+-		if (can_receive_unicast_unconfigured (client -> interface))
++		if ((!(bootp_broadcast_always ||
++		    client ->config->bootp_broadcast_always)) &&
++		    can_receive_unicast_unconfigured (client -> interface))
+ 			client -> packet.flags = 0;
+ 		else
+ 			client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -3374,7 +3634,8 @@ void make_decline (client, lease)
+ 	client -> packet.hops = 0;
+ 	client -> packet.xid = client -> xid;
+ 	client -> packet.secs = 0; /* Filled in by send_request. */
+-	if (can_receive_unicast_unconfigured (client -> interface))
++	if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))
++	    && can_receive_unicast_unconfigured (client->interface))
+ 		client -> packet.flags = 0;
+ 	else
+ 		client -> packet.flags = htons (BOOTP_BROADCAST);
+diff --git a/common/conflex.c b/common/conflex.c
+index 045b655..71c0bf5 100644
+--- a/common/conflex.c
++++ b/common/conflex.c
+@@ -832,6 +832,8 @@ intern(char *atom, enum dhcp_token dfv) {
+ 		if (!strcasecmp(atom+1, "ig-endian")) {
+ 			return TOKEN_BIG_ENDIAN;
+ 		}
++		if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
++			return BOOTP_BROADCAST_ALWAYS;
+ 		break;
+ 	      case 'c':
+ 		if (!strcasecmp(atom + 1, "ase"))
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 5930e6a..018fa34 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -1269,6 +1269,9 @@ struct client_config {
+ 
+ 	int lease_id_format;		/* format for IDs in lease file,
+ 					   TOKEN_OCTAL or TOKEN_HEX */
++
++	int bootp_broadcast_always;	/* If nonzero, always set the BOOTP_BROADCAST
++					   flag in requests */
+ };
+ 
+ /* Per-interface state used in the dhcp client... */
+diff --git a/includes/dhctoken.h b/includes/dhctoken.h
+index 5920f4f..7e7215a 100644
+--- a/includes/dhctoken.h
++++ b/includes/dhctoken.h
+@@ -377,6 +377,7 @@ enum dhcp_token {
+ 	TOKEN_HEX = 677,
+ 	TOKEN_OCTAL = 678,
+ 	KEY_ALGORITHM = 679
++        BOOTP_BROADCAST_ALWAYS = 680
+ };
+ 
+ #define is_identifier(x)	((x) >= FIRST_TOKEN &&	\
+-- 
+2.14.5
+
diff --git a/SOURCES/0003-Handle-releasing-interfaces-requested-by-sbin-ifup.patch b/SOURCES/0003-Handle-releasing-interfaces-requested-by-sbin-ifup.patch
new file mode 100644
index 0000000..2953c0f
--- /dev/null
+++ b/SOURCES/0003-Handle-releasing-interfaces-requested-by-sbin-ifup.patch
@@ -0,0 +1,99 @@
+From af504e99abde04b881768d18eaa0054b36b16303 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:21:14 +0100
+Subject: [PATCH 03/26] Handle releasing interfaces requested by /sbin/ifup
+Cc: pzhukov@redhat.com
+
+---
+ client/dhclient.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 26a333c..2a2e9e6 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -787,9 +787,81 @@ main(int argc, char **argv) {
+ 				}
+ 			}
+ 			fclose(pidfd);
++		} else {
++			/* handle release for interfaces requested with Red Hat
++			 * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
++			 */
++
++			if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
++				path_dhclient_pid = "/var/run/dhclient.pid";
++
++			char *new_path_dhclient_pid;
++			struct interface_info *ip;
++			int pdp_len = strlen(path_dhclient_pid), pfx, dpfx;
++
++			/* find append point: beginning of any trailing '.pid'
++			 * or '-$IF.pid' */
++			for (pfx=pdp_len; (pfx >= 0) && (path_dhclient_pid[pfx] != '.') && (path_dhclient_pid[pfx] != '/'); pfx--);
++				if (pfx == -1)
++					pfx = pdp_len;
++
++			if (path_dhclient_pid[pfx] == '/')
++				pfx += 1;
++
++			for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
++				if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
++					pfx = dpfx;
++
++			for (ip = interfaces; ip; ip = ip->next) {
++				if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
++					int n_len = strlen(ip->name);
++
++					new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
++					strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
++					sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
++
++					if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
++						e = fscanf(pidfd, "%ld\n", &temp);
++						oldpid = (pid_t)temp;
++
++						if (e != 0 && e != EOF) {
++							if (oldpid) {
++								if (kill(oldpid, SIGTERM) == 0)
++									unlink(path_dhclient_pid);
++							}
++						}
++
++						fclose(pidfd);
++					}
++
++					free(new_path_dhclient_pid);
++				}
++			}
++		}
++	} else {
++		FILE *pidfp = NULL;
++		long temp = 0;
++		pid_t dhcpid = 0;
++		int dhc_running = 0;
++		char procfn[256] = "";
++
++		if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
++			if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
++				snprintf(procfn,256,"/proc/%u",dhcpid);
++				dhc_running = (access(procfn, F_OK) == 0);
++			}
++
++			fclose(pidfp);
++		}
++
++		if (dhc_running) {
++			log_fatal("dhclient(%u) is already running - exiting. ", dhcpid);
++			return(1);
+ 		}
+ 	}
+ 
++	write_client_pid_file();
++
+ 	if (!quiet) {
+ 		log_info("%s %s", message, PACKAGE_VERSION);
+ 		log_info(copyright);
+-- 
+2.14.5
+
diff --git a/SOURCES/0004-Support-unicast-BOOTP-for-IBM-pSeries-systems-and-ma.patch b/SOURCES/0004-Support-unicast-BOOTP-for-IBM-pSeries-systems-and-ma.patch
new file mode 100644
index 0000000..7f414a3
--- /dev/null
+++ b/SOURCES/0004-Support-unicast-BOOTP-for-IBM-pSeries-systems-and-ma.patch
@@ -0,0 +1,118 @@
+From 7e8cc8388ac31c5c2b1a423c6b2da0491b19f6f9 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:22:41 +0100
+Subject: [PATCH 04/26] Support unicast BOOTP for IBM pSeries systems (and
+ maybe others)
+Cc: pzhukov@redhat.com
+
+---
+ server/bootp.c | 12 +++++++++++-
+ server/dhcp.c  | 33 ++++++++++++++++++++++++++-------
+ 2 files changed, 37 insertions(+), 8 deletions(-)
+
+diff --git a/server/bootp.c b/server/bootp.c
+index 26a7607..2212f31 100644
+--- a/server/bootp.c
++++ b/server/bootp.c
+@@ -52,6 +52,7 @@ void bootp (packet)
+ 	char msgbuf [1024];
+ 	int ignorep;
+ 	int peer_has_leases = 0;
++	int norelay = 0;
+ 
+ 	if (packet -> raw -> op != BOOTREQUEST)
+ 		return;
+@@ -67,7 +68,7 @@ void bootp (packet)
+ 		 ? inet_ntoa (packet -> raw -> giaddr)
+ 		 : packet -> interface -> name);
+ 
+-	if (!locate_network (packet)) {
++	if ((norelay = locate_network (packet)) == 0) {
+ 		log_info ("%s: network unknown", msgbuf);
+ 		return;
+ 	}
+@@ -428,6 +429,15 @@ void bootp (packet)
+ 
+ 			goto out;
+ 		}
++	} else if (norelay == 2) {
++		to.sin_addr = raw.ciaddr;
++		to.sin_port = remote_port;
++		if (fallback_interface) {
++			result = send_packet (fallback_interface, NULL, &raw,
++					      outgoing.packet_length, from,
++					      &to, &hto);
++			goto out;
++		}
+ 
+ 	/* If it comes from a client that already knows its address
+ 	   and is not requesting a broadcast response, and we can
+diff --git a/server/dhcp.c b/server/dhcp.c
+index 6f3a91f..20f2a62 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -5224,6 +5224,7 @@ int locate_network (packet)
+ 	struct data_string data;
+ 	struct subnet *subnet = (struct subnet *)0;
+ 	struct option_cache *oc;
++	int norelay = 0;
+ 
+ #if defined(DHCPv6) && defined(DHCP4o6)
+ 	if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
+@@ -5245,12 +5246,24 @@ int locate_network (packet)
+ 	   from the interface, if there is one.   If not, fail. */
+ 	if (!oc && !packet -> raw -> giaddr.s_addr) {
+ 		if (packet -> interface -> shared_network) {
+-			shared_network_reference
+-				(&packet -> shared_network,
+-				 packet -> interface -> shared_network, MDL);
+-			return 1;
++			struct in_addr any_addr;
++			any_addr.s_addr = INADDR_ANY;
++
++			if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
++				struct iaddr cip;
++				memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
++				cip.len = 4;
++				if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
++					norelay = 2;
++			}
++
++			if (!norelay) {
++				shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
++				return 1;
++			}
++		} else {
++			return 0;
+ 		}
+-		return 0;
+ 	}
+ 
+ 	/* If there's an option indicating link connection, and it's valid,
+@@ -5277,7 +5290,10 @@ int locate_network (packet)
+ 		data_string_forget (&data, MDL);
+ 	} else {
+ 		ia.len = 4;
+-		memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
++		if (norelay)
++			memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
++		else
++			memcpy (ia.iabuf, &packet->raw->giaddr, 4);
+ 	}
+ 
+ 	/* If we know the subnet on which the IP address lives, use it. */
+@@ -5285,7 +5301,10 @@ int locate_network (packet)
+ 		shared_network_reference (&packet -> shared_network,
+ 					  subnet -> shared_network, MDL);
+ 		subnet_dereference (&subnet, MDL);
+-		return 1;
++		if (norelay)
++			return norelay;
++		else
++			return 1;
+ 	}
+ 
+ 	/* Otherwise, fail. */
+-- 
+2.14.5
+
diff --git a/SOURCES/0005-Change-default-requested-options.patch b/SOURCES/0005-Change-default-requested-options.patch
new file mode 100644
index 0000000..34ff7b5
--- /dev/null
+++ b/SOURCES/0005-Change-default-requested-options.patch
@@ -0,0 +1,60 @@
+From a2a3554ff9e05d1a8e2c8aa843f1b6a33fce87e3 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:24:24 +0100
+Subject: [PATCH 05/26] Change default requested options
+Cc: pzhukov@redhat.com
+
+Add NIS domain, NIS servers, NTP servers, interface-mtu and domain-search
+to the list of default requested DHCP options
+---
+ client/clparse.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index 7212e3a..39b95a0 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -31,7 +31,7 @@
+ 
+ struct client_config top_level_config;
+ 
+-#define NUM_DEFAULT_REQUESTED_OPTS	9
++#define NUM_DEFAULT_REQUESTED_OPTS	14
+ /* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
+ struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
+ 
+@@ -116,6 +116,31 @@ isc_result_t read_client_conf ()
+ 	option_code_hash_lookup(&default_requested_options[8],
+ 				dhcpv6_universe.code_hash, &code, 0, MDL);
+ 
++	/* 10 */
++	code = DHO_NIS_DOMAIN;
++	option_code_hash_lookup(&default_requested_options[9],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
++	/* 11 */
++	code = DHO_NIS_SERVERS;
++	option_code_hash_lookup(&default_requested_options[10],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
++	/* 12 */
++	code = DHO_NTP_SERVERS;
++	option_code_hash_lookup(&default_requested_options[11],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
++	/* 13 */
++	code = DHO_INTERFACE_MTU;
++	option_code_hash_lookup(&default_requested_options[12],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
++	/* 14 */
++	code = DHO_DOMAIN_SEARCH;
++	option_code_hash_lookup(&default_requested_options[13],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
+ 	for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
+ 		if (default_requested_options[code] == NULL)
+ 			log_fatal("Unable to find option definition for "
+-- 
+2.14.5
+
diff --git a/SOURCES/0006-Various-man-page-only-fixes.patch b/SOURCES/0006-Various-man-page-only-fixes.patch
new file mode 100644
index 0000000..a98783c
--- /dev/null
+++ b/SOURCES/0006-Various-man-page-only-fixes.patch
@@ -0,0 +1,168 @@
+From 846779467f7393b19e8d206405116e1e26e16efc Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:25:53 +0100
+Subject: [PATCH 06/26] Various man-page-only fixes
+Cc: pzhukov@redhat.com
+
+---
+ client/dhclient-script.8 | 22 +++++++++++++++++++++-
+ client/dhclient.conf.5   | 14 +++++++++++++-
+ common/dhcp-options.5    | 15 +++++++++++++++
+ server/dhcpd.conf.5      | 14 +++++++++-----
+ 4 files changed, 58 insertions(+), 7 deletions(-)
+
+diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
+index 3553afd..0db5516 100644
+--- a/client/dhclient-script.8
++++ b/client/dhclient-script.8
+@@ -43,7 +43,7 @@ customizations are needed, they should be possible using the enter and
+ exit hooks provided (see HOOKS for details).   These hooks will allow the
+ user to override the default behaviour of the client in creating a
+ .B /etc/resolv.conf
+-file.
++file, and to handle DHCP options not handled by default.
+ .PP
+ No standard client script exists for some operating systems, even though
+ the actual client may work, so a pioneering user may well need to create
+@@ -87,6 +87,26 @@ present.   The
+ .B ETCDIR/dhclient-exit-hooks
+ script can modify the valid of exit_status to change the exit status
+ of dhclient-script.
++.PP
++Immediately after dhclient brings an interface UP with a new IP address,
++subnet mask, and routes, in the REBOOT/BOUND states, it will check for the
++existence of an executable
++.B ETCDIR/dhclient-up-hooks
++script, and source it if found. This script can handle DHCP options in
++the environment that are not handled by default. A per-interface.
++.B ETCDIR/dhclient-${IF}-up-hooks
++script will override the generic script and be sourced when interface
++$IF has been brought up.
++.PP
++Immediately before dhclient brings an interface DOWN, removing its IP
++address, subnet mask, and routes, in the STOP/RELEASE  states, it will
++check for the existence of an executable
++.B ETCDIR/dhclient-down-hooks
++script, and source it if found. This script can handle DHCP options in
++the environment that are not handled by default. A per-interface
++.B ETCDIR/dhclient-${IF}-down-hooks
++script will override the generic script and be sourced when interface
++$IF is about to be brought down.
+ .SH OPERATION
+ When dhclient needs to invoke the client configuration script, it
+ defines a set of variables in the environment, and then invokes
+diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5
+index fa3b908..566a881 100644
+--- a/client/dhclient.conf.5
++++ b/client/dhclient.conf.5
+@@ -228,7 +228,8 @@ responding to the client send the client its values for the specified
+ options.  Only the option names should be specified in the request
+ statement - not option parameters.  By default, the DHCPv4 client
+ requests the subnet-mask, broadcast-address, time-offset, routers,
+-domain-name, domain-name-servers and host-name options while the DHCPv6
++domain-search, domain-name, domain-name-servers, host-name, nis-domain,
++nis-servers, ntp-servers and interface-mtu options while the DHCPv6
+ client requests the dhcp6 name-servers and domain-search options.  Note
+ that if you enter a \'request\' statement, you over-ride these defaults
+ and these options will not be requested.
+@@ -735,6 +736,17 @@ broadcast packets transmitted by DHCP clients, but is only useful if you
+ know the DHCP service(s) anycast MAC address prior to configuring your
+ client.  The \fIlink-type\fR and \fImac-address\fR parameters are configured
+ in a similar manner to the \fBhardware\fR statement.
++.PP
++ \fBbootp-broadcast-always;\fR
++.PP
++The
++.B bootp-broadcast-always
++statement instructs dhclient to always set the bootp broadcast flag in
++request packets, so that servers will always broadcast replies.
++This is equivalent to supplying the dhclient -B argument, and has
++the same effect as specifying 'always-broadcast' in the server's dhcpd.conf.
++This option is provided as an extension to enable dhclient to work
++on IBM s390 Linux guests.
+ .PP
+ .SH SAMPLE
+ The following configuration file was used on a laptop running NetBSD
+diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
+index 33d4804..d9e1197 100644
+--- a/common/dhcp-options.5
++++ b/common/dhcp-options.5
+@@ -1068,6 +1068,21 @@ classless IP routing - it does not include a subnet mask.  Since
+ classless IP routing is now the most widely deployed routing standard,
+ this option is virtually useless, and is not implemented by any of the
+ popular DHCP clients, for example the Microsoft DHCP client.
++.PP
++NOTE to Fedora dhclient users:
++.br
++dhclient-script interprets trailing 0 octets of the target as indicating
++the subnet class of the route, so for the following static-routes value:
++.br
++        option static-routes 172.0.0.0 172.16.2.254,
++.br
++                             192.168.0.0 192.168.2.254;
++.br
++dhclient-script will create routes:
++.br
++        172/8 via 172.16.2.254 dev $interface
++.br
++        192.168/16 via 192.168.2.254 dev $interface
+ .RE
+ .PP
+ .nf
+diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
+index 17330d4..89b5540 100644
+--- a/server/dhcpd.conf.5
++++ b/server/dhcpd.conf.5
+@@ -527,6 +527,9 @@ pool {
+ };
+ .fi
+ .PP
++Dynamic BOOTP leases are not compatible with failover, and, as such,
++you need to disallow BOOTP in pools that you are using failover for.
++.PP
+ The  server currently  does very  little  sanity checking,  so if  you
+ configure it wrong, it will just  fail in odd ways.  I would recommend
+ therefore that you either do  failover or don't do failover, but don't
+@@ -541,9 +544,9 @@ primary server might look like this:
+ failover peer "foo" {
+   primary;
+   address anthrax.rc.example.com;
+-  port 519;
++  port 647;
+   peer address trantor.rc.example.com;
+-  peer port 520;
++  peer port 847;
+   max-response-delay 60;
+   max-unacked-updates 10;
+   mclt 3600;
+@@ -1323,7 +1326,7 @@ the zone containing PTR records - for ISC BIND, something like this:
+ .PP
+ .nf
+ key DHCP_UPDATER {
+-  algorithm HMAC-MD5.SIG-ALG.REG.INT;
++  algorithm hmac-md5;
+   secret pRP5FapFoJ95JEL06sv4PQ==;
+ };
+ 
+@@ -1346,7 +1349,7 @@ dhcpd.conf file:
+ .PP
+ .nf
+ key DHCP_UPDATER {
+-  algorithm HMAC-MD5.SIG-ALG.REG.INT;
++  algorithm hmac-md5;
+   secret pRP5FapFoJ95JEL06sv4PQ==;
+ };
+ 
+@@ -2912,7 +2915,8 @@ statement
+ The \fInext-server\fR statement is used to specify the host address of
+ the server from which the initial boot file (specified in the
+ \fIfilename\fR statement) is to be loaded.  \fIServer-name\fR should
+-be a numeric IP address or a domain name.
++be a numeric IP address or a domain name.  If no \fInext-server\fR statement
++applies to a given client, the address 0.0.0.0 is used.
+ .RE
+ .PP
+ The
+-- 
+2.14.5
+
diff --git a/SOURCES/0007-Change-paths-to-conform-to-our-standards.patch b/SOURCES/0007-Change-paths-to-conform-to-our-standards.patch
new file mode 100644
index 0000000..87c4f8c
--- /dev/null
+++ b/SOURCES/0007-Change-paths-to-conform-to-our-standards.patch
@@ -0,0 +1,54 @@
+From ac65289663532db0bc1de449ca2a0eb4c8c2ca6f Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:26:34 +0100
+Subject: [PATCH 07/26] Change paths to conform to our standards
+Cc: pzhukov@redhat.com
+
+---
+ doc/examples/dhcpd-dhcpv6.conf | 2 +-
+ includes/dhcpd.h               | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/doc/examples/dhcpd-dhcpv6.conf b/doc/examples/dhcpd-dhcpv6.conf
+index 448a6a6..2357824 100644
+--- a/doc/examples/dhcpd-dhcpv6.conf
++++ b/doc/examples/dhcpd-dhcpv6.conf
+@@ -43,7 +43,7 @@ option dhcp6.domain-search "test.example.com","example.com";
+ option dhcp6.info-refresh-time 21600;
+ 
+ # The path of the lease file
+-dhcpv6-lease-file-name "/usr/local/var/db/dhcpd6.leases";
++dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases";
+ 
+ # Static definition (must be global)
+ host myclient {
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 018fa34..3632a6b 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -1545,7 +1545,7 @@ typedef unsigned char option_mask [16];
+ #else /* !DEBUG */
+ 
+ #ifndef _PATH_DHCPD_CONF
+-#define _PATH_DHCPD_CONF	"/etc/dhcpd.conf"
++#define _PATH_DHCPD_CONF	"/etc/dhcp/dhcpd.conf"
+ #endif /* DEBUG */
+ 
+ #ifndef _PATH_DHCPD_DB
+@@ -1567,11 +1567,11 @@ typedef unsigned char option_mask [16];
+ #endif /* DEBUG */
+ 
+ #ifndef _PATH_DHCLIENT_CONF
+-#define _PATH_DHCLIENT_CONF	"/etc/dhclient.conf"
++#define _PATH_DHCLIENT_CONF	"/etc/dhcp/dhclient.conf"
+ #endif
+ 
+ #ifndef _PATH_DHCLIENT_SCRIPT
+-#define _PATH_DHCLIENT_SCRIPT	"/sbin/dhclient-script"
++#define _PATH_DHCLIENT_SCRIPT	"/usr/sbin/dhclient-script"
+ #endif
+ 
+ #ifndef _PATH_DHCLIENT_PID
+-- 
+2.14.5
+
diff --git a/SOURCES/0008-Make-sure-all-open-file-descriptors-are-closed-on-ex.patch b/SOURCES/0008-Make-sure-all-open-file-descriptors-are-closed-on-ex.patch
new file mode 100644
index 0000000..8294563
--- /dev/null
+++ b/SOURCES/0008-Make-sure-all-open-file-descriptors-are-closed-on-ex.patch
@@ -0,0 +1,367 @@
+From d2da34706f140101c34f6a9806c258411806a939 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:27:18 +0100
+Subject: [PATCH 08/26] Make sure all open file descriptors are closed-on-exec
+ for SELinux
+Cc: pzhukov@redhat.com
+
+ISC-bug: #19148
+---
+ client/clparse.c  |  4 ++--
+ client/dhclient.c | 28 ++++++++++++++--------------
+ common/bpf.c      |  2 +-
+ common/dlpi.c     |  2 +-
+ common/nit.c      |  2 +-
+ common/resolv.c   |  2 +-
+ common/upf.c      |  2 +-
+ omapip/trace.c    |  6 +++---
+ relay/dhcrelay.c  | 10 +++++-----
+ server/confpars.c |  2 +-
+ server/db.c       |  4 ++--
+ server/dhcpd.c    | 14 +++++++-------
+ server/ldap.c     |  2 +-
+ 13 files changed, 40 insertions(+), 40 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index 39b95a0..44387ed 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -288,7 +288,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
+ 	int token;
+ 	isc_result_t status;
+ 
+-	if ((file = open (name, O_RDONLY)) < 0)
++	if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
+ 		return uerr2isc (errno);
+ 
+ 	cfile = NULL;
+@@ -364,7 +364,7 @@ void read_client_leases ()
+ 
+ 	/* Open the lease file.   If we can't open it, just return -
+ 	   we can safely trust the server to remember our state. */
+-	if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
++	if ((file = open (path_dhclient_db, O_RDONLY | O_CLOEXEC)) < 0)
+ 		return;
+ 
+ 	cfile = NULL;
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 2a2e9e6..a86ab9e 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -273,11 +273,11 @@ main(int argc, char **argv) {
+ 	/* Make sure that file descriptors 0 (stdin), 1, (stdout), and
+ 	   2 (stderr) are open. To do this, we assume that when we
+ 	   open a file the lowest available file descriptor is used. */
+-	fd = open("/dev/null", O_RDWR);
++	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 0)
+-		fd = open("/dev/null", O_RDWR);
++		fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 1)
+-		fd = open("/dev/null", O_RDWR);
++		fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 2)
+ 		log_perror = 0; /* No sense logging to /dev/null. */
+ 	else if (fd != -1)
+@@ -765,7 +765,7 @@ main(int argc, char **argv) {
+ 		long temp;
+ 		int e;
+ 
+-		if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
++		if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
+ 			e = fscanf(pidfd, "%ld\n", &temp);
+ 			oldpid = (pid_t)temp;
+ 
+@@ -820,7 +820,7 @@ main(int argc, char **argv) {
+ 					strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
+ 					sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
+ 
+-					if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
++					if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
+ 						e = fscanf(pidfd, "%ld\n", &temp);
+ 						oldpid = (pid_t)temp;
+ 
+@@ -845,7 +845,7 @@ main(int argc, char **argv) {
+ 		int dhc_running = 0;
+ 		char procfn[256] = "";
+ 
+-		if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
++		if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
+ 			if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
+ 				snprintf(procfn,256,"/proc/%u",dhcpid);
+ 				dhc_running = (access(procfn, F_OK) == 0);
+@@ -3808,7 +3808,7 @@ void rewrite_client_leases ()
+ 
+ 	if (leaseFile != NULL)
+ 		fclose (leaseFile);
+-	leaseFile = fopen (path_dhclient_db, "w");
++	leaseFile = fopen (path_dhclient_db, "we");
+ 	if (leaseFile == NULL) {
+ 		log_error ("can't create %s: %m", path_dhclient_db);
+ 		return;
+@@ -4003,7 +4003,7 @@ write_duid(struct data_string *duid)
+ 		return DHCP_R_INVALIDARG;
+ 
+ 	if (leaseFile == NULL) {	/* XXX? */
+-		leaseFile = fopen(path_dhclient_db, "w");
++		leaseFile = fopen(path_dhclient_db, "we");
+ 		if (leaseFile == NULL) {
+ 			log_error("can't create %s: %m", path_dhclient_db);
+ 			return ISC_R_IOERROR;
+@@ -4207,7 +4207,7 @@ int write_client_lease (client, lease, rewrite, makesure)
+ 		return 1;
+ 
+ 	if (leaseFile == NULL) {	/* XXX */
+-		leaseFile = fopen (path_dhclient_db, "w");
++		leaseFile = fopen (path_dhclient_db, "we");
+ 		if (leaseFile == NULL) {
+ 			log_error ("can't create %s: %m", path_dhclient_db);
+ 			return 0;
+@@ -4786,9 +4786,9 @@ void detach ()
+ 	(void) close(2);
+ 
+ 	/* Reopen them on /dev/null. */
+-	(void) open("/dev/null", O_RDWR);
+-	(void) open("/dev/null", O_RDWR);
+-	(void) open("/dev/null", O_RDWR);
++	(void) open("/dev/null", O_RDWR | O_CLOEXEC);
++	(void) open("/dev/null", O_RDWR | O_CLOEXEC);
++	(void) open("/dev/null", O_RDWR | O_CLOEXEC);
+ 
+ 	write_client_pid_file ();
+ 
+@@ -4806,14 +4806,14 @@ void write_client_pid_file ()
+ 		return;
+ 	}
+ 
+-	pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
++	pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
+ 
+ 	if (pfdesc < 0) {
+ 		log_error ("Can't create %s: %m", path_dhclient_pid);
+ 		return;
+ 	}
+ 
+-	pf = fdopen (pfdesc, "w");
++	pf = fdopen (pfdesc, "we");
+ 	if (!pf) {
+ 		close(pfdesc);
+ 		log_error ("Can't fdopen %s: %m", path_dhclient_pid);
+diff --git a/common/bpf.c b/common/bpf.c
+index 16076fe..67b6d64 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -94,7 +94,7 @@ int if_register_bpf (info)
+ 	for (b = 0; 1; b++) {
+ 		/* %Audit% 31 bytes max. %2004.06.17,Safe% */
+ 		sprintf(filename, BPF_FORMAT, b);
+-		sock = open (filename, O_RDWR, 0);
++		sock = open (filename, O_RDWR | O_CLOEXEC, 0);
+ 		if (sock < 0) {
+ 			if (errno == EBUSY) {
+ 				continue;
+diff --git a/common/dlpi.c b/common/dlpi.c
+index 3990bf1..a941258 100644
+--- a/common/dlpi.c
++++ b/common/dlpi.c
+@@ -817,7 +817,7 @@ dlpiopen(const char *ifname) {
+ 	}
+ 	*dp = '\0';
+ 	
+-	return open (devname, O_RDWR, 0);
++	return open (devname, O_RDWR | O_CLOEXEC, 0);
+ }
+ 
+ /*
+diff --git a/common/nit.c b/common/nit.c
+index d822c15..a9132bc 100644
+--- a/common/nit.c
++++ b/common/nit.c
+@@ -75,7 +75,7 @@ int if_register_nit (info)
+ 	struct strioctl sio;
+ 
+ 	/* Open a NIT device */
+-	sock = open ("/dev/nit", O_RDWR);
++	sock = open ("/dev/nit", O_RDWR | O_CLOEXEC);
+ 	if (sock < 0)
+ 		log_fatal ("Can't open NIT device for %s: %m", info -> name);
+ 
+diff --git a/common/resolv.c b/common/resolv.c
+index a01f520..b209e3f 100644
+--- a/common/resolv.c
++++ b/common/resolv.c
+@@ -43,7 +43,7 @@ void read_resolv_conf (parse_time)
+ 	struct domain_search_list *dp, *dl, *nd;
+ 	isc_result_t status;
+ 
+-	if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
++	if ((file = open (path_resolv_conf, O_RDONLY | O_CLOEXEC)) < 0) {
+ 		log_error ("Can't open %s: %m", path_resolv_conf);
+ 		return;
+ 	}
+diff --git a/common/upf.c b/common/upf.c
+index 9785879..e0a524f 100644
+--- a/common/upf.c
++++ b/common/upf.c
+@@ -71,7 +71,7 @@ int if_register_upf (info)
+ 		/* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
+ 		sprintf(filename, "/dev/pf/pfilt%d", b);
+ 
+-		sock = open (filename, O_RDWR, 0);
++		sock = open (filename, O_RDWR | O_CLOEXEC, 0);
+ 		if (sock < 0) {
+ 			if (errno == EBUSY) {
+ 				continue;
+diff --git a/omapip/trace.c b/omapip/trace.c
+index 45bd508..5ea7486 100644
+--- a/omapip/trace.c
++++ b/omapip/trace.c
+@@ -136,10 +136,10 @@ isc_result_t trace_begin (const char *filename,
+ 		return DHCP_R_INVALIDARG;
+ 	}
+ 
+-	traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
++	traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL | O_CLOEXEC, 0600);
+ 	if (traceoutfile < 0 && errno == EEXIST) {
+ 		log_error ("WARNING: Overwriting trace file \"%s\"", filename);
+-		traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC,
++		traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC | O_CLOEXEC,
+ 				     0600);
+ 	}
+ 
+@@ -427,7 +427,7 @@ void trace_file_replay (const char *filename)
+ 	isc_result_t result;
+ 	int len;
+ 
+-	traceinfile = fopen (filename, "r");
++	traceinfile = fopen (filename, "re");
+ 	if (!traceinfile) {
+ 		log_error("Can't open tracefile %s: %m", filename);
+ 		return;
+diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
+index d8caaaf..ea1be18 100644
+--- a/relay/dhcrelay.c
++++ b/relay/dhcrelay.c
+@@ -296,11 +296,11 @@ main(int argc, char **argv) {
+ 	/* Make sure that file descriptors 0(stdin), 1,(stdout), and
+ 	   2(stderr) are open. To do this, we assume that when we
+ 	   open a file the lowest available file descriptor is used. */
+-	fd = open("/dev/null", O_RDWR);
++	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 0)
+-		fd = open("/dev/null", O_RDWR);
++		fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 1)
+-		fd = open("/dev/null", O_RDWR);
++		fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+ 	if (fd == 2)
+ 		log_perror = 0; /* No sense logging to /dev/null. */
+ 	else if (fd != -1)
+@@ -776,13 +776,13 @@ main(int argc, char **argv) {
+ 		/* Create the pid file. */
+ 		if (no_pid_file == ISC_FALSE) {
+ 			pfdesc = open(path_dhcrelay_pid,
+-				      O_CREAT | O_TRUNC | O_WRONLY, 0644);
++				      O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
+ 
+ 			if (pfdesc < 0) {
+ 				log_error("Can't create %s: %m",
+ 					  path_dhcrelay_pid);
+ 			} else {
+-				pf = fdopen(pfdesc, "w");
++				pf = fdopen(pfdesc, "we");
+ 				if (!pf)
+ 					log_error("Can't fdopen %s: %m",
+ 						  path_dhcrelay_pid);
+diff --git a/server/confpars.c b/server/confpars.c
+index d2cedfe..2743979 100644
+--- a/server/confpars.c
++++ b/server/confpars.c
+@@ -118,7 +118,7 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ 	}
+ #endif
+ 
+-	if ((file = open (filename, O_RDONLY)) < 0) {
++	if ((file = open (filename, O_RDONLY | O_CLOEXEC)) < 0) {
+ 		if (leasep) {
+ 			log_error ("Can't open lease database %s: %m --",
+ 				   path_dhcpd_db);
+diff --git a/server/db.c b/server/db.c
+index 67e6cc1..6181528 100644
+--- a/server/db.c
++++ b/server/db.c
+@@ -1154,7 +1154,7 @@ int new_lease_file (int test_mode)
+ 		     path_dhcpd_db, (int)t) >= sizeof newfname)
+ 		log_fatal("new_lease_file: lease file path too long");
+ 
+-	db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
++	db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
+ 	if (db_fd < 0) {
+ 		log_error ("Can't create new lease file: %m");
+ 		return 0;
+@@ -1175,7 +1175,7 @@ int new_lease_file (int test_mode)
+ 	}
+ #endif /* PARANOIA */
+ 
+-	if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
++	if ((new_db_file = fdopen(db_fd, "we")) == NULL) {
+ 		log_error("Can't fdopen new lease file: %m");
+ 		close(db_fd);
+ 		goto fdfail;
+diff --git a/server/dhcpd.c b/server/dhcpd.c
+index 55ffae7..530a923 100644
+--- a/server/dhcpd.c
++++ b/server/dhcpd.c
+@@ -300,11 +300,11 @@ main(int argc, char **argv) {
+         /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
+            2 (stderr) are open. To do this, we assume that when we
+            open a file the lowest available file descriptor is used. */
+-        fd = open("/dev/null", O_RDWR);
++        fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 0)
+-                fd = open("/dev/null", O_RDWR);
++                fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 1)
+-                fd = open("/dev/null", O_RDWR);
++                fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 2)
+                 log_perror = 0; /* No sense logging to /dev/null. */
+         else if (fd != -1)
+@@ -975,7 +975,7 @@ main(int argc, char **argv) {
+ 	 * appropriate.
+ 	 */
+ 	if (no_pid_file == ISC_FALSE) {
+-		i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644);
++		i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
+ 		if (i >= 0) {
+ 			sprintf(pbuf, "%d\n", (int) getpid());
+ 			IGNORE_RET(write(i, pbuf, strlen(pbuf)));
+@@ -1028,9 +1028,9 @@ main(int argc, char **argv) {
+                 (void) close(2);
+ 
+                 /* Reopen them on /dev/null. */
+-                (void) open("/dev/null", O_RDWR);
+-                (void) open("/dev/null", O_RDWR);
+-                (void) open("/dev/null", O_RDWR);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
+                 log_perror = 0; /* No sense logging to /dev/null. */
+ 
+        		IGNORE_RET (chdir("/"));
+diff --git a/server/ldap.c b/server/ldap.c
+index 5126d24..555545c 100644
+--- a/server/ldap.c
++++ b/server/ldap.c
+@@ -1446,7 +1446,7 @@ ldap_start (void)
+ 
+   if (ldap_debug_file != NULL && ldap_debug_fd == -1)
+     {
+-      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
++      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
+                                  S_IRUSR | S_IWUSR)) < 0)
+         log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
+                    strerror (errno));
+-- 
+2.14.5
+
diff --git a/SOURCES/0009-Fix-garbage-in-format-string-error.patch b/SOURCES/0009-Fix-garbage-in-format-string-error.patch
new file mode 100644
index 0000000..f9d81ab
--- /dev/null
+++ b/SOURCES/0009-Fix-garbage-in-format-string-error.patch
@@ -0,0 +1,27 @@
+From a0a2186ce52a31357d4eb3c32d7d6887e4603814 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:28:13 +0100
+Subject: [PATCH 09/26] Fix 'garbage in format string' error
+Cc: pzhukov@redhat.com
+
+RHBZ: 450042
+---
+ common/tables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/common/tables.c b/common/tables.c
+index c1aa214..d2294c0 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -215,7 +215,7 @@ static struct option dhcp_options[] = {
+ 	{ "name-service-search", "Sa",		&dhcp_universe, 117, 1 },
+ #endif
+ 	{ "subnet-selection", "I",		&dhcp_universe, 118, 1 },
+-	{ "domain-search", "Dc",		&dhcp_universe, 119, 1 },
++	{ "domain-search", "D",			&dhcp_universe, 119, 1 },
+ 	{ "vivco", "Evendor-class.",		&dhcp_universe, 124, 1 },
+ 	{ "vivso", "Evendor.",			&dhcp_universe, 125, 1 },
+ #if 0
+-- 
+2.14.5
+
diff --git a/SOURCES/0010-Handle-null-timeout.patch b/SOURCES/0010-Handle-null-timeout.patch
new file mode 100644
index 0000000..2b6e49b
--- /dev/null
+++ b/SOURCES/0010-Handle-null-timeout.patch
@@ -0,0 +1,32 @@
+From ed7610cdb2e8ebdbaee618e477879e7e008d4f29 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:29:08 +0100
+Subject: [PATCH 10/26] Handle null timeout
+Cc: pzhukov@redhat.com
+
+Handle cases in add_timeout() where the function is called with a NULL
+value for the 'when' parameter
+
+ISC-Bugs: #19867 (rejected)
+---
+ common/dispatch.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/common/dispatch.c b/common/dispatch.c
+index 0207ad3..d7fe200 100644
+--- a/common/dispatch.c
++++ b/common/dispatch.c
+@@ -209,6 +209,10 @@ void add_timeout (when, where, what, ref, unref)
+ 	isc_interval_t interval;
+ 	isc_time_t expires;
+ 
++	if (when == NULL) {
++		return;
++	}
++
+ 	/* See if this timeout supersedes an existing timeout. */
+ 	t = (struct timeout *)0;
+ 	for (q = timeouts; q; q = q->next) {
+-- 
+2.14.5
+
diff --git a/SOURCES/0011-Drop-unnecessary-capabilities.patch b/SOURCES/0011-Drop-unnecessary-capabilities.patch
new file mode 100644
index 0000000..4277baf
--- /dev/null
+++ b/SOURCES/0011-Drop-unnecessary-capabilities.patch
@@ -0,0 +1,278 @@
+From 3b37f4b7bb3a17f8bd655be919915a1912062ea6 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:30:28 +0100
+Subject: [PATCH 11/26] Drop unnecessary capabilities
+Cc: pzhukov@redhat.com
+
+dhclient (#517649, #546765), dhcpd/dhcrelay (#699713)
+---
+ client/Makefile.am       |  3 ++-
+ client/dhclient-script.8 | 10 ++++++++++
+ client/dhclient.8        | 29 +++++++++++++++++++++++++++++
+ client/dhclient.c        | 24 ++++++++++++++++++++++++
+ configure.ac             | 35 +++++++++++++++++++++++++++++++++++
+ relay/Makefile.am        |  3 ++-
+ relay/dhcrelay.c         | 29 +++++++++++++++++++++++++++++
+ 7 files changed, 131 insertions(+), 2 deletions(-)
+
+diff --git a/client/Makefile.am b/client/Makefile.am
+index d177159..0689185 100644
+--- a/client/Makefile.am
++++ b/client/Makefile.am
+@@ -17,6 +17,7 @@ dhclient_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \
+ 		 @BINDLIBIRSDIR@/libirs.@A@ \
+ 		 @BINDLIBDNSDIR@/libdns.@A@ \
+ 		 @BINDLIBISCCFGDIR@/libisccfg.@A@ \
+-		 @BINDLIBISCDIR@/libisc.@A@
++		 @BINDLIBISCDIR@/libisc.@A@ \
++		 $(CAPNG_LDADD)
+ man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
+ EXTRA_DIST = $(man_MANS)
+diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
+index 0db5516..2eddb8f 100644
+--- a/client/dhclient-script.8
++++ b/client/dhclient-script.8
+@@ -243,6 +243,16 @@ repeatedly initialized to the values provided by one server, and then
+ the other.   Assuming the information provided by both servers is
+ valid, this shouldn't cause any real problems, but it could be
+ confusing.
++.PP
++Normally, if dhclient was compiled with libcap-ng support,
++dhclient drops most capabilities immediately upon startup.
++While more secure, this greatly restricts the additional actions that
++hooks in dhclient-script can take. For example, any daemons that
++dhclient-script starts or restarts will inherit the restricted
++capabilities as well, which may interfere with their correct operation.
++Thus, the
++.BI \-nc
++option can be used to prevent dhclient from dropping capabilities.
+ .SH SEE ALSO
+ dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
+ dhclient.leases(5).
+diff --git a/client/dhclient.8 b/client/dhclient.8
+index 6d7fbdb..0145b9f 100644
+--- a/client/dhclient.8
++++ b/client/dhclient.8
+@@ -134,6 +134,9 @@ dhclient - Dynamic Host Configuration Protocol Client
+ .B -w
+ ]
+ [
++.B -nc
++]
++[
+ .B -B
+ ]
+ [
+@@ -328,6 +331,32 @@ not to exit when it doesn't find any such interfaces.  The
+ program can then be used to notify the client when a network interface
+ has been added or removed, so that the client can attempt to configure an IP
+ address on that interface.
++.TP
++.BI \-nc
++Do not drop capabilities.
++
++Normally, if
++.B dhclient
++was compiled with libcap-ng support,
++.B dhclient
++drops most capabilities immediately upon startup.  While more secure,
++this greatly restricts the additional actions that hooks in
++.B dhclient-script (8)
++can take.  (For example, any daemons that 
++.B dhclient-script (8)
++starts or restarts will inherit the restricted capabilities as well,
++which may interfere with their correct operation.)  Thus, the
++.BI \-nc
++option can be used to prevent
++.B dhclient
++from dropping capabilities.
++
++The
++.BI \-nc
++option is ignored if
++.B dhclient
++was not compiled with libcap-ng support.
++
+ .TP
+ .BI \-n
+ Do not configure any interfaces.  This is most likely to be useful in
+diff --git a/client/dhclient.c b/client/dhclient.c
+index a86ab9e..5d3f5bc 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -41,6 +41,10 @@
+ #include <sys/wait.h>
+ #include <limits.h>
+ 
++#ifdef HAVE_LIBCAP_NG
++#include <cap-ng.h>
++#endif
++
+ /*
+  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
+  * that when building ISC code.
+@@ -266,6 +270,9 @@ main(int argc, char **argv) {
+ 	int timeout_arg = 0;
+ 	char *arg_conf = NULL;
+ 	int arg_conf_len = 0;
++#ifdef HAVE_LIBCAP_NG
++	int keep_capabilities = 0;
++#endif
+ 
+ 	/* Initialize client globals. */
+ 	memset(&default_duid, 0, sizeof(default_duid));
+@@ -665,6 +672,10 @@ main(int argc, char **argv) {
+ 
+ 			dhclient_request_options = argv[i];
+ 
++		} else if (!strcmp(argv[i], "-nc")) {
++#ifdef HAVE_LIBCAP_NG
++                  keep_capabilities = 1;
++#endif
+ 		} else if (argv[i][0] == '-') {
+ 			usage("Unknown command: %s", argv[i]);
+ 		} else if (interfaces_requested < 0) {
+@@ -725,6 +736,19 @@ main(int argc, char **argv) {
+ 		path_dhclient_script = s;
+ 	}
+ 
++#ifdef HAVE_LIBCAP_NG
++	/* Drop capabilities */
++	if (!keep_capabilities) {
++		capng_clear(CAPNG_SELECT_CAPS);
++		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++				CAP_DAC_OVERRIDE); // Drop this someday
++		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++				CAP_NET_ADMIN, CAP_NET_RAW,
++				CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
++		capng_apply(CAPNG_SELECT_CAPS);
++	}
++#endif
++
+ 	/* Set up the initial dhcp option universe. */
+ 	initialize_common_option_spaces();
+ 
+diff --git a/configure.ac b/configure.ac
+index a797438..15fc0d7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -612,6 +612,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[void foo() __attribute__((noreturn));
+ # Look for optional headers.
+ AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
+ 
++# look for capabilities library
++AC_ARG_WITH(libcap-ng,
++    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
++    with_libcap_ng=auto)
++
++# Check for Libcap-ng API
++#
++# libcap-ng detection
++if test x$with_libcap_ng = xno ; then
++    have_libcap_ng=no;
++else
++    # Start by checking for header file
++    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
++
++    # See if we have libcap-ng library
++    AC_CHECK_LIB(cap-ng, capng_clear,
++                 CAPNG_LDADD=-lcap-ng,)
++
++    # Check results are usable
++    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
++       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
++    fi
++    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
++       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
++    fi
++fi
++AC_SUBST(CAPNG_LDADD)
++AC_MSG_CHECKING(whether to use libcap-ng)
++if test x$CAPNG_LDADD != x ; then
++    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
++    AC_MSG_RESULT(yes)
++else
++    AC_MSG_RESULT(no)
++fi
++
+ # Solaris needs some libraries for functions
+ AC_SEARCH_LIBS(socket, [socket])
+ AC_SEARCH_LIBS(inet_ntoa, [nsl])
+diff --git a/relay/Makefile.am b/relay/Makefile.am
+index 2ba5979..8900e0b 100644
+--- a/relay/Makefile.am
++++ b/relay/Makefile.am
+@@ -6,7 +6,8 @@ dhcrelay_LDADD = ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \
+ 		 @BINDLIBIRSDIR@/libirs.@A@ \
+ 		 @BINDLIBDNSDIR@/libdns.@A@ \
+ 		 @BINDLIBISCCFGDIR@/libisccfg.@A@ \
+-		 @BINDLIBISCDIR@/libisc.@A@
++		 @BINDLIBISCDIR@/libisc.@A@ \
++		 $(CAPNG_LDADD)
+ man_MANS = dhcrelay.8
+ EXTRA_DIST = $(man_MANS)
+ 
+diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
+index ea1be18..7b4f4f1 100644
+--- a/relay/dhcrelay.c
++++ b/relay/dhcrelay.c
+@@ -32,6 +32,11 @@
+ #include <sys/time.h>
+ #include <isc/file.h>
+ 
++#ifdef HAVE_LIBCAP_NG
++#  include <cap-ng.h>
++   int keep_capabilities = 0;
++#endif
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+ struct tree_cache *global_options[256];
+@@ -590,6 +595,10 @@ main(int argc, char **argv) {
+ 			if (++i == argc)
+ 				usage(use_noarg, argv[i-1]);
+ 			dhcrelay_sub_id = argv[i];
++#endif
++		} else if (!strcmp(argv[i], "-nc")) {
++#ifdef HAVE_LIBCAP_NG
++			keep_capabilities = 1;
+ #endif
+ 		} else if (!strcmp(argv[i], "-pf")) {
+ 			if (++i == argc)
+@@ -660,6 +669,17 @@ main(int argc, char **argv) {
+ #endif
+ 	}
+ 
++#ifdef HAVE_LIBCAP_NG
++	/* Drop capabilities */
++	if (!keep_capabilities) {
++		capng_clear(CAPNG_SELECT_BOTH);
++		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++				CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
++		capng_apply(CAPNG_SELECT_BOTH);
++		log_info ("Dropped all unnecessary capabilities.");
++	}
++#endif
++
+ 	if (!quiet) {
+ 		log_info("%s %s", message, PACKAGE_VERSION);
+ 		log_info(copyright);
+@@ -816,6 +836,15 @@ main(int argc, char **argv) {
+ 	signal(SIGTERM, dhcp_signal_handler);  /* kill */
+ #endif
+ 
++#ifdef HAVE_LIBCAP_NG
++	/* Drop all capabilities */
++	if (!keep_capabilities) {
++		capng_clear(CAPNG_SELECT_BOTH);
++		capng_apply(CAPNG_SELECT_BOTH);
++		log_info ("Dropped all capabilities.");
++	}
++#endif
++
+ 	/* Start dispatching packets and timeouts... */
+ 	dispatch();
+ 
+-- 
+2.14.5
+
diff --git a/SOURCES/0012-RFC-3442-Classless-Static-Route-Option-for-DHCPv4-51.patch b/SOURCES/0012-RFC-3442-Classless-Static-Route-Option-for-DHCPv4-51.patch
new file mode 100644
index 0000000..866527c
--- /dev/null
+++ b/SOURCES/0012-RFC-3442-Classless-Static-Route-Option-for-DHCPv4-51.patch
@@ -0,0 +1,439 @@
+From 01b1dcfef129a4eccfaf0f63a216774019f82dca Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:32:35 +0100
+Subject: [PATCH 12/26] RFC 3442 - Classless Static Route Option for DHCPv4
+ (#516325)
+Cc: pzhukov@redhat.com
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24572])
+---
+ client/clparse.c      | 13 ++++++++++--
+ common/dhcp-options.5 | 43 +++++++++++++++++++++++++++++++++++++++
+ common/inet.c         | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
+ common/options.c      | 49 +++++++++++++++++++++++++++++++++++++++++++-
+ common/parse.c        | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ common/tables.c       |  2 ++
+ includes/dhcp.h       |  1 +
+ includes/dhcpd.h      |  2 ++
+ includes/dhctoken.h   |  5 +++--
+ 9 files changed, 219 insertions(+), 6 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index 44387ed..862e4f9 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -31,7 +31,7 @@
+ 
+ struct client_config top_level_config;
+ 
+-#define NUM_DEFAULT_REQUESTED_OPTS	14
++#define NUM_DEFAULT_REQUESTED_OPTS	15
+ /* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
+ struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
+ 
+@@ -87,7 +87,11 @@ isc_result_t read_client_conf ()
+ 				dhcp_universe.code_hash, &code, 0, MDL);
+ 
+ 	/* 4 */
+-	code = DHO_ROUTERS;
++	/* The Classless Static Routes option code MUST appear in the parameter
++     * request list prior to both the Router option code and the Static
++     * Routes option code, if present. (RFC3442)
++	 */
++	code = DHO_CLASSLESS_STATIC_ROUTES;
+ 	option_code_hash_lookup(&default_requested_options[3],
+ 				dhcp_universe.code_hash, &code, 0, MDL);
+ 
+@@ -141,6 +145,11 @@ isc_result_t read_client_conf ()
+ 	option_code_hash_lookup(&default_requested_options[13],
+ 				dhcp_universe.code_hash, &code, 0, MDL);
+ 
++	/* 15 */
++	code = DHO_ROUTERS;
++	option_code_hash_lookup(&default_requested_options[14],
++				dhcp_universe.code_hash, &code, 0, MDL);
++
+ 	for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
+ 		if (default_requested_options[code] == NULL)
+ 			log_fatal("Unable to find option definition for "
+diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
+index d9e1197..2343b19 100644
+--- a/common/dhcp-options.5
++++ b/common/dhcp-options.5
+@@ -110,6 +110,26 @@ hexadecimal, separated by colons.  For example:
+ or
+   option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
+ .fi
++.PP
++The
++.B destination-descriptor
++describe the IP subnet number and subnet mask
++of a particular destination using a compact encoding. This encoding
++consists of one octet describing the width of the subnet mask,
++followed by all the significant octets of the subnet number.
++The following table contains some examples of how various subnet
++number/mask combinations can be encoded:
++.nf
++.sp 1
++Subnet number   Subnet mask      Destination descriptor
++0               0                0
++10.0.0.0        255.0.0.0        8.10
++10.0.0.0        255.255.255.0    24.10.0.0
++10.17.0.0       255.255.0.0      16.10.17
++10.27.129.0     255.255.255.0    24.10.27.129
++10.229.0.128    255.255.255.128  25.10.229.0.128
++10.198.122.47   255.255.255.255  32.10.198.122.47
++.fi
+ .SH SETTING OPTION VALUES USING EXPRESSIONS
+ Sometimes it's helpful to be able to set the value of a DHCP option
+ based on some value that the client has sent.  To do this, you can
+@@ -1086,6 +1106,29 @@ dhclient-script will create routes:
+ .RE
+ .PP
+ .nf
++.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR
++                            [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR
++.fi
++.RS 0.25i
++.PP
++This option (see RFC3442) specifies a list of classless static routes
++that the client should install in its routing cache.
++.PP
++This option can contain one or more static routes, each of which
++consists of a destination descriptor and the IP address of the router
++that should be used to reach that destination.
++.PP
++Many clients may not implement the Classless Static Routes option.
++DHCP server administrators should therefore configure their DHCP
++servers to send both a Router option and a Classless Static Routes
++option, and should specify the default router(s) both in the Router
++option and in the Classless Static Routes option.
++.PP
++If the DHCP server returns both a Classless Static Routes option and
++a Router option, the DHCP client ignores the Router option.
++.RE
++.PP
++.nf
+ .B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR
+                                            [\fB,\fR \fIip-address\fR...]\fB;\fR
+ .fi
+diff --git a/common/inet.c b/common/inet.c
+index c4da73c..981fb92 100644
+--- a/common/inet.c
++++ b/common/inet.c
+@@ -519,6 +519,60 @@ free_iaddrcidrnetlist(struct iaddrcidrnetlist **result) {
+ 	return ISC_R_SUCCESS;
+ }
+ 
++static const char *
++inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size)
++{
++	char tmp[sizeof("32.255.255.255.255")];
++	int len;
++
++	switch (srclen) {
++		case 2:
++			len = sprintf (tmp, "%u.%u", src[0], src[1]);
++			break;
++		case 3:
++			len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]);
++			break;
++		case 4:
++			len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
++			break;
++		case 5:
++			len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]);
++			break;
++		default:
++			return NULL;
++	}
++	if (len < 0)
++		return NULL;
++
++	if (len > size) {
++		errno = ENOSPC;
++		return NULL;
++	}
++
++	return strcpy (dst, tmp);
++}
++
++/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */
++const char *
++pdestdesc(const struct iaddr addr) {
++	static char pbuf[sizeof("255.255.255.255.255")];
++
++	if (addr.len == 0) {
++		return "<null destination descriptor>";
++	}
++	if (addr.len == 1) {
++		return "0";
++	}
++	if ((addr.len >= 2) && (addr.len <= 5)) {
++		return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf));
++	}
++
++	log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.",
++		  MDL, addr.len);
++	/* quell compiler warnings */
++	return NULL;
++}
++
+ /* piaddr() turns an iaddr structure into a printable address. */
+ /* XXX: should use a const pointer rather than passing the structure */
+ const char *
+diff --git a/common/options.c b/common/options.c
+index fc0e088..3034cf0 100644
+--- a/common/options.c
++++ b/common/options.c
+@@ -729,7 +729,11 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
+ 		 * packet.
+ 		 */
+ 		priority_list[priority_len++] = DHO_SUBNET_MASK;
+-		priority_list[priority_len++] = DHO_ROUTERS;
++		if (lookup_option(&dhcp_universe, cfg_options,
++							DHO_CLASSLESS_STATIC_ROUTES))
++			priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES;
++		else
++			priority_list[priority_len++] = DHO_ROUTERS;
+ 		priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS;
+ 		priority_list[priority_len++] = DHO_HOST_NAME;
+ 		priority_list[priority_len++] = DHO_FQDN;
+@@ -1804,6 +1808,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+ 	unsigned long tval;
+ 	isc_boolean_t a_array = ISC_FALSE;
+ 	int len_used;
++	unsigned int octets = 0;
+ 
+ 	if (emit_commas)
+ 		comma = ',';
+@@ -1812,6 +1817,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+ 
+ 	memset (enumbuf, 0, sizeof enumbuf);
+ 
++	if (option->format[0] != 'R') { /* see explanation lower */
+ 	/* Figure out the size of the data. */
+ 	for (l = i = 0; option -> format [i]; i++, l++) {
+ 		if (l >= sizeof(fmtbuf) - 1)
+@@ -2004,6 +2010,33 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+ 	if (numhunk < 0)
+ 		numhunk = 1;
+ 
++	} else { /* option->format[i] == 'R') */
++		/* R (destination descriptor) has variable length.
++		 * We can find it only in classless static route option,
++		 * so we are for sure parsing classless static route option now.
++		 * We go through whole the option to check whether there are no
++		 * missing/extra bytes.
++		 * I didn't find out how to improve the existing code and that's the
++		 * reason for this separate 'else' where I do my own checkings.
++		 * I know it's little bit unsystematic, but it works.
++		 */
++		numhunk = 0;
++		numelem = 2; /* RI */
++		fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0;
++		for (i =0; i < len; i = i + octets + 5) {
++			if (data[i] > 32) { /* subnet mask width */
++				log_error ("wrong subnet mask width in destination descriptor");
++				break;
++			}
++			numhunk++;
++			octets = ((data[i]+7) / 8);
++		}
++		if (i != len) {
++			log_error ("classless static routes option has wrong size or "
++					   "there's some garbage in format");
++		}
++	}
++
+ 	/* Cycle through the array (or hunk) printing the data. */
+ 	for (i = 0; i < numhunk; i++) {
+ 		if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
+@@ -2159,6 +2192,20 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+ 				strcpy(op, piaddr(iaddr));
+ 				dp += 4;
+ 				break;
++
++			      case 'R':
++				if (dp[0] <= 32)
++					iaddr.len = (((dp[0]+7)/8)+1);
++				else {
++					log_error ("wrong subnet mask width in destination descriptor");
++					return "<error>";
++				}
++
++				memcpy(iaddr.iabuf, dp, iaddr.len);
++				strcpy(op, pdestdesc(iaddr));
++				dp += iaddr.len;
++				break;
++
+ 			      case '6':
+ 				iaddr.len = 16;
+ 				memcpy(iaddr.iabuf, dp, 16);
+diff --git a/common/parse.c b/common/parse.c
+index 3ac4ebf..f17bc0b 100644
+--- a/common/parse.c
++++ b/common/parse.c
+@@ -344,6 +344,39 @@ int parse_ip_addr (cfile, addr)
+ 	return 0;
+ }	
+ 
++/*
++ * destination-descriptor :== NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
++ */
++
++int parse_destination_descriptor (cfile, addr)
++	struct parse *cfile;
++	struct iaddr *addr;
++{
++		unsigned int mask_width, dest_dest_len;
++		addr -> len = 0;
++		if (parse_numeric_aggregate (cfile, addr -> iabuf,
++									 &addr -> len, DOT, 10, 8)) {
++			mask_width = (unsigned int)addr->iabuf[0];
++			dest_dest_len = (((mask_width+7)/8)+1);
++			if (mask_width > 32) {
++				parse_warn (cfile,
++				"subnet mask width (%u) greater than 32.", mask_width);
++			}
++			else if (dest_dest_len != addr->len) {
++				parse_warn (cfile,
++				"destination descriptor with subnet mask width %u "
++				"should have %u octets, but has %u octets.",
++				mask_width, dest_dest_len, addr->len);
++			}
++
++			return 1;
++		}
++		return 0;
++}
++
+ /*
+  * Return true if every character in the string is hexadecimal.
+  */
+@@ -724,8 +757,10 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
+ 		if (count) {
+ 			token = peek_token (&val, (unsigned *)0, cfile);
+ 			if (token != separator) {
+-				if (!*max)
++				if (!*max) {
++					*max = count;
+ 					break;
++				}
+ 				if (token != RBRACE && token != LBRACE)
+ 					token = next_token (&val,
+ 							    (unsigned *)0,
+@@ -1672,6 +1707,9 @@ int parse_option_code_definition (cfile, option)
+ 	      case IP_ADDRESS:
+ 		type = 'I';
+ 		break;
++	      case DESTINATION_DESCRIPTOR:
++		type = 'R';
++		break;
+ 	      case IP6_ADDRESS:
+ 		type = '6';
+ 		break;
+@@ -5101,6 +5139,15 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
+ 		}
+ 		break;
+ 
++	      case 'R': /* destination descriptor */
++		if (!parse_destination_descriptor (cfile, &addr)) {
++			return 0;
++		}
++		if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) {
++			return 0;
++		}
++		break;
++
+ 	      case '6': /* IPv6 address. */
+ 		if (!parse_ip6_addr(cfile, &addr)) {
+ 			return 0;
+@@ -5378,6 +5425,13 @@ int parse_option_decl (oc, cfile)
+ 					goto exit;
+ 				len = ip_addr.len;
+ 				dp = ip_addr.iabuf;
++				goto alloc;
++
++			      case 'R': /* destination descriptor */
++				if (!parse_destination_descriptor (cfile, &ip_addr))
++					goto exit;
++				len = ip_addr.len;
++				dp = ip_addr.iabuf;
+ 
+ 			      alloc:
+ 				if (hunkix + len > sizeof hunkbuf) {
+diff --git a/common/tables.c b/common/tables.c
+index d2294c0..f1be07d 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -45,6 +45,7 @@ HASH_FUNCTIONS (option_code, const unsigned *, struct option,
+    Format codes:
+ 
+    I - IPv4 address
++   R - destination descriptor (RFC3442)
+    6 - IPv6 address
+    l - 32-bit signed integer
+    L - 32-bit unsigned integer
+@@ -216,6 +217,7 @@ static struct option dhcp_options[] = {
+ #endif
+ 	{ "subnet-selection", "I",		&dhcp_universe, 118, 1 },
+ 	{ "domain-search", "D",			&dhcp_universe, 119, 1 },
++	{ "classless-static-routes", "RIA",	&dhcp_universe, 121, 1 },
+ 	{ "vivco", "Evendor-class.",		&dhcp_universe, 124, 1 },
+ 	{ "vivso", "Evendor.",			&dhcp_universe, 125, 1 },
+ #if 0
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index 0a74137..95bf539 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -158,6 +158,7 @@ struct dhcp_packet {
+ #define DHO_ASSOCIATED_IP			92
+ #define DHO_SUBNET_SELECTION			118 /* RFC3011! */
+ #define DHO_DOMAIN_SEARCH			119 /* RFC3397 */
++#define DHO_CLASSLESS_STATIC_ROUTES		121 /* RFC3442 */
+ #define DHO_VIVCO_SUBOPTIONS			124
+ #define DHO_VIVSO_SUBOPTIONS			125
+ 
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 3632a6b..2ac39ae 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -2951,6 +2951,7 @@ isc_result_t range2cidr(struct iaddrcidrnetlist **result,
+ 			const struct iaddr *lo, const struct iaddr *hi);
+ isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result);
+ const char *piaddr (struct iaddr);
++const char *pdestdesc (struct iaddr);
+ char *piaddrmask(struct iaddr *, struct iaddr *);
+ char *piaddrcidr(const struct iaddr *, unsigned int);
+ u_int16_t validate_port(char *);
+@@ -3169,6 +3170,7 @@ void parse_client_lease_declaration (struct parse *,
+ int parse_option_decl (struct option_cache **, struct parse *);
+ void parse_string_list (struct parse *, struct string_list **, int);
+ int parse_ip_addr (struct parse *, struct iaddr *);
++int parse_destination_descriptor (struct parse *, struct iaddr *);
+ int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *);
+ void parse_reject_statement (struct parse *, struct client_config *);
+ 
+diff --git a/includes/dhctoken.h b/includes/dhctoken.h
+index 7e7215a..b4d93ba 100644
+--- a/includes/dhctoken.h
++++ b/includes/dhctoken.h
+@@ -376,8 +376,9 @@ enum dhcp_token {
+ 	LEASE_ID_FORMAT = 676,
+ 	TOKEN_HEX = 677,
+ 	TOKEN_OCTAL = 678,
+-	KEY_ALGORITHM = 679
+-        BOOTP_BROADCAST_ALWAYS = 680
++	KEY_ALGORITHM = 679,
++        BOOTP_BROADCAST_ALWAYS = 680,
++	DESTINATION_DESCRIPTOR = 681
+ };
+ 
+ #define is_identifier(x)	((x) >= FIRST_TOKEN &&	\
+-- 
+2.14.5
+
diff --git a/SOURCES/0013-DHCPv6-over-PPP-support-626514.patch b/SOURCES/0013-DHCPv6-over-PPP-support-626514.patch
new file mode 100644
index 0000000..5e0a6ba
--- /dev/null
+++ b/SOURCES/0013-DHCPv6-over-PPP-support-626514.patch
@@ -0,0 +1,176 @@
+From 234747fbfd6c6429619ba843713d5b39fb4a513d Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:33:06 +0100
+Subject: [PATCH 13/26] DHCPv6 over PPP support (#626514)
+Cc: pzhukov@redhat.com
+
+---
+ client/dhc6.c     |  3 ++-
+ client/dhclient.c | 17 ++++++++++++++---
+ common/bpf.c      | 16 ++++++++++++++++
+ common/lpf.c      | 16 ++++++++++++++++
+ includes/dhcp.h   |  2 ++
+ includes/dhcpd.h  |  2 +-
+ server/dhcpv6.c   |  3 +++
+ 7 files changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/client/dhc6.c b/client/dhc6.c
+index 16a0838..3171828 100644
+--- a/client/dhc6.c
++++ b/client/dhc6.c
+@@ -5744,7 +5744,8 @@ make_client6_options(struct client_state *client, struct option_state **op,
+ 	 */
+ 	if ((oc = lookup_option(&dhcpv6_universe, *op,
+ 				D6O_CLIENTID)) == NULL) {
+-		if (!option_cache(&oc, &default_duid, NULL, clientid_option,
++		if (default_duid.len == 0 ||
++		    !option_cache(&oc, &default_duid, NULL, clientid_option,
+ 				  MDL))
+ 			log_fatal("Failure assembling a DUID.");
+ 
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 5d3f5bc..301132c 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1202,8 +1202,8 @@ main(int argc, char **argv) {
+ 			if (default_duid.buffer != NULL)
+ 				data_string_forget(&default_duid, MDL);
+ 
+-			form_duid(&default_duid, MDL);
+-			write_duid(&default_duid);
++			if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
++				write_duid(&default_duid);
+ 		}
+ 	}
+ 
+@@ -3956,7 +3956,7 @@ write_options(struct client_state *client, struct option_state *options,
+  * is not how it is intended.  Upcoming rearchitecting the client should
+  * address this "one daemon model."
+  */
+-void
++isc_result_t
+ form_duid(struct data_string *duid, const char *file, int line)
+ {
+ 	struct interface_info *ip;
+@@ -3969,6 +3969,15 @@ form_duid(struct data_string *duid, const char *file, int line)
+ 	if (ip == NULL)
+ 		log_fatal("Impossible condition at %s:%d.", MDL);
+ 
++	while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
++		/* Try the other interfaces */
++		log_debug("Cannot form default DUID from interface %s.", ip->name);
++		ip = ip->next;
++	}
++	if (ip == NULL) {
++		return ISC_R_UNEXPECTED;
++	}
++
+ 	if ((ip->hw_address.hlen == 0) ||
+ 	    (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+ 		log_fatal("Impossible hardware address length at %s:%d.", MDL);
+@@ -4014,6 +4023,8 @@ form_duid(struct data_string *duid, const char *file, int line)
+ 		log_info("Created duid %s.", str);
+ 		dfree(str, MDL);
+ 	}
++	
++	return ISC_R_SUCCESS;
+ }
+ 
+ /* Write the default DUID to the lease store. */
+diff --git a/common/bpf.c b/common/bpf.c
+index 67b6d64..ffbd09a 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -650,6 +650,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
+                         memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
+                         break;
+ #endif /* IFT_FDDI */
++#if defined(IFT_PPP)
++                case IFT_PPP:
++                        if (local_family != AF_INET6)
++                             log_fatal("Unsupported device type %d for \"%s\"",
++                                        sa->sdl_type, name);
++                        hw->hlen = 0;
++                        hw->hbuf[0] = HTYPE_RESERVED;
++                        /* 0xdeadbeef should never occur on the wire,
++                         *  and is a signature that something went wrong.
++                         */
++                        hw->hbuf[1] = 0xde;
++                        hw->hbuf[2] = 0xad;
++                        hw->hbuf[3] = 0xbe;
++                        hw->hbuf[4] = 0xef;
++                        break;
++#endif
+                 default:
+                         log_fatal("Unsupported device type %d for \"%s\"",
+                                   sa->sdl_type, name);
+diff --git a/common/lpf.c b/common/lpf.c
+index 82a279b..b0ed01c 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -563,6 +563,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
+ 			hw->hbuf[0] = HTYPE_FDDI;
+ 			memcpy(&hw->hbuf[1], sa->sa_data, 6);
+ 			break;
++#if defined(ARPHRD_PPP)
++		case ARPHRD_PPP:
++			if (local_family != AF_INET6)
++				log_fatal("Unsupported device type %d for \"%s\"",
++				           sa->sa_family, name);
++			hw->hlen = 0;
++			hw->hbuf[0] = HTYPE_RESERVED;
++			/* 0xdeadbeef should never occur on the wire,
++			 * and is a signature that something went wrong.
++			 */
++			hw->hbuf[1] = 0xde;
++			hw->hbuf[2] = 0xad;
++			hw->hbuf[3] = 0xbe;
++			hw->hbuf[4] = 0xef;
++			break;
++#endif
+ 		default:
+ 			log_fatal("Unsupported device type %ld for \"%s\"",
+ 				  (long int)sa->sa_family, name);
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index 95bf539..4cc547a 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -80,6 +80,8 @@ struct dhcp_packet {
+ 					 * is no standard for this so we
+ 					 * just steal a type            */
+ 
++#define HTYPE_RESERVED	0		/* RFC 5494 */
++
+ /* Magic cookie validating dhcp options field (and bootp vendor
+    extensions field). */
+ #define DHCP_OPTIONS_COOKIE	"\143\202\123\143"
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 2ac39ae..faa9251 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -3051,7 +3051,7 @@ void client_dns_remove(struct client_state *client, struct iaddr *addr);
+ 
+ void dhcpv4_client_assignments(void);
+ void dhcpv6_client_assignments(void);
+-void form_duid(struct data_string *duid, const char *file, int line);
++isc_result_t form_duid(struct data_string *duid, const char *file, int line);
+ 
+ void dhcp4o6_start(void);
+ 
+diff --git a/server/dhcpv6.c b/server/dhcpv6.c
+index a7110f9..c5ce7e8 100644
+--- a/server/dhcpv6.c
++++ b/server/dhcpv6.c
+@@ -482,6 +482,9 @@ generate_new_server_duid(void) {
+ 		if (p->hw_address.hlen > 0) {
+ 			break;
+ 		}
++		if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
++			log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
++		}
+ 	}
+ 	if (p == NULL) {
+ 		return ISC_R_UNEXPECTED;
+-- 
+2.14.5
+
diff --git a/SOURCES/0014-IPoIB-support-660681.patch b/SOURCES/0014-IPoIB-support-660681.patch
new file mode 100644
index 0000000..3d6d316
--- /dev/null
+++ b/SOURCES/0014-IPoIB-support-660681.patch
@@ -0,0 +1,629 @@
+From 042082b4410f158ec86ca8478689b34bc12518e6 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:34:21 +0100
+Subject: [PATCH 14/27] IPoIB support (#660681)
+Cc: pzhukov@redhat.com
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24249])
+---
+ client/dhclient.c |  32 ++++++
+ common/bpf.c      |  32 ++++++
+ common/discover.c |   4 +-
+ common/lpf.c      | 276 ++++++++++++++++++++++++++++++++++++++++++----
+ common/socket.c   |   8 +-
+ includes/dhcpd.h  |   6 +-
+ 6 files changed, 329 insertions(+), 29 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 301132c..dc9080e 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -205,6 +205,8 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
+   
+ #define DHCLIENT_USAGEH "{--version|--help|-h}"
+ 
++static void setup_ib_interface(struct interface_info *ip);
++
+ static void
+ usage(const char *sfmt, const char *sarg)
+ {
+@@ -1191,6 +1193,13 @@ main(int argc, char **argv) {
+ 	}
+ 	srandom(seed + cur_time + (unsigned)getpid());
+ 
++	/* Setup specific Infiniband options */
++	for (ip = interfaces; ip; ip = ip->next) {
++		if (ip->client &&
++		    (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
++			setup_ib_interface(ip);
++		}
++	}
+ 
+ 	/*
+ 	 * Establish a default DUID.  We always do so for v6 and
+@@ -1486,6 +1495,29 @@ int find_subnet (struct subnet **sp,
+ 	return 0;
+ }
+ 
++static void setup_ib_interface(struct interface_info *ip)
++{
++	struct group *g;
++
++	/* Set the broadcast flag */
++	ip->client->config->bootp_broadcast_always = 1;
++
++	/*
++	 * Find out if a dhcp-client-identifier option was specified either
++	 * in the config file or on the command line
++	 */
++	for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
++		if ((g->statements != NULL) &&
++		    (strcmp(g->statements->data.option->option->name,
++			    "dhcp-client-identifier") == 0)) {
++			return;
++		}
++	}
++
++	/* No client ID specified */
++	log_fatal("dhcp-client-identifier must be specified for InfiniBand");
++}
++
+ /* Individual States:
+  *
+  * Each routine is called from the dhclient_state_machine() in one of
+diff --git a/common/bpf.c b/common/bpf.c
+index ffbd09a..568e3d9 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -237,11 +237,43 @@ int dhcp_bpf_relay_filter_len =
+ 	sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
+ #endif
+ 
++/* Packet filter program for DHCP over Infiniband.
++ *
++ * XXX
++ * Changes to the filter program may require changes to the constant offsets
++ * used in lpf_gen_filter_setup to patch the port in the BPF program!
++ * XXX
++ */
++struct bpf_insn dhcp_ib_bpf_filter [] = {
++	/* Packet filter for Infiniband */
++	/* Make sure it's a UDP packet... */
++	BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
++	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
++
++	/* Make sure this isn't a fragment... */
++	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
++	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
++
++	/* Get the IP header length... */
++	BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
++
++	/* Make sure it's to the right port... */
++	BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
++	BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
++
++	/* If we passed all the tests, ask for the whole packet. */
++	BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
++
++	/* Otherwise, drop it. */
++	BPF_STMT(BPF_RET + BPF_K, 0),
++};
++
+ #if defined (DEC_FDDI)
+ struct bpf_insn *bpf_fddi_filter = NULL;
+ #endif
+ 
+ int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
++int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
+ #if defined (HAVE_TR_SUPPORT)
+ struct bpf_insn dhcp_bpf_tr_filter [] = {
+         /* accept all token ring packets due to variable length header */
+diff --git a/common/discover.c b/common/discover.c
+index 6ef8852..65881fc 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -894,7 +894,7 @@ discover_interfaces(int state) {
+ 				if_register_send(tmp);
+ 			} else {
+ 				/* get_hw_addr() was called by register. */
+-				get_hw_addr(tmp->name, &tmp->hw_address);
++				get_hw_addr(tmp);
+ 			}
+ 			break;
+ #ifdef DHCPv6
+@@ -907,7 +907,7 @@ discover_interfaces(int state) {
+ 				   so now we have to call it explicitly
+ 				   to not leave the hardware address unknown
+ 				   (some code expects it cannot be. */
+-				get_hw_addr(tmp->name, &tmp->hw_address);
++				get_hw_addr(tmp);
+ 			} else {
+ 				if_register_linklocal6(tmp);
+ 			}
+diff --git a/common/lpf.c b/common/lpf.c
+index b0ed01c..a9e19f4 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -45,6 +45,17 @@
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
++#include <ifaddrs.h>
++
++/* Default broadcast address for IPoIB */
++static unsigned char default_ib_bcast_addr[20] = {
++ 	0x00, 0xff, 0xff, 0xff,
++	0xff, 0x12, 0x40, 0x1b,
++	0x00, 0x00, 0x00, 0x00,
++	0x00, 0x00, 0x00, 0x00,
++	0xff, 0xff, 0xff, 0xff
++};
++
+ #endif
+ 
+ #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
+@@ -78,10 +89,20 @@ int if_register_lpf (info)
+ 		struct sockaddr common;
+ 		} sa;
+ 	struct ifreq ifr;
++	int type;
++	int protocol;
++
++	get_hw_addr(info);
++	if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++		type = SOCK_DGRAM;
++		protocol = ETHERTYPE_IP;
++	} else {
++		type = SOCK_RAW;
++		protocol = ETH_P_ALL;
++	}
+ 
+ 	/* Make an LPF socket. */
+-	if ((sock = socket(PF_PACKET, SOCK_RAW,
+-			   htons((short)ETH_P_ALL))) < 0) {
++	if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
+ 		if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+ 		    errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+ 		    errno == EAFNOSUPPORT || errno == EINVAL) {
+@@ -104,6 +125,7 @@ int if_register_lpf (info)
+ 	/* Bind to the interface name */
+ 	memset (&sa, 0, sizeof sa);
+ 	sa.ll.sll_family = AF_PACKET;
++	sa.ll.sll_protocol = htons(protocol);
+ 	sa.ll.sll_ifindex = ifr.ifr_ifindex;
+ 	if (bind (sock, &sa.common, sizeof sa)) {
+ 		if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+@@ -120,8 +142,6 @@ int if_register_lpf (info)
+ 
+ 	}
+ 
+-	get_hw_addr(info->name, &info->hw_address);
+-
+ 	return sock;
+ }
+ #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
+@@ -176,6 +196,8 @@ void if_deregister_send (info)
+    in bpf includes... */
+ extern struct sock_filter dhcp_bpf_filter [];
+ extern int dhcp_bpf_filter_len;
++extern struct sock_filter dhcp_ib_bpf_filter [];
++extern int dhcp_ib_bpf_filter_len;
+ 
+ #if defined(RELAY_PORT)
+ extern struct sock_filter dhcp_bpf_relay_filter [];
+@@ -199,11 +221,12 @@ void if_register_receive (info)
+ #ifdef PACKET_AUXDATA
+ 	{
+ 	int val = 1;
+-
+-	if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
+-		       &val, sizeof(val)) < 0) {
+-		if (errno != ENOPROTOOPT) {
+-			log_fatal ("Failed to set auxiliary packet data: %m");
++	if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
++		if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
++			      &val, sizeof(val)) < 0) {
++			if (errno != ENOPROTOOPT) {
++				log_fatal ("Failed to set auxiliary packet data: %m");
++			}
+ 		}
+ 	}
+ 	}
+@@ -253,6 +276,18 @@ static void lpf_gen_filter_setup (info)
+ 
+ 	memset(&p, 0, sizeof(p));
+ 
++	if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++		p.len = dhcp_ib_bpf_filter_len;
++		p.filter = dhcp_ib_bpf_filter;
++
++		/* Patch the server port into the LPF program...
++		   XXX
++		   changes to filter program may require changes
++		   to the insn number(s) used below!
++		   XXX */
++		dhcp_ib_bpf_filter[6].k = ntohs (local_port);
++	} else {
++
+ 	/* Set up the bpf filter program structure.    This is defined in
+ 	   bpf.c */
+ 	p.len = dhcp_bpf_filter_len;
+@@ -275,6 +310,8 @@ static void lpf_gen_filter_setup (info)
+ #endif
+ 	dhcp_bpf_filter [8].k = ntohs (local_port);
+ 
++	}
++
+ 	if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+ 			sizeof p) < 0) {
+ 		if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+@@ -330,6 +367,54 @@ static void lpf_tr_filter_setup (info)
+ #endif /* USE_LPF_RECEIVE */
+ 
+ #ifdef USE_LPF_SEND
++ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
++	struct interface_info *interface;
++	struct packet *packet;
++	struct dhcp_packet *raw;
++	size_t len;
++	struct in_addr from;
++	struct sockaddr_in *to;
++	struct hardware *hto;
++{
++	unsigned ibufp = 0;
++	double ih [1536 / sizeof (double)];
++	unsigned char *buf = (unsigned char *)ih;
++	ssize_t result;
++
++	union sockunion {
++		struct sockaddr sa;
++		struct sockaddr_ll sll;
++		struct sockaddr_storage ss;
++	} su;
++
++	assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
++				to->sin_addr.s_addr, to->sin_port,
++				(unsigned char *)raw, len);
++	memcpy (buf + ibufp, raw, len);
++
++	memset(&su, 0, sizeof(su));
++	su.sll.sll_family = AF_PACKET;
++	su.sll.sll_protocol = htons(ETHERTYPE_IP);
++
++	if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
++		errno = ENOENT;
++		log_error ("send_packet_ib: %m - failed to get if index");
++		return -1;
++	}
++
++	su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
++	su.sll.sll_halen = sizeof(interface->bcast_addr);
++	memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
++
++	result = sendto(interface->wfdesc, buf, ibufp + len, 0,
++			&su.sa, sizeof(su));
++
++	if (result < 0)
++		log_error ("send_packet_ib: %m");
++
++	return result;
++}
++
+ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ 	struct interface_info *interface;
+ 	struct packet *packet;
+@@ -350,6 +435,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ 		return send_fallback (interface, packet, raw,
+ 				      len, from, to, hto);
+ 
++	if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++		return send_packet_ib(interface, packet, raw, len, from,
++				      to, hto);
++	}
++
+ 	if (hto == NULL && interface->anycast_mac_addr.hlen)
+ 		hto = &interface->anycast_mac_addr;
+ 
+@@ -370,6 +460,42 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ #endif /* USE_LPF_SEND */
+ 
+ #ifdef USE_LPF_RECEIVE
++ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
++	struct interface_info *interface;
++	unsigned char *buf;
++	size_t len;
++	struct sockaddr_in *from;
++	struct hardware *hfrom;
++{
++	int length = 0;
++	int offset = 0;
++	unsigned char ibuf [1536];
++	unsigned bufix = 0;
++	unsigned paylen;
++
++	length = read(interface->rfdesc, ibuf, sizeof(ibuf));
++
++	if (length <= 0)
++		return length;
++
++	offset = decode_udp_ip_header(interface, ibuf, bufix, from,
++				       (unsigned)length, &paylen, 0);
++
++	if (offset < 0)
++		return 0;
++
++	bufix += offset;
++	length -= offset;
++
++	if (length < paylen)
++		log_fatal("Internal inconsistency at %s:%d.", MDL);
++
++	/* Copy out the data in the packet... */
++	memcpy(buf, &ibuf[bufix], paylen);
++
++	return (ssize_t)paylen;
++}
++
+ ssize_t receive_packet (interface, buf, len, from, hfrom)
+ 	struct interface_info *interface;
+ 	unsigned char *buf;
+@@ -408,6 +534,10 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
+ 	};
+ #endif /* PACKET_AUXDATA */
+ 
++	if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++		return receive_packet_ib(interface, buf, len, from, hfrom);
++	}
++
+ 	length = recvmsg (interface->rfdesc, &msg, 0);
+ 	if (length <= 0)
+ 		return length;
+@@ -521,11 +651,33 @@ void maybe_setup_fallback ()
+ #endif
+ 
+ #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
+-void
+-get_hw_addr(const char *name, struct hardware *hw) {
++struct sockaddr_ll *
++get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name)
++{
++	for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
++		if ((*ifa)->ifa_addr == NULL)
++			continue;
++
++		if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
++			continue;
++
++		if ((*ifa)->ifa_flags & IFF_LOOPBACK)
++			continue;
++
++		if (strcmp((*ifa)->ifa_name, name) == 0)
++			return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr;
++	}
++	*ifa = NULL;
++	return NULL;
++}
++
++struct sockaddr_ll *
++ioctl_get_ll(char *name)
++{
+ 	int sock;
+ 	struct ifreq tmp;
+-	struct sockaddr *sa;
++	struct sockaddr *sa = NULL;
++	struct sockaddr_ll *sll = NULL;
+ 
+ 	if (strlen(name) >= sizeof(tmp.ifr_name)) {
+ 		log_fatal("Device name too long: \"%s\"", name);
+@@ -539,16 +691,61 @@ get_hw_addr(const char *name, struct hardware *hw) {
+ 	memset(&tmp, 0, sizeof(tmp));
+ 	strcpy(tmp.ifr_name, name);
+ 	if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
+-		log_fatal("Error getting hardware address for \"%s\": %m", 
++		log_fatal("Error getting hardware address for \"%s\": %m",
+ 			  name);
+ 	}
++	close(sock);
+ 
+ 	sa = &tmp.ifr_hwaddr;
+-	switch (sa->sa_family) {
++	// needs to be freed outside this function
++	sll = dmalloc (sizeof (struct sockaddr_ll), MDL);
++	if (!sll)
++		log_fatal("Unable to allocate memory for link layer address");
++	memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
++	memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
++	switch (sll->sll_hatype) {
++		case ARPHRD_INFINIBAND:
++			sll->sll_halen = HARDWARE_ADDR_LEN_IOCTL;
++			break;
++		default:
++			break;
++	}
++	return sll;
++}
++
++void
++get_hw_addr(struct interface_info *info)
++{
++	struct hardware *hw = &info->hw_address;
++	char *name = info->name;
++	struct ifaddrs *ifaddrs = NULL;
++	struct ifaddrs *ifa = NULL;
++	struct sockaddr_ll *sll = NULL;
++	int sll_allocated = 0;
++	char *dup = NULL;
++	char *colon = NULL;
++
++	if (getifaddrs(&ifaddrs) == -1)
++		log_fatal("Failed to get interfaces");
++
++	if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
++		/*
++		 * We were unable to get link-layer address for name.
++		 * Fall back to ioctl(SIOCGIFHWADDR).
++		 */
++		sll = ioctl_get_ll(name);
++		if (sll != NULL)
++			sll_allocated = 1;
++		else
++			// shouldn't happen
++			log_fatal("Unexpected internal error");
++	}
++
++	switch (sll->sll_hatype) {
+ 		case ARPHRD_ETHER:
+ 			hw->hlen = 7;
+ 			hw->hbuf[0] = HTYPE_ETHER;
+-			memcpy(&hw->hbuf[1], sa->sa_data, 6);
++			memcpy(&hw->hbuf[1], sll->sll_addr, 6);
+ 			break;
+ 		case ARPHRD_IEEE802:
+ #ifdef ARPHRD_IEEE802_TR
+@@ -556,18 +753,50 @@ get_hw_addr(const char *name, struct hardware *hw) {
+ #endif /* ARPHRD_IEEE802_TR */
+ 			hw->hlen = 7;
+ 			hw->hbuf[0] = HTYPE_IEEE802;
+-			memcpy(&hw->hbuf[1], sa->sa_data, 6);
++			memcpy(&hw->hbuf[1], sll->sll_addr, 6);
+ 			break;
+ 		case ARPHRD_FDDI:
+ 			hw->hlen = 7;
+ 			hw->hbuf[0] = HTYPE_FDDI;
+-			memcpy(&hw->hbuf[1], sa->sa_data, 6);
++			memcpy(&hw->hbuf[1], sll->sll_addr, 6);
++			break;
++		case ARPHRD_INFINIBAND:
++			dup = strdup(name);
++			/* Aliased infiniband interface is special case where
++			 * neither get_ll() nor ioctl_get_ll() get's correct hw
++			 * address, so we have to truncate the :0 and run
++			 * get_ll() again for the rest.
++			*/
++			if ((colon = strchr(dup, ':')) != NULL) {
++				*colon = '\0';
++				if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
++					log_fatal("Error getting hardware address for \"%s\": %m", name);
++			}
++			free (dup);
++			/* For Infiniband, save the broadcast address and store
++			 * the port GUID into the hardware address.
++			 */
++			if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
++				struct sockaddr_ll *bll;
++
++				bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
++				memcpy(&info->bcast_addr, bll->sll_addr, 20);
++			} else {
++				memcpy(&info->bcast_addr, default_ib_bcast_addr,
++				       20);
++			}
++
++			hw->hlen = HARDWARE_ADDR_LEN_IOCTL + 1;
++			hw->hbuf[0] = HTYPE_INFINIBAND;
++			memcpy(&hw->hbuf[1],
++			       &sll->sll_addr[sll->sll_halen - HARDWARE_ADDR_LEN_IOCTL],
++			       HARDWARE_ADDR_LEN_IOCTL);
+ 			break;
+ #if defined(ARPHRD_PPP)
+ 		case ARPHRD_PPP:
+ 			if (local_family != AF_INET6)
+-				log_fatal("Unsupported device type %d for \"%s\"",
+-				           sa->sa_family, name);
++				log_fatal("local_family != AF_INET6 for \"%s\"",
++					  name);
+ 			hw->hlen = 0;
+ 			hw->hbuf[0] = HTYPE_RESERVED;
+ 			/* 0xdeadbeef should never occur on the wire,
+@@ -580,10 +809,13 @@ get_hw_addr(const char *name, struct hardware *hw) {
+ 			break;
+ #endif
+ 		default:
+-			log_fatal("Unsupported device type %ld for \"%s\"",
+-				  (long int)sa->sa_family, name);
++			freeifaddrs(ifaddrs);
++			log_fatal("Unsupported device type %hu for \"%s\"",
++				  sll->sll_hatype, name);
+ 	}
+ 
+-	close(sock);
++	if (sll_allocated)
++		dfree(sll, MDL);
++	freeifaddrs(ifaddrs);
+ }
+ #endif
+diff --git a/common/socket.c b/common/socket.c
+index 483eb9c..6e1caac 100644
+--- a/common/socket.c
++++ b/common/socket.c
+@@ -350,7 +350,7 @@ void if_register_send (info)
+ 	info->wfdesc = if_register_socket(info, AF_INET, 0, NULL);
+ 	/* If this is a normal IPv4 address, get the hardware address. */
+ 	if (strcmp(info->name, "fallback") != 0)
+-		get_hw_addr(info->name, &info->hw_address);
++		get_hw_addr(info);
+ #if defined (USE_SOCKET_FALLBACK)
+ 	/* Fallback only registers for send, but may need to receive as
+ 	   well. */
+@@ -413,7 +413,7 @@ void if_register_receive (info)
+ #endif /* IP_PKTINFO... */
+ 	/* If this is a normal IPv4 address, get the hardware address. */
+ 	if (strcmp(info->name, "fallback") != 0)
+-		get_hw_addr(info->name, &info->hw_address);
++		get_hw_addr(info);
+ 
+ 	if (!quiet_interface_discovery)
+ 		log_info ("Listening on Socket/%s%s%s",
+@@ -567,7 +567,7 @@ if_register6(struct interface_info *info, int do_multicast) {
+ 	if (req_multi)
+ 		if_register_multicast(info);
+ 
+-	get_hw_addr(info->name, &info->hw_address);
++	get_hw_addr(info);
+ 
+ 	if (!quiet_interface_discovery) {
+ 		if (info->shared_network != NULL) {
+@@ -623,7 +623,7 @@ if_register_linklocal6(struct interface_info *info) {
+ 	info->rfdesc = sock;
+ 	info->wfdesc = sock;
+ 
+-	get_hw_addr(info->name, &info->hw_address);
++	get_hw_addr(info);
+ 
+ 	if (!quiet_interface_discovery) {
+ 		if (info->shared_network != NULL) {
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index faa9251..0c1a0aa 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -485,6 +485,9 @@ struct packet {
+ 
+ #define HARDWARE_ADDR_LEN 20
+ 
++/* ioctl limits hardware addresses to 8 bytes */
++#define HARDWARE_ADDR_LEN_IOCTL	8
++
+ struct hardware {
+ 	u_int8_t hlen;
+ 	u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
+@@ -1365,6 +1368,7 @@ struct interface_info {
+ 	struct shared_network *shared_network;
+ 				/* Networks connected to this interface. */
+ 	struct hardware hw_address;	/* Its physical address. */
++	u_int8_t bcast_addr[20];	/* Infiniband broadcast address */
+ 	struct in_addr *addresses;	/* Addresses associated with this
+ 					 * interface.
+ 					 */
+@@ -2633,7 +2637,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
+ #endif
+ const char *print_time(TIME);
+ 
+-void get_hw_addr(const char *name, struct hardware *hw);
++void get_hw_addr(struct interface_info *info);
+ char *buf_to_hex (const unsigned char *s, unsigned len,
+                    const char *file, int line);
+ char *format_lease_id(const unsigned char *s, unsigned len, int format,
+-- 
+2.26.2
+
diff --git a/SOURCES/0015-Add-GUID-DUID-to-dhcpd-logs-1064416.patch b/SOURCES/0015-Add-GUID-DUID-to-dhcpd-logs-1064416.patch
new file mode 100644
index 0000000..1f88d7d
--- /dev/null
+++ b/SOURCES/0015-Add-GUID-DUID-to-dhcpd-logs-1064416.patch
@@ -0,0 +1,332 @@
+From 3d3e442ed1316930a5360e4d5a56b46a42a29419 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:35:47 +0100
+Subject: [PATCH 15/26] Add GUID/DUID to dhcpd logs (#1064416)
+Cc: pzhukov@redhat.com
+
+---
+ client/dhclient.c | 75 ++++++++++++++++++++++++++++++++++++++++++----------
+ server/dhcp.c     | 78 +++++++++++++++++++++++++++++++++----------------------
+ 2 files changed, 108 insertions(+), 45 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index dc9080e..8e57da9 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1170,6 +1170,26 @@ main(int argc, char **argv) {
+ 		}
+ 	}
+ 
++	/* We create a backup seed before rediscovering interfaces in order to
++	   have a seed built using all of the available interfaces
++	   It's interesting if required interfaces doesn't let us defined
++	   a really unique seed due to a lack of valid HW addr later
++	   (this is the case with DHCP over IB)
++	   We only use the last device as using a sum could broke the
++	   uniqueness of the seed among multiple nodes
++	 */
++	unsigned backup_seed = 0;
++	for (ip = interfaces; ip; ip = ip -> next) {
++		int junk;
++		if ( ip -> hw_address.hlen <= sizeof seed )
++		  continue;
++		memcpy (&junk,
++			&ip -> hw_address.hbuf [ip -> hw_address.hlen -
++						sizeof seed], sizeof seed);
++		backup_seed = junk;
++	}
++
++
+ 	/* At this point, all the interfaces that the script thinks
+ 	   are relevant should be running, so now we once again call
+ 	   discover_interfaces(), and this time ask it to actually set
+@@ -1184,14 +1204,36 @@ main(int argc, char **argv) {
+ 	   Not much entropy, but we're booting, so we're not likely to
+ 	   find anything better. */
+ 	seed = 0;
++	int seed_flag = 0;
+ 	for (ip = interfaces; ip; ip = ip->next) {
+ 		int junk;
++		if ( ip -> hw_address.hlen <= sizeof seed )
++		  continue;
+ 		memcpy(&junk,
+ 		       &ip->hw_address.hbuf[ip->hw_address.hlen -
+ 					    sizeof seed], sizeof seed);
+ 		seed += junk;
++		seed_flag = 1;
+ 	}
+-	srandom(seed + cur_time + (unsigned)getpid());
++	if ( seed_flag == 0 ) {
++		if ( backup_seed != 0 ) {
++		  seed = backup_seed;
++		  log_info ("xid: rand init seed (0x%x) built using all"
++			    " available interfaces",seed);
++		}
++		else {
++		  seed = cur_time^((unsigned) gethostid()) ;
++		  log_info ("xid: warning: no netdev with useable HWADDR found"
++			    " for seed's uniqueness enforcement");
++		  log_info ("xid: rand init seed (0x%x) built using gethostid",
++			    seed);
++		}
++		/* we only use seed and no current time as a broadcast reply */
++		/* will certainly be used by the hwaddrless interface */
++		srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
++	}
++	else
++	        srandom(seed + ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid());
+ 
+ 	/* Setup specific Infiniband options */
+ 	for (ip = interfaces; ip; ip = ip->next) {
+@@ -1746,10 +1788,10 @@ void dhcpack (packet)
+ #endif
+ 		return;
+ 	}
+-
+-	log_info ("DHCPACK of %s from %s",
+-		  inet_ntoa(packet->raw->yiaddr),
+-		  piaddr (packet->client_addr));
++	log_info ("DHCPACK of %s from %s (xid=0x%x)",
++                  inet_ntoa(packet->raw->yiaddr),
++                  piaddr (packet -> client_addr),
++                  ntohl(client -> xid));
+ 
+ 	lease = packet_to_lease (packet, client);
+ 	if (!lease) {
+@@ -2669,7 +2711,7 @@ void dhcpnak (packet)
+ 		return;
+ 	}
+ 
+-	log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
++	log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
+ 
+ 	if (!client -> active) {
+ #if defined (DEBUG)
+@@ -2802,10 +2844,10 @@ void send_discover (cpp)
+ 			  (long)(client -> interval));
+ 	} else
+ #endif
+-	log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
++	log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
+ 	      client -> name ? client -> name : client -> interface -> name,
+ 	      inet_ntoa (sockaddr_broadcast.sin_addr),
+-	      ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
++	      ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), ntohl(client -> xid));
+ 
+ 	/* Send out a packet. */
+ #if defined(DHCPv6) && defined(DHCP4o6)
+@@ -3108,10 +3150,12 @@ void send_request (cpp)
+ 	}
+ 
+ 	strncpy(rip_buf, rip_str, sizeof(rip_buf)-1);
+-	log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf,
++	log_info ("DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
++                  rip_buf,
+ 		  client->name ? client->name : client->interface->name,
+ 		  inet_ntoa(destination.sin_addr),
+-		  ntohs (destination.sin_port));
++		  ntohs (destination.sin_port),
++                  ntohl(client -> xid));
+ 
+ #if defined(DHCPv6) && defined(DHCP4o6)
+ 	if (dhcpv4_over_dhcpv6) {
+@@ -3168,11 +3212,13 @@ void send_decline (cpp)
+ 		log_info ("DHCPDECLINE");
+ 	} else
+ #endif
+-	log_info ("DHCPDECLINE of %s on %s to %s port %d",
++	log_info ("DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",                  
+ 		  piaddr(client->requested_address),
+ 		  (client->name ? client->name : client->interface->name),
+ 		  inet_ntoa(sockaddr_broadcast.sin_addr),
+-		  ntohs(sockaddr_broadcast.sin_port));
++		  ntohs(sockaddr_broadcast.sin_port),
++                  ntohl(client -> xid));
++
+ 
+ 	/* Send out a packet. */
+ #if defined(DHCPv6) && defined(DHCP4o6)
+@@ -3231,11 +3277,12 @@ void send_release (cpp)
+ 		log_info ("DHCPRELEASE");
+ 	} else
+ #endif
+-	log_info ("DHCPRELEASE of %s on %s to %s port %d",
++	log_info ("DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
+ 		  piaddr(client->active->address),
+ 		  client->name ? client->name : client->interface->name,
+ 		  inet_ntoa (destination.sin_addr),
+-		  ntohs (destination.sin_port));
++		  ntohs (destination.sin_port),
++                  ntohl(client -> xid));
+ 
+ #if defined(DHCPv6) && defined(DHCP4o6)
+ 	if (dhcpv4_over_dhcpv6) {
+diff --git a/server/dhcp.c b/server/dhcp.c
+index 20f2a62..0582c4c 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -87,6 +87,42 @@ const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
+ 
+ static TIME leaseTimeCheck(TIME calculated, TIME alternate);
+ 
++char *print_client_identifier_from_packet (packet)
++	struct packet *packet;
++{
++	struct option_cache *oc;
++	struct data_string client_identifier;
++	char *ci;
++
++	memset (&client_identifier, 0, sizeof client_identifier);
++
++	oc = lookup_option (&dhcp_universe, packet -> options,
++			DHO_DHCP_CLIENT_IDENTIFIER);
++	if (oc &&
++	    evaluate_option_cache (&client_identifier,
++				    packet, (struct lease *)0,
++				    (struct client_state *)0,
++				    packet -> options,
++				    (struct option_state *)0,
++				    &global_scope, oc, MDL)) {
++		ci = print_hw_addr (HTYPE_INFINIBAND, client_identifier.len, client_identifier.data);
++		data_string_forget (&client_identifier, MDL);
++		return ci;
++	} else
++		return "\"no client id\"";
++}
++
++char *print_hw_addr_or_client_id (packet)
++	struct packet *packet;
++{
++	if (packet -> raw -> htype == HTYPE_INFINIBAND)
++		return print_client_identifier_from_packet (packet);
++	else
++		return print_hw_addr (packet -> raw -> htype,
++				      packet -> raw -> hlen,
++				      packet -> raw -> chaddr);
++}
++
+ void
+ dhcp (struct packet *packet) {
+ 	int ms_nulltp = 0;
+@@ -129,9 +165,7 @@ dhcp (struct packet *packet) {
+ 
+ 		log_info("%s from %s via %s: %s", s,
+ 			 (packet->raw->htype
+-			  ? print_hw_addr(packet->raw->htype,
+-					  packet->raw->hlen,
+-					  packet->raw->chaddr)
++			  ? print_hw_addr_or_client_id(packet)
+ 			  : "<no identifier>"),
+ 			 packet->raw->giaddr.s_addr
+ 			 ? inet_ntoa(packet->raw->giaddr)
+@@ -328,9 +362,7 @@ void dhcpdiscover (packet, ms_nulltp)
+ #endif
+ 	snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
+ 		 (packet -> raw -> htype
+-		  ? print_hw_addr (packet -> raw -> htype,
+-				   packet -> raw -> hlen,
+-				   packet -> raw -> chaddr)
++		  ? print_hw_addr_or_client_id (packet)
+ 		  : (lease
+ 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
+ 		     : "<no identifier>")),
+@@ -542,9 +574,7 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
+ 		 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
+ 		 piaddr (cip), smbuf,
+ 		 (packet -> raw -> htype
+-		  ? print_hw_addr (packet -> raw -> htype,
+-				   packet -> raw -> hlen,
+-				   packet -> raw -> chaddr)
++		  ? print_hw_addr_or_client_id(packet)
+ 		  : (lease
+ 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
+ 		     : "<no identifier>")),
+@@ -785,9 +815,7 @@ void dhcprelease (packet, ms_nulltp)
+ 	if ((oc = lookup_option (&dhcp_universe, packet -> options,
+ 				 DHO_DHCP_REQUESTED_ADDRESS))) {
+ 		log_info ("DHCPRELEASE from %s specified requested-address.",
+-		      print_hw_addr (packet -> raw -> htype,
+-				     packet -> raw -> hlen,
+-				     packet -> raw -> chaddr));
++		      print_hw_addr_or_client_id(packet));
+ 	}
+ 
+ 	oc = lookup_option (&dhcp_universe, packet -> options,
+@@ -879,9 +907,7 @@ void dhcprelease (packet, ms_nulltp)
+ 		 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
+ 		 cstr,
+ 		 (packet -> raw -> htype
+-		  ? print_hw_addr (packet -> raw -> htype,
+-				   packet -> raw -> hlen,
+-				   packet -> raw -> chaddr)
++		  ? print_hw_addr_or_client_id(packet)
+ 		  : (lease
+ 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
+ 		     : "<no identifier>")),
+@@ -986,9 +1012,7 @@ void dhcpdecline (packet, ms_nulltp)
+ 		 "DHCPDECLINE of %s from %s %s%s%svia %s",
+ 		 piaddr (cip),
+ 		 (packet -> raw -> htype
+-		  ? print_hw_addr (packet -> raw -> htype,
+-				   packet -> raw -> hlen,
+-				   packet -> raw -> chaddr)
++		  ? print_hw_addr_or_client_id(packet)
+ 		  : (lease
+ 		     ? print_hex_1(lease->uid_len, lease->uid, 60)
+ 		     : "<no identifier>")),
+@@ -1732,8 +1756,7 @@ void dhcpinform (packet, ms_nulltp)
+ 	/* Report what we're sending. */
+ 	snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
+ 		 (packet->raw->htype && packet->raw->hlen) ?
+-			print_hw_addr(packet->raw->htype, packet->raw->hlen,
+-				      packet->raw->chaddr) :
++			print_hw_addr_or_client_id(packet) :
+ 			"<no client hardware address>");
+ 	log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
+ 					    packet->interface->name);
+@@ -1918,9 +1941,7 @@ void nak_lease (packet, cip, network_group)
+ #endif
+ 	log_info ("DHCPNAK on %s to %s via %s",
+ 	      piaddr (*cip),
+-	      print_hw_addr (packet -> raw -> htype,
+-			     packet -> raw -> hlen,
+-			     packet -> raw -> chaddr),
++	      print_hw_addr_or_client_id(packet),
+ 	      packet -> raw -> giaddr.s_addr
+ 	      ? inet_ntoa (packet -> raw -> giaddr)
+ 	      : packet -> interface -> name);
+@@ -3936,7 +3957,7 @@ void dhcp_reply (lease)
+ 		   ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
+ 		   : "BOOTREPLY"),
+ 		  piaddr (lease -> ip_addr),
+-		  (lease -> hardware_addr.hlen
++		  (lease -> hardware_addr.hlen > 1
+ 		   ? print_hw_addr (lease -> hardware_addr.hbuf [0],
+ 				    lease -> hardware_addr.hlen - 1,
+ 				    &lease -> hardware_addr.hbuf [1])
+@@ -4497,10 +4518,7 @@ int find_lease (struct lease **lp,
+ 			if (uid_lease) {
+ 			    if (uid_lease->binding_state == FTS_ACTIVE) {
+ 				log_error ("client %s has duplicate%s on %s",
+-					   (print_hw_addr
+-					    (packet -> raw -> htype,
+-					     packet -> raw -> hlen,
+-					     packet -> raw -> chaddr)),
++					   (print_hw_addr_or_client_id(packet)),
+ 					   " leases",
+ 					   (ip_lease -> subnet ->
+ 					    shared_network -> name));
+@@ -4667,9 +4685,7 @@ int find_lease (struct lease **lp,
+ 			log_error("uid lease %s for client %s is duplicate "
+ 				  "on %s",
+ 				  piaddr(uid_lease->ip_addr),
+-				  print_hw_addr(packet->raw->htype,
+-						packet->raw->hlen,
+-						packet->raw->chaddr),
++				  print_hw_addr_or_client_id(packet),
+ 				  uid_lease->subnet->shared_network->name);
+ 
+ 			if (!packet -> raw -> ciaddr.s_addr &&
+-- 
+2.14.5
+
diff --git a/SOURCES/0016-Turn-on-creating-sending-of-DUID.patch b/SOURCES/0016-Turn-on-creating-sending-of-DUID.patch
new file mode 100644
index 0000000..bafffb5
--- /dev/null
+++ b/SOURCES/0016-Turn-on-creating-sending-of-DUID.patch
@@ -0,0 +1,126 @@
+From 2f6b827e89305adcff45288c632785ac054adb8e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:36:30 +0100
+Subject: [PATCH 16/26] Turn on creating/sending of DUID
+Cc: pzhukov@redhat.com
+
+as client identifier with DHCPv4 clients (#560361c#40, rfc4361)
+---
+ client/dhclient.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 70 insertions(+), 4 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 8e57da9..ccc98e4 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -4021,6 +4021,59 @@ write_options(struct client_state *client, struct option_state *options,
+ 	}
+ }
+ 
++int unhexchar(char c) {
++
++	if (c >= '0' && c <= '9')
++		return c - '0';
++
++	if (c >= 'a' && c <= 'f')
++		return c - 'a' + 10;
++
++	if (c >= 'A' && c <= 'F')
++		return c - 'A' + 10;
++
++	return -1;
++}
++
++isc_result_t
++read_uuid(u_int8_t* uuid) {
++	const char *id_fname = "/etc/machine-id";
++	char id[32];
++	size_t nread;
++	FILE * file = fopen( id_fname , "r");
++	if (!file) {
++		log_debug("Cannot open %s", id_fname);
++		return ISC_R_IOERROR;
++	}
++	nread = fread(id, 1, sizeof id, file);
++	fclose(file);
++
++	if (nread < 32) {
++		log_debug("Not enough data in %s", id_fname);
++		return ISC_R_IOERROR;
++	}
++	int j;
++	for (j = 0; j < 16; j++) {
++		int a, b;
++
++		a = unhexchar(id[j*2]);
++		b = unhexchar(id[j*2+1]);
++
++		if (a < 0 || b < 0) {
++			log_debug("Wrong data in %s", id_fname);
++                        return ISC_R_IOERROR;
++		}
++		uuid[j] = a << 4 | b;
++	}
++
++	/* Set UUID version to 4 --- truly random generation */
++	uuid[6] = (uuid[6] & 0x0F) | 0x40;
++	/* Set the UUID variant to DCE */
++	uuid[8] = (uuid[8] & 0x3F) | 0x80;
++
++	return ISC_R_SUCCESS;
++}
++
+ /*
+  * The "best" default DUID, since we cannot predict any information
+  * about the system (such as whether or not the hardware addresses are
+@@ -4041,6 +4094,7 @@ form_duid(struct data_string *duid, const char *file, int line)
+ 	struct interface_info *ip;
+ 	int len;
+ 	char *str;
++	u_int8_t uuid[16];
+ 
+ 	/* For now, just use the first interface on the list. */
+ 	ip = interfaces;
+@@ -4061,9 +4115,16 @@ form_duid(struct data_string *duid, const char *file, int line)
+ 	    (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+ 		log_fatal("Impossible hardware address length at %s:%d.", MDL);
+ 
+-	if (duid_type == 0)
+-		duid_type = stateless ? DUID_LL : DUID_LLT;
+-
++	if (duid_type == 0) {
++		if (read_uuid(uuid) == ISC_R_SUCCESS)
++		    duid_type = DUID_UUID;
++		else
++		    duid_type = stateless ? DUID_LL : DUID_LLT;
++	}
++	
++	if (duid_type == DUID_UUID)
++		len = 2 + sizeof (uuid);
++	else {
+ 	/*
+ 	 * 2 bytes for the 'duid type' field.
+ 	 * 2 bytes for the 'htype' field.
+@@ -4074,13 +4135,18 @@ form_duid(struct data_string *duid, const char *file, int line)
+ 	len = 4 + (ip->hw_address.hlen - 1);
+ 	if (duid_type == DUID_LLT)
+ 		len += 4;
++	}
+ 	if (!buffer_allocate(&duid->buffer, len, MDL))
+ 		log_fatal("no memory for default DUID!");
+ 	duid->data = duid->buffer->data;
+ 	duid->len = len;
+ 
++	if (duid_type == DUID_UUID) {
++		putUShort(duid->buffer->data, DUID_UUID);
++		memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
++	}
+ 	/* Basic Link Local Address type of DUID. */
+-	if (duid_type == DUID_LLT) {
++	else if (duid_type == DUID_LLT) {
+ 		putUShort(duid->buffer->data, DUID_LLT);
+ 		putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
+ 		putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
+-- 
+2.14.5
+
diff --git a/SOURCES/0017-Send-unicast-request-release-via-correct-interface.patch b/SOURCES/0017-Send-unicast-request-release-via-correct-interface.patch
new file mode 100644
index 0000000..26c8b96
--- /dev/null
+++ b/SOURCES/0017-Send-unicast-request-release-via-correct-interface.patch
@@ -0,0 +1,77 @@
+From 193c4d7631fd623efa601f52fdab6018bf8be771 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:39:36 +0100
+Subject: [PATCH 17/26] Send unicast request/release via correct interface
+Cc: pzhukov@redhat.com
+
+(#800561, #1177351)
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #30544])
+---
+ client/dhclient.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index ccc98e4..27fde69 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -3171,6 +3171,14 @@ void send_request (cpp)
+ #endif
+ 	if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
+ 	    fallback_interface) {
++#if defined(SO_BINDTODEVICE)
++		if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++			       SO_BINDTODEVICE, client->interface->name,
++			       strlen(client->interface->name)) < 0) {
++			log_error("%s:%d: Failed to bind fallback interface"
++				  " to %s: %m", MDL, client->interface->name);
++		}
++#endif
+ 		result = send_packet(fallback_interface, NULL, &client->packet,
+ 				     client->packet_length, from, &destination,
+ 				     NULL);
+@@ -3180,6 +3188,13 @@ void send_request (cpp)
+ 				  client->packet_length,
+ 				  fallback_interface->name);
+ 		}
++#if defined(SO_BINDTODEVICE)
++		if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++			       SO_BINDTODEVICE, NULL, 0) < 0) {
++			log_fatal("%s:%d: Failed to unbind fallback interface:"
++				  " %m", MDL);
++		}
++#endif
+         }
+ 	else {
+ 		/* Send out a packet. */
+@@ -3297,6 +3312,14 @@ void send_release (cpp)
+ 	} else
+ #endif
+ 	if (fallback_interface) {
++#if defined(SO_BINDTODEVICE)
++		if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++			       SO_BINDTODEVICE, client->interface->name,
++			       strlen(client->interface->name)) < 0) {
++			log_error("%s:%d: Failed to bind fallback interface"
++				  " to %s: %m", MDL, client->interface->name);
++		}
++#endif
+ 		result = send_packet(fallback_interface, NULL, &client->packet,
+ 				      client->packet_length, from, &destination,
+ 				      NULL);
+@@ -3306,6 +3329,13 @@ void send_release (cpp)
+ 				  client->packet_length,
+ 				  fallback_interface->name);
+ 		}
++#if defined(SO_BINDTODEVICE)
++		if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++			       SO_BINDTODEVICE, NULL, 0) < 0) {
++			log_fatal("%s:%d: Failed to unbind fallback interface:"
++				  " %m", MDL);
++		}
++#endif
+         } else {
+ 		/* Send out a packet. */
+ 		result = send_packet(client->interface, NULL, &client->packet,
+-- 
+2.14.5
+
diff --git a/SOURCES/0018-No-subnet-declaration-for-iface-should-be-info-not-e.patch b/SOURCES/0018-No-subnet-declaration-for-iface-should-be-info-not-e.patch
new file mode 100644
index 0000000..2ff4030
--- /dev/null
+++ b/SOURCES/0018-No-subnet-declaration-for-iface-should-be-info-not-e.patch
@@ -0,0 +1,63 @@
+From 2277d041692b8ebdf6b86d41e3a0bc0381cd1e47 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:40:51 +0100
+Subject: [PATCH 18/26] No subnet declaration for <iface>' should be info, not
+ error.
+Cc: pzhukov@redhat.com
+
+---
+ common/discover.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/common/discover.c b/common/discover.c
+index 65881fc..056342c 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -801,9 +801,9 @@ discover_interfaces(int state) {
+ 
+ 		/* We must have a subnet declaration for each interface. */
+ 		if (!tmp->shared_network && (state == DISCOVER_SERVER)) {
+-			log_error("%s", "");
++			log_info("%s", "");
+ 			if (local_family == AF_INET) {
+-				log_error("No subnet declaration for %s (%s).",
++				log_info("No subnet declaration for %s (%s).",
+ 					  tmp->name, 
+ 					  (tmp->addresses == NULL) ?
+ 					   "no IPv4 addresses" :
+@@ -818,26 +818,26 @@ discover_interfaces(int state) {
+ 				} else {
+ 					strcpy(abuf, "no IPv6 addresses");
+ 				}
+-				log_error("No subnet6 declaration for %s (%s).",
++				log_info("No subnet6 declaration for %s (%s).",
+ 					  tmp->name,
+ 					  abuf);
+ #endif /* DHCPv6 */
+ 			}
+ 			if (supports_multiple_interfaces(tmp)) {
+-				log_error ("** Ignoring requests on %s.  %s",
++				log_info ("** Ignoring requests on %s.  %s",
+ 					   tmp -> name, "If this is not what");
+-				log_error ("   you want, please write %s",
++				log_info ("   you want, please write %s",
+ #ifdef DHCPv6
+ 				           (local_family != AF_INET) ?
+ 					   "a subnet6 declaration" :
+ #endif
+ 					   "a subnet declaration");
+-				log_error ("   in your dhcpd.conf file %s",
++				log_info ("   in your dhcpd.conf file %s",
+ 					   "for the network segment");
+-				log_error ("   to %s %s %s",
++				log_info ("   to %s %s %s",
+ 					   "which interface",
+ 					   tmp -> name, "is attached. **");
+-				log_error ("%s", "");
++				log_info ("%s", "");
+ 				goto next;
+ 			} else {
+ 				log_error ("You must write a %s",
+-- 
+2.14.5
+
diff --git a/SOURCES/0019-dhclient-write-DUID_LLT-even-in-stateless-mode-11563.patch b/SOURCES/0019-dhclient-write-DUID_LLT-even-in-stateless-mode-11563.patch
new file mode 100644
index 0000000..3405ea1
--- /dev/null
+++ b/SOURCES/0019-dhclient-write-DUID_LLT-even-in-stateless-mode-11563.patch
@@ -0,0 +1,29 @@
+From 6ea56e988df1da51f7d0bdd8984b38e40102c17b Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:41:14 +0100
+Subject: [PATCH 19/26] dhclient: write DUID_LLT even in stateless mode
+ (#1156356)
+Cc: pzhukov@redhat.com
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #38144])
+---
+ client/dhclient.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 27fde69..4e5546a 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1442,6 +1442,9 @@ void run_stateless(int exit_mode, u_int16_t port)
+ 			data_string_forget(&default_duid, MDL);
+ 
+ 		form_duid(&default_duid, MDL);
++		if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS &&
++		    duid_type == DUID_LLT)
++			write_duid(&default_duid);
+ 	}
+ 
+ #ifdef DHCP4o6
+-- 
+2.14.5
+
diff --git a/SOURCES/0020-Discover-all-hwaddress-for-xid-uniqueness.patch b/SOURCES/0020-Discover-all-hwaddress-for-xid-uniqueness.patch
new file mode 100644
index 0000000..c838d7a
--- /dev/null
+++ b/SOURCES/0020-Discover-all-hwaddress-for-xid-uniqueness.patch
@@ -0,0 +1,101 @@
+From 01ce61b8a0331a2f068ca2191bfb897b505c1b9d Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:42:50 +0100
+Subject: [PATCH 20/26] Discover all hwaddress for xid uniqueness
+Cc: pzhukov@redhat.com
+
+---
+ common/discover.c |  2 ++
+ common/lpf.c      | 27 ++++++++++++++++++++++-----
+ includes/dhcpd.h  |  3 +++
+ 3 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/common/discover.c b/common/discover.c
+index 056342c..e66e1c5 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -648,6 +648,8 @@ discover_interfaces(int state) {
+ 			interface_dereference(&tmp, MDL);
+ 			tmp = interfaces; /* XXX */
+ 		}
++		if (tmp != NULL)
++			try_hw_addr(tmp);
+ 
+ 		if (dhcp_interface_discovery_hook) {
+ 			(*dhcp_interface_discovery_hook)(tmp);
+diff --git a/common/lpf.c b/common/lpf.c
+index b732a86..a708a5d 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -699,8 +699,22 @@ ioctl_get_ll(char *name)
+ 	return sll;
+ }
+ 
++// define ? 
++void try_hw_addr(struct interface_info *info){
++  get_hw_addr2(info);
++};
++
+ void
+ get_hw_addr(struct interface_info *info)
++{
++  if (get_hw_addr2(info) == ISC_R_NOTFOUND){
++    log_fatal("Unsupported device type for \"%s\"",
++              info->name);
++  }
++}
++
++isc_result_t
++get_hw_addr2(struct interface_info *info)
+ {
+ 	struct hardware *hw = &info->hw_address;
+ 	char *name = info->name;
+@@ -710,7 +724,8 @@ get_hw_addr(struct interface_info *info)
+ 	int sll_allocated = 0;
+ 	char *dup = NULL;
+ 	char *colon = NULL;
+-
++        isc_result_t result = ISC_R_SUCCESS;
++        
+ 	if (getifaddrs(&ifaddrs) == -1)
+ 		log_fatal("Failed to get interfaces");
+ 
+@@ -794,14 +809,16 @@ get_hw_addr(struct interface_info *info)
+ 			hw->hbuf[4] = 0xef;
+ 			break;
+ #endif
+-		default:
+-			freeifaddrs(ifaddrs);
+-			log_fatal("Unsupported device type %hu for \"%s\"",
+-				  sll->sll_hatype, name);
++        default:
++          log_error("Unsupported device type %hu for \"%s\"",
++                      sll->sll_hatype, name);
++          result = ISC_R_NOTFOUND;
++
+ 	}
+ 
+ 	if (sll_allocated)
+ 		dfree(sll, MDL);
+ 	freeifaddrs(ifaddrs);
++        return result;
+ }
+ #endif
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 0c1a0aa..635c510 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -2637,7 +2637,10 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
+ #endif
+ const char *print_time(TIME);
+ 
++
+ void get_hw_addr(struct interface_info *info);
++void try_hw_addr(struct interface_info *info);
++isc_result_t get_hw_addr2(struct interface_info *info);
+ char *buf_to_hex (const unsigned char *s, unsigned len,
+                    const char *file, int line);
+ char *format_lease_id(const unsigned char *s, unsigned len, int format,
+-- 
+2.14.5
+
diff --git a/SOURCES/0021-Load-leases-DB-in-non-replay-mode-only.patch b/SOURCES/0021-Load-leases-DB-in-non-replay-mode-only.patch
new file mode 100644
index 0000000..d398918
--- /dev/null
+++ b/SOURCES/0021-Load-leases-DB-in-non-replay-mode-only.patch
@@ -0,0 +1,50 @@
+commit 50c2b3ba8ce030a47b55dd707bb8a6ab20444a05
+Author: Pavel Zhukov <pzhukov@redhat.com>
+Date:   Thu Feb 21 10:44:06 2019 +0100
+
+    Load leases DB in non-replay mode only
+
+diff --git a/server/confpars.c b/server/confpars.c
+index 2743979..6b61964 100644
+--- a/server/confpars.c
++++ b/server/confpars.c
+@@ -134,6 +134,11 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ 
+ 	cfile = (struct parse *)0;
+ #if defined (TRACING)
++	// No need to dmalloc huge memory region if we're not going to re-play
++	if (!trace_record()){
++		status = new_parse(&cfile, file, NULL, 0, filename, 0);
++		goto noreplay;
++	};
+ 	flen = lseek (file, (off_t)0, SEEK_END);
+ 	if (flen < 0) {
+ 	      boom:
+@@ -165,7 +170,6 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ 	if (result != ulen)
+ 		log_fatal ("%s: short read of %d bytes instead of %d.",
+ 			   filename, ulen, result);
+-	close (file);
+       memfile:
+ 	/* If we're recording, write out the filename and file contents. */
+ 	if (trace_record ())
+@@ -174,6 +178,9 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ #else
+ 	status = new_parse(&cfile, file, NULL, 0, filename, 0);
+ #endif
++      noreplay:
++	if (!trace_playback())
++		close (file);
+ 	if (status != ISC_R_SUCCESS || cfile == NULL)
+ 		return status;
+ 
+@@ -183,7 +190,8 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ 		status = conf_file_subparse (cfile, group, group_type);
+ 	end_parse (&cfile);
+ #if defined (TRACING)
+-	dfree (dbuf, MDL);
++	if (trace_record())
++	    dfree (dbuf, MDL);
+ #endif
+ 	return status;
+ }
diff --git a/SOURCES/0022-dhclient-make-sure-link-local-address-is-ready-in-st.patch b/SOURCES/0022-dhclient-make-sure-link-local-address-is-ready-in-st.patch
new file mode 100644
index 0000000..85ea650
--- /dev/null
+++ b/SOURCES/0022-dhclient-make-sure-link-local-address-is-ready-in-st.patch
@@ -0,0 +1,80 @@
+From 9975d198a2c02e32c31c3e0f43d2aa79dfa7f508 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 28 Feb 2019 15:30:21 +0100
+Subject: [PATCH 22/26] dhclient: make sure link-local address is ready in
+ stateless mode
+Cc: pzhukov@redhat.com
+
+Bug-url: https://bugzilla.redhat.com/1263466
+---
+ client/dhclient.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 4e5546a..9b65438 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -937,6 +937,12 @@ main(int argc, char **argv) {
+ 
+ 	inaddr_any.s_addr = INADDR_ANY;
+ 
++	/* Discover all the network interfaces. */
++	discover_interfaces(DISCOVER_UNCONFIGURED);
++
++	/* Parse the dhclient.conf file. */
++	read_client_conf();
++
+ 	/* Stateless special case. */
+ 	if (stateless) {
+ 		if (release_mode || (wanted_ia_na > 0) ||
+@@ -953,12 +959,6 @@ main(int argc, char **argv) {
+ 		finish(0);
+ 	}
+ 
+-	/* Discover all the network interfaces. */
+-	discover_interfaces(DISCOVER_UNCONFIGURED);
+-
+-	/* Parse the dhclient.conf file. */
+-	read_client_conf();
+-
+ 	/* Parse any extra command line configuration arguments: */
+ 	if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
+ 		arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
+@@ -1413,20 +1413,30 @@ void run_stateless(int exit_mode, u_int16_t port)
+ 	IGNORE_UNUSED(port);
+ #endif
+ 
+-	/* Discover the network interface. */
+-	discover_interfaces(DISCOVER_REQUESTED);
++	struct interface_info *ip;
+ 
+ 	if (!interfaces)
+ 		usage("No interfaces available for stateless command: %s", "-S");
+ 
+-	/* Parse the dhclient.conf file. */
+ #ifdef DHCP4o6
+ 	if (dhcpv4_over_dhcpv6) {
+ 		/* Mark we want to request IRT too! */
+ 		dhcpv4_over_dhcpv6++;
+ 	}
+ #endif
+-	read_client_conf();
++
++	for (ip = interfaces; ip; ip = ip->next) {
++		if ((interfaces_requested > 0) &&
++		    ((ip->flags & (INTERFACE_REQUESTED |
++				   INTERFACE_AUTOMATIC)) !=
++		     INTERFACE_REQUESTED))
++			continue;
++		script_init(ip->client, "PREINIT6", NULL);
++		script_go(ip->client);
++	}
++
++	/* Discover the network interface. */
++	discover_interfaces(DISCOVER_REQUESTED);
+ 
+ 	/* Parse the lease database. */
+ 	read_client_leases();
+-- 
+2.14.5
+
diff --git a/SOURCES/0023-option-97-pxe-client-id.patch b/SOURCES/0023-option-97-pxe-client-id.patch
new file mode 100644
index 0000000..6cc4328
--- /dev/null
+++ b/SOURCES/0023-option-97-pxe-client-id.patch
@@ -0,0 +1,247 @@
+From 6fd7894ea57791c8eee16c21d19da34b909e016e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 28 Feb 2019 16:40:38 +0100
+Subject: [PATCH 23/26] option 97 - pxe-client-id
+Cc: pzhukov@redhat.com
+
+Bug-url: https://bugzilla.redhat.com/1058674
+ISC-Bugs #38110
+---
+ common/options.c        | 27 ++++++++++++++++++++-------
+ common/tables.c         |  3 ++-
+ includes/dhcp.h         |  1 +
+ server/dhcp.c           | 19 +++++++++++++++++++
+ server/dhcpd.conf.5     |  9 ++++++---
+ server/dhcpleasequery.c | 18 +++++++++++++++---
+ server/failover.c       |  3 +++
+ server/mdb.c            |  5 +++--
+ 8 files changed, 69 insertions(+), 16 deletions(-)
+
+diff --git a/common/options.c b/common/options.c
+index 3034cf0..686dd12 100644
+--- a/common/options.c
++++ b/common/options.c
+@@ -4465,13 +4465,26 @@ int validate_packet(struct packet *packet)
+ 				"a future version of ISC DHCP will reject this");
+ 		}
+ 	} else {
+-		/*
+-		 * If hlen is 0 we don't have any identifier, we warn the user
+-		 * but continue processing the packet as we can.
+-		 */
+-		if (packet->raw->hlen == 0) {
+-			log_debug("Received DHCPv4 packet without client-id"
+-				  " option and empty hlen field.");
++		oc = lookup_option (&dhcp_universe, packet->options,
++				    DHO_PXE_CLIENT_ID);
++		if (oc) {
++			/* Let's check if pxe-client-id is sane */
++			if ((oc->data.len < 2) ||
++			    (oc->data.data[0] == '\0' &&
++			     oc->data.len != 17)) {
++				log_debug("Dropped DHCPv4 packet with wrong "
++				    "(len == %d) pxe-client-id", oc->data.len);
++				return (0);
++			}
++		} else {
++			/*
++			 * If hlen is 0 we don't have any identifier, we warn the user
++			 * but continue processing the packet as we can.
++			 */
++			if (packet->raw->hlen == 0) {
++				log_debug("Received DHCPv4 packet without client-id"
++						" option and empty hlen field.");
++			}
+ 		}
+ 	}
+ 
+diff --git a/common/tables.c b/common/tables.c
+index f1be07d..4419220 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -196,8 +196,9 @@ static struct option dhcp_options[] = {
+ 	/* Defined by RFC 4578 */
+ 	{ "pxe-system-type", "Sa",		&dhcp_universe,  93, 1 },
+ 	{ "pxe-interface-id", "BBB",		&dhcp_universe,  94, 1 },
+-	{ "pxe-client-id", "BX",		&dhcp_universe,  97, 1 },
+ #endif
++	{ "pxe-client-id", "BX",		&dhcp_universe,  97, 1 },
++
+ 	{ "uap-servers", "t",			&dhcp_universe,  98, 1 },
+ #if defined(RFC4776_OPTIONS)
+         { "geoconf-civic", "X",                 &dhcp_universe, 99, 1 },
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index 4cc547a..4eb9791 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -158,6 +158,7 @@ struct dhcp_packet {
+ #define DHO_AUTHENTICATE			90  /* RFC3118, was 210 */
+ #define DHO_CLIENT_LAST_TRANSACTION_TIME	91
+ #define DHO_ASSOCIATED_IP			92
++#define DHO_PXE_CLIENT_ID			97  /* RFC4578 */
+ #define DHO_SUBNET_SELECTION			118 /* RFC3011! */
+ #define DHO_DOMAIN_SEARCH			119 /* RFC3397 */
+ #define DHO_CLASSLESS_STATIC_ROUTES		121 /* RFC3442 */
+diff --git a/server/dhcp.c b/server/dhcp.c
+index 0582c4c..4e86262 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -222,6 +222,10 @@ dhcp (struct packet *packet) {
+ 		if (lease -> uid_len) {
+ 			oc = lookup_option (&dhcp_universe, packet -> options,
+ 					    DHO_DHCP_CLIENT_IDENTIFIER);
++			if (!oc)
++				oc = lookup_option (&dhcp_universe,
++						    packet -> options,
++						    DHO_PXE_CLIENT_ID);
+ 			if (!oc)
+ 				goto nolease;
+ 
+@@ -820,6 +824,9 @@ void dhcprelease (packet, ms_nulltp)
+ 
+ 	oc = lookup_option (&dhcp_universe, packet -> options,
+ 			    DHO_DHCP_CLIENT_IDENTIFIER);
++	if (!oc)
++		oc = lookup_option (&dhcp_universe, packet -> options,
++				    DHO_PXE_CLIENT_ID);
+ 	memset (&data, 0, sizeof data);
+ 	if (oc &&
+ 	    evaluate_option_cache (&data, packet, (struct lease *)0,
+@@ -1331,6 +1338,9 @@ void dhcpinform (packet, ms_nulltp)
+          */
+ 	oc = lookup_option(&dhcp_universe, packet->options,
+ 			   DHO_DHCP_CLIENT_IDENTIFIER);
++	if (!oc)
++		oc = lookup_option (&dhcp_universe, packet -> options,
++				    DHO_PXE_CLIENT_ID);
+ 	memset(&d1, 0, sizeof(d1));
+ 	if (oc &&
+ 	    evaluate_option_cache(&d1, packet, NULL, NULL,
+@@ -2441,6 +2451,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
+ 		   can be used. */
+ 		oc = lookup_option (&dhcp_universe, packet -> options,
+ 				    DHO_DHCP_CLIENT_IDENTIFIER);
++		if (!oc)
++			oc = lookup_option (&dhcp_universe, packet -> options,
++					    DHO_PXE_CLIENT_ID);
+ 		if (oc &&
+ 		    evaluate_option_cache (&d1, packet, lease,
+ 					   (struct client_state *)0,
+@@ -3033,6 +3046,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
+ 		/* Record the uid, if given... */
+ 		oc = lookup_option (&dhcp_universe, packet -> options,
+ 				    DHO_DHCP_CLIENT_IDENTIFIER);
++		if (!oc)
++			oc = lookup_option (&dhcp_universe, packet -> options,
++					    DHO_PXE_CLIENT_ID);
+ 		if (oc &&
+ 		    evaluate_option_cache(&d1, packet, lease, NULL,
+ 					  packet->options, state->options,
+@@ -4150,6 +4166,9 @@ int find_lease (struct lease **lp,
+ 	   specified unique client identifier. */
+ 	oc = lookup_option (&dhcp_universe, packet -> options,
+ 			    DHO_DHCP_CLIENT_IDENTIFIER);
++	if (!oc)
++		oc = lookup_option (&dhcp_universe, packet -> options,
++				    DHO_PXE_CLIENT_ID);
+ 	memset (&client_identifier, 0, sizeof client_identifier);
+ 	if (oc &&
+ 	    evaluate_option_cache (&client_identifier,
+diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
+index 89b5540..4751a8b 100644
+--- a/server/dhcpd.conf.5
++++ b/server/dhcpd.conf.5
+@@ -1664,10 +1664,12 @@ should be a name identifying the host.  If a \fIhostname\fR option is
+ not specified for the host, \fIhostname\fR is used.
+ .PP
+ \fIHost\fR declarations are matched to actual DHCP or BOOTP clients
+-by matching the \fRdhcp-client-identifier\fR option specified in the
++by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR
++options specified in the
+ \fIhost\fR declaration to the one supplied by the client, or, if the
+ \fIhost\fR declaration or the client does not provide a
+-\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR
++\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options,
++by matching the \fIhardware\fR
+ parameter in the \fIhost\fR declaration to the network hardware
+ address supplied by the client.  BOOTP clients do not normally
+ provide a \fIdhcp-client-identifier\fR, so the hardware address must
+@@ -1679,7 +1681,8 @@ to identify hosts.
+ .PP
+ Please be aware that
+ .B only
+-the \fIdhcp-client-identifier\fR option and the hardware address can be
++the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR
++options and the hardware address can be
+ used to match a host declaration, or the \fIhost-identifier option\fR
+ parameter for DHCPv6 servers.  For example, it is not possible to
+ match a host declaration to a \fIhost-name\fR option.  This is
+diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c
+index 7be0788..2fee698 100644
+--- a/server/dhcpleasequery.c
++++ b/server/dhcpleasequery.c
+@@ -276,7 +276,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
+ 		 */
+ 
+ 		memset(&uid, 0, sizeof(uid));
+-		if (get_option(&uid, 
++		i = get_option(&uid,
+ 			       &dhcp_universe,
+ 			       packet,
+ 			       NULL,
+@@ -286,8 +286,20 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
+ 			       packet->options, 
+ 			       &global_scope,
+ 			       DHO_DHCP_CLIENT_IDENTIFIER,
+-			       MDL)) {
+-
++			       MDL);
++		if (!i)
++			i = get_option(&uid,
++				       &dhcp_universe,
++				       packet,
++				       NULL,
++				       NULL,
++				       packet->options,
++				       NULL,
++				       packet->options,
++				       &global_scope,
++				       DHO_PXE_CLIENT_ID,
++				       MDL);
++		if (i) {
+ 			snprintf(dbg_info, 
+ 				 sizeof(dbg_info), 
+ 				 "client-id %s",
+diff --git a/server/failover.c b/server/failover.c
+index 72f7b00..40fa691 100644
+--- a/server/failover.c
++++ b/server/failover.c
+@@ -5988,6 +5988,9 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state)
+ 
+ 	oc = lookup_option(&dhcp_universe, packet->options,
+ 			   DHO_DHCP_CLIENT_IDENTIFIER);
++	if (!oc)
++		oc = lookup_option(&dhcp_universe, packet -> options,
++				    DHO_PXE_CLIENT_ID);
+ 	memset(&ds, 0, sizeof ds);
+ 	if (oc &&
+ 	    evaluate_option_cache(&ds, packet, NULL, NULL,
+diff --git a/server/mdb.c b/server/mdb.c
+index 052df67..8851366 100644
+--- a/server/mdb.c
++++ b/server/mdb.c
+@@ -129,8 +129,9 @@ static int find_uid_statement (struct executable_statement *esp,
+ 	    esp -> data.option &&
+ 	    (esp -> data.option -> option -> universe ==
+ 	     &dhcp_universe) &&
+-	    (esp -> data.option -> option -> code ==
+-	     DHO_DHCP_CLIENT_IDENTIFIER)) {
++	    ((esp -> data.option -> option -> code ==
++						DHO_DHCP_CLIENT_IDENTIFIER) ||
++	     (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) {
+ 		if (condp) {
+ 			log_error ("dhcp client identifier may not be %s",
+ 				   "specified conditionally.");
+-- 
+2.14.5
+
diff --git a/SOURCES/0024-Detect-system-time-changes.patch b/SOURCES/0024-Detect-system-time-changes.patch
new file mode 100644
index 0000000..cf38d0d
--- /dev/null
+++ b/SOURCES/0024-Detect-system-time-changes.patch
@@ -0,0 +1,93 @@
+From 41c6032ace65119e6a400365f7e90283c930afd4 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Oct 2019 16:23:01 +0200
+Subject: [PATCH 24/26] Detect system time changes
+Cc: pzhukov@redhat.com
+
+---
+ client/dhclient.c |  6 ++++++
+ common/dispatch.c | 11 ++++++++++-
+ includes/dhcpd.h  |  3 ++-
+ server/dhcpd.c    |  6 ++++++
+ 4 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 9b65438..44d508a 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -5408,6 +5408,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ 		  case server_awaken:
+ 		    state_reboot (client);
+ 		    break;
++
++                  case server_time_changed:
++                    if (client->active){
++                      state_reboot (client);
++                    }
++                    break;
+ 		}
+ 	    }
+ 	}
+diff --git a/common/dispatch.c b/common/dispatch.c
+index d7fe200..8a24499 100644
+--- a/common/dispatch.c
++++ b/common/dispatch.c
+@@ -118,7 +118,6 @@ dispatch(void)
+ 		 * signal. It will return ISC_R_RELOAD in that
+ 		 * case. That is a normal behavior.
+ 		 */
+-
+ 		if (status == ISC_R_RELOAD) {
+ 			/*
+ 			 * dhcp_set_control_state() will do the job.
+@@ -129,6 +128,16 @@ dispatch(void)
+ 			if (status == ISC_R_SUCCESS)
+ 				status = ISC_R_RELOAD;
+ 		}
++
++                
++                if (status == ISC_R_TIMESHIFTED){
++                  status = dhcp_set_control_state(server_time_changed,
++                                                  server_time_changed);
++                  status = ISC_R_RELOAD;
++                  log_info ("System time has been changed. Unable to use existing leases. Restarting");
++                  // do nothing, restart context
++                };
++
+ 	} while (status == ISC_R_RELOAD);
+ 
+ 	log_fatal ("Dispatch routine failed: %s -- exiting",
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 635c510..ec6c227 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -524,7 +524,8 @@ typedef enum {
+ 	server_running = 1,
+ 	server_shutdown = 2,
+ 	server_hibernate = 3,
+-	server_awaken = 4
++	server_awaken = 4,
++        server_time_changed = 5
+ } control_object_state_t;
+ 
+ typedef struct {
+diff --git a/server/dhcpd.c b/server/dhcpd.c
+index 530a923..4aef16b 100644
+--- a/server/dhcpd.c
++++ b/server/dhcpd.c
+@@ -1767,6 +1767,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ {
+ 	struct timeval tv;
+ 
++        if (newstate == server_time_changed){
++          log_error ("System time has been changed. Leases information unreliable!");
++          return ISC_R_SUCCESS;
++        }
++
++                
+ 	if (newstate != server_shutdown)
+ 		return DHCP_R_INVALIDARG;
+ 	/* Re-entry. */
+-- 
+2.14.5
+
diff --git a/SOURCES/0025-bind-Detect-system-time-changes.patch b/SOURCES/0025-bind-Detect-system-time-changes.patch
new file mode 100644
index 0000000..80191b2
--- /dev/null
+++ b/SOURCES/0025-bind-Detect-system-time-changes.patch
@@ -0,0 +1,197 @@
+From ef4f5e80d8a1ea1507829ea6f5214f276478f475 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Oct 2019 16:23:24 +0200
+Subject: [PATCH 25/27] bind: Detect system time changes
+Cc: pzhukov@redhat.com
+
+---
+ bind/bind/lib/isc/include/isc/result.h    |  4 ++-
+ bind/bind/lib/isc/include/isc/util.h      |  4 +++
+ bind/bind/lib/isc/result.c                |  2 ++
+ bind/bind/lib/isc/unix/app.c              | 41 ++++++++++++++++++++++++++++---
+ bind/bind/lib/isc/unix/include/isc/time.h | 20 +++++++++++++++
+ bind/bind/lib/isc/unix/time.c             | 22 +++++++++++++++++
+ 6 files changed, 89 insertions(+), 4 deletions(-)
+
+diff --git a/bind/bind/lib/isc/include/isc/result.h b/bind/bind/lib/isc/include/isc/result.h
+index 0389efa..0e35f98 100644
+--- a/bind/bind/lib/isc/include/isc/result.h
++++ b/bind/bind/lib/isc/include/isc/result.h
+@@ -89,7 +89,9 @@
+ #define ISC_R_DISCFULL			67	/*%< disc full */
+ #define ISC_R_DEFAULT			68	/*%< default */
+ #define ISC_R_IPV4PREFIX		69	/*%< IPv4 prefix */
+-#define ISC_R_NRESULTS 			70
++#define ISC_R_TIMESHIFTED               70      /*%< system time changed */
++/*% Not a result code: the number of results. */
++#define ISC_R_NRESULTS 			71
+ 
+ ISC_LANG_BEGINDECLS
+ 
+diff --git a/bind/bind/lib/isc/include/isc/util.h b/bind/bind/lib/isc/include/isc/util.h
+index 973c348..cceeb5e 100644
+--- a/bind/bind/lib/isc/include/isc/util.h
++++ b/bind/bind/lib/isc/include/isc/util.h
+@@ -289,6 +289,10 @@ extern void mock_assert(const int result, const char* const expression,
+  * Time
+  */
+ #define TIME_NOW(tp) 	RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
++#ifdef CLOCK_BOOTTIME
++#define TIME_MONOTONIC(tp) 	RUNTIME_CHECK(isc_time_boottime((tp)) == ISC_R_SUCCESS)
++#endif
++
+ 
+ /*%
+  * Alignment
+diff --git a/bind/bind/lib/isc/result.c b/bind/bind/lib/isc/result.c
+index a9db132..7c04831 100644
+--- a/bind/bind/lib/isc/result.c
++++ b/bind/bind/lib/isc/result.c
+@@ -105,6 +105,7 @@ static const char *description[ISC_R_NRESULTS] = {
+ 	"disc full",				/*%< 67 */
+ 	"default",				/*%< 68 */
+ 	"IPv4 prefix",				/*%< 69 */
++        "time changed",                         /*%< 70 */
+ };
+ 
+ static const char *identifier[ISC_R_NRESULTS] = {
+@@ -178,6 +179,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
+ 	"ISC_R_DISCFULL",
+ 	"ISC_R_DEFAULT",
+ 	"ISC_R_IPV4PREFIX",
++        "ISC_R_TIMESHIFTED",
+ };
+ 
+ #define ISC_RESULT_RESULTSET			2
+diff --git a/bind/bind/lib/isc/unix/app.c b/bind/bind/lib/isc/unix/app.c
+index a6e9882..dbd23f7 100644
+--- a/bind/bind/lib/isc/unix/app.c
++++ b/bind/bind/lib/isc/unix/app.c
+@@ -442,15 +442,51 @@ isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task,
+ static isc_result_t
+ evloop(isc__appctx_t *ctx) {
+ 	isc_result_t result;
++        isc_time_t now;
++#ifdef CLOCK_BOOTTIME
++        isc_time_t monotonic;
++        uint64_t diff  = 0;
++#else
++        isc_time_t prev;
++        TIME_NOW(&prev);
++#endif
++
++
++
+ 
+ 	while (!ctx->want_shutdown) {
+ 		int n;
+-		isc_time_t when, now;
++		isc_time_t when;
++                
+ 		struct timeval tv, *tvp;
+ 		isc_socketwait_t *swait;
+ 		bool readytasks;
+ 		bool call_timer_dispatch = false;
+ 
++                uint64_t us; 
++
++#ifdef CLOCK_BOOTTIME
++                // TBD macros for following three lines
++                TIME_NOW(&now);
++                TIME_MONOTONIC(&monotonic);
++                INSIST(now.seconds > monotonic.seconds)
++                us = isc_time_microdiff (&now, &monotonic);
++                if (us < diff){ 
++                  us = diff - us;
++                  if (us > 1000000){ // ignoring shifts less than one second
++                    return ISC_R_TIMESHIFTED;
++                  };
++                  diff = isc_time_microdiff (&now, &monotonic);
++                } else {
++                  diff = isc_time_microdiff (&now, &monotonic);
++                  // not implemented
++                }
++#else
++                TIME_NOW(&now);
++                if (isc_time_compare (&now, &prev) < 0)
++                  return ISC_R_TIMESHIFTED;
++                TIME_NOW(&prev);
++#endif                
+ 		/*
+ 		 * Check the reload (or suspend) case first for exiting the
+ 		 * loop as fast as possible in case:
+@@ -475,9 +511,8 @@ evloop(isc__appctx_t *ctx) {
+ 			if (result != ISC_R_SUCCESS)
+ 				tvp = NULL;
+ 			else {
+-				uint64_t us;
+-
+ 				TIME_NOW(&now);
++
+ 				us = isc_time_microdiff(&when, &now);
+ 				if (us == 0)
+ 					call_timer_dispatch = true;
+diff --git a/bind/bind/lib/isc/unix/include/isc/time.h b/bind/bind/lib/isc/unix/include/isc/time.h
+index b864c29..5dd43c9 100644
+--- a/bind/bind/lib/isc/unix/include/isc/time.h
++++ b/bind/bind/lib/isc/unix/include/isc/time.h
+@@ -132,6 +132,26 @@ isc_time_isepoch(const isc_time_t *t);
+  *\li	't' is a valid pointer.
+  */
+ 
++#ifdef CLOCK_BOOTTIME
++isc_result_t
++isc_time_boottime(isc_time_t *t);
++/*%<
++ * Set 't' to monotonic time from previous boot
++ * it's not affected by system time change. It also
++ * includes the time system was suspended
++ *
++ * Requires:
++ *\li	't' is a valid pointer.
++ *
++ * Returns:
++ *
++ *\li	Success
++ *\li	Unexpected error
++ *		Getting the time from the system failed.
++ */
++#endif /* CLOCK_BOOTTIME */
++ 
++
+ isc_result_t
+ isc_time_now(isc_time_t *t);
+ /*%<
+diff --git a/bind/bind/lib/isc/unix/time.c b/bind/bind/lib/isc/unix/time.c
+index 8edc9df..fe0bb91 100644
+--- a/bind/bind/lib/isc/unix/time.c
++++ b/bind/bind/lib/isc/unix/time.c
+@@ -498,3 +498,25 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
+ 			 t->nanoseconds / NS_PER_MS);
+ 	}
+ }
++
++
++#ifdef CLOCK_BOOTTIME
++isc_result_t
++isc_time_boottime(isc_time_t *t) {
++  struct timespec ts;
++  
++  char strbuf[ISC_STRERRORSIZE];
++
++  if (clock_gettime (CLOCK_BOOTTIME, &ts) != 0){
++    isc__strerror(errno, strbuf, sizeof(strbuf));
++    UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
++    return (ISC_R_UNEXPECTED);    
++  }
++
++  t->seconds = ts.tv_sec;
++  t->nanoseconds = ts.tv_nsec;
++
++  return (ISC_R_SUCCESS);
++  
++};
++#endif
+-- 
+2.14.5
+
diff --git a/SOURCES/0026-Add-dhclient-5-B-option-description.patch b/SOURCES/0026-Add-dhclient-5-B-option-description.patch
new file mode 100644
index 0000000..7ddfacf
--- /dev/null
+++ b/SOURCES/0026-Add-dhclient-5-B-option-description.patch
@@ -0,0 +1,24 @@
+commit 6acfd3125546a0e5db8fae8a9964cd2f88bf68c0
+Author: Pavel Zhukov <pzhukov@redhat.com>
+Date:   Tue Oct 22 16:28:04 2019 +0200
+
+    Add dhclient(5) -B option description
+    
+    Bug-Url: https://bugzilla.redhat.com/1764088
+
+diff --git a/client/dhclient.8 b/client/dhclient.8
+index 0145b9f..5226de5 100644
+--- a/client/dhclient.8
++++ b/client/dhclient.8
+@@ -552,6 +552,11 @@ Path to the network configuration script invoked by
+ when it gets a lease.  If unspecified, the default
+ .B CLIENTBINDIR/dhclient-script
+ is used.  See \fBdhclient-script(8)\fR for a description of this file.
++.TP
++.BI \-B
++Always set the bootp broadcast flag in request packets, so that
++servers will always broadcast replies. This option is provided as
++an extension to enable dhclient to work on IBM s390 Linux guests.
+ .PP
+ .SH PORTS
+ During operations the client may use multiple UDP ports
diff --git a/SOURCES/0027-Add-missed-sd-notify-patch-to-manage-dhcpd-with-syst.patch b/SOURCES/0027-Add-missed-sd-notify-patch-to-manage-dhcpd-with-syst.patch
new file mode 100644
index 0000000..cde51de
--- /dev/null
+++ b/SOURCES/0027-Add-missed-sd-notify-patch-to-manage-dhcpd-with-syst.patch
@@ -0,0 +1,97 @@
+From 8d974fd1f667e1b957ad4092fe66a8bb94f5f8fd Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 7 Nov 2019 14:47:45 +0100
+Subject: [PATCH 1/1] Add missed sd notify patch to manage dhcpd with systemd
+Cc: pzhukov@redhat.com
+
+---
+ configure.ac     | 11 +++++++++++
+ relay/dhcrelay.c | 12 ++++++++++++
+ server/dhcpd.c   | 12 ++++++++++++
+ 3 files changed, 35 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index 15fc0d7..0c08000 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1014,6 +1014,17 @@ if test x$ldap = xyes || test x$ldapcrypto = xyes || test x$ldap_gssapi = xyes;
+     AC_SUBST(LDAP_CFLAGS, [$LDAP_CFLAGS])
+ fi
+ 
++AC_ARG_WITH(systemd,
++        AC_HELP_STRING([--with-systemd],
++                       [enable sending status notifications to systemd daemon (default is no)]),
++        [systemd=$withval],
++        [systemd=no])
++
++if test x$systemd = xyes ; then
++   AC_CHECK_LIB(systemd, sd_notifyf, ,
++                AC_MSG_FAILURE([*** systemd library not present - do you need to install systemd-libs package?]))
++fi
++
+ # Append selected warning levels to CFLAGS before substitution (but after
+ # AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) & etc).
+ CFLAGS="$CFLAGS $STD_CWARNINGS"
+diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
+index 7b4f4f1..9eb5bfd 100644
+--- a/relay/dhcrelay.c
++++ b/relay/dhcrelay.c
+@@ -37,6 +37,10 @@
+    int keep_capabilities = 0;
+ #endif
+ 
++#ifdef HAVE_LIBSYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+ struct tree_cache *global_options[256];
+@@ -845,6 +849,14 @@ main(int argc, char **argv) {
+ 	}
+ #endif
+ 
++#ifdef HAVE_LIBSYSTEMD
++        /* We are ready to process incomming packets. Let's notify systemd */
++        sd_notifyf(0, "READY=1\n"
++                   "STATUS=Dispatching packets...\n"
++                   "MAINPID=%lu",
++                   (unsigned long) getpid());
++#endif
++
+ 	/* Start dispatching packets and timeouts... */
+ 	dispatch();
+ 
+diff --git a/server/dhcpd.c b/server/dhcpd.c
+index 4aef16b..778ef8d 100644
+--- a/server/dhcpd.c
++++ b/server/dhcpd.c
+@@ -60,6 +60,10 @@ gid_t set_gid = 0;
+ struct class unknown_class;
+ struct class known_class;
+ 
++#ifdef HAVE_LIBSYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ struct iaddr server_identifier;
+ int server_identifier_matched;
+ 
+@@ -1057,6 +1061,14 @@ main(int argc, char **argv) {
+ 	/* Log that we are about to start working */
+ 	log_info("Server starting service.");
+ 
++#ifdef HAVE_LIBSYSTEMD
++        /* We are ready to process incomming packets. Let's notify systemd */
++        sd_notifyf(0, "READY=1\n"
++                   "STATUS=Dispatching packets...\n"
++                   "MAINPID=%lu",
++                   (unsigned long) getpid());
++#endif
++
+ 	/*
+ 	 * Receive packets and dispatch them...
+ 	 * dispatch() will never return.
+-- 
+2.14.5
+
diff --git a/SOURCES/0028-Fix-for-CVE-2021-25217.patch b/SOURCES/0028-Fix-for-CVE-2021-25217.patch
new file mode 100644
index 0000000..7f9dad9
--- /dev/null
+++ b/SOURCES/0028-Fix-for-CVE-2021-25217.patch
@@ -0,0 +1,34 @@
+From 02b4ae1953d39f1b6c3f0e63aefb72114039ab50 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Jun 2021 06:56:29 +0200
+Subject: [PATCH 28/29] Fix for  CVE-2021-25217
+Cc: pzhukov@redhat.com
+
+---
+ common/parse.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/common/parse.c b/common/parse.c
+index f17bc0b..4e8b408 100644
+--- a/common/parse.c
++++ b/common/parse.c
+@@ -5587,13 +5587,14 @@ int parse_X (cfile, buf, max)
+ 				skip_to_semi (cfile);
+ 				return 0;
+ 			}
+-			convert_num (cfile, &buf [len], val, 16, 8);
+-			if (len++ > max) {
++			if (len >= max) {
+ 				parse_warn (cfile,
+ 					    "hexadecimal constant too long.");
+ 				skip_to_semi (cfile);
+ 				return 0;
+ 			}
++			convert_num (cfile, &buf [len], val, 16, 8);
++			len++;
+ 			token = peek_token (&val, (unsigned *)0, cfile);
+ 			if (token == COLON)
+ 				token = next_token (&val,
+-- 
+2.26.3
+
diff --git a/SOURCES/0029-Use-system-getaddrinfo-for-dhcp.patch b/SOURCES/0029-Use-system-getaddrinfo-for-dhcp.patch
new file mode 100644
index 0000000..24cbb6b
--- /dev/null
+++ b/SOURCES/0029-Use-system-getaddrinfo-for-dhcp.patch
@@ -0,0 +1,118 @@
+From 019021caa791c254a319c71b4f634142dc14b37d Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Jun 2021 06:58:40 +0200
+Subject: [PATCH 29/29] Use system getaddrinfo for dhcp
+Cc: pzhukov@redhat.com
+
+---
+ bind/bind/lib/irs/include/irs/netdb.h.in | 94 ++++++++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+
+diff --git a/bind/bind/lib/irs/include/irs/netdb.h.in b/bind/bind/lib/irs/include/irs/netdb.h.in
+index 23dcd37..f36113d 100644
+--- a/bind/bind/lib/irs/include/irs/netdb.h.in
++++ b/bind/bind/lib/irs/include/irs/netdb.h.in
+@@ -149,6 +149,100 @@ struct addrinfo {
+ #define	NI_NUMERICSERV	0x00000008
+ #define	NI_DGRAM	0x00000010
+ 
++/*
++ * Define to map into irs_ namespace.
++ */
++
++#define IRS_NAMESPACE
++
++#ifdef IRS_NAMESPACE
++
++/*
++ * Use our versions not the ones from the C library.
++ */
++
++#ifdef getnameinfo
++#undef getnameinfo
++#endif
++#define getnameinfo irs_getnameinfo
++
++#ifdef getaddrinfo
++#undef getaddrinfo
++#endif
++#define getaddrinfo irs_getaddrinfo
++
++#ifdef freeaddrinfo
++#undef freeaddrinfo
++#endif
++#define freeaddrinfo irs_freeaddrinfo
++
++#ifdef gai_strerror
++#undef gai_strerror
++#endif
++#define gai_strerror irs_gai_strerror
++
++#endif
++
++extern int getaddrinfo (const char *name,
++			const char *service,
++			const struct addrinfo *req,
++			struct addrinfo **pai);
++extern int getnameinfo (const struct sockaddr *sa,
++			socklen_t salen, char *host,
++			socklen_t hostlen, char *serv,
++			socklen_t servlen, int flags);
++extern void freeaddrinfo (struct addrinfo *ai);
++extern const char *gai_strerror (int ecode);
++
++/*
++ * Define to map into irs_ namespace.
++ */
++
++#define IRS_NAMESPACE
++
++#ifdef IRS_NAMESPACE
++
++/*
++ * Use our versions not the ones from the C library.
++ */
++
++#ifdef getnameinfo
++#undef getnameinfo
++#endif
++#define getnameinfo irs_getnameinfo
++
++#ifdef getaddrinfo
++#undef getaddrinfo
++#endif
++#define getaddrinfo irs_getaddrinfo
++
++#ifdef freeaddrinfo
++#undef freeaddrinfo
++#endif
++#define freeaddrinfo irs_freeaddrinfo
++
++#ifdef gai_strerror
++#undef gai_strerror
++#endif
++#define gai_strerror irs_gai_strerror
++
++int
++getaddrinfo(const char *hostname, const char *servname,
++	    const struct addrinfo *hints, struct addrinfo **res);
++
++int
++getnameinfo(const struct sockaddr *sa, IRS_GETNAMEINFO_SOCKLEN_T salen,
++	    char *host, IRS_GETNAMEINFO_BUFLEN_T hostlen,
++	    char *serv, IRS_GETNAMEINFO_BUFLEN_T servlen,
++	    IRS_GETNAMEINFO_FLAGS_T flags);
++
++void freeaddrinfo (struct addrinfo *ai);
++
++IRS_GAISTRERROR_RETURN_T
++gai_strerror(int ecode);
++
++#endif
++
+ /*
+  * Tell Emacs to use C mode on this file.
+  * Local variables:
+-- 
+2.26.3
+
diff --git a/SOURCES/11-dhclient b/SOURCES/11-dhclient
new file mode 100644
index 0000000..8bd0c75
--- /dev/null
+++ b/SOURCES/11-dhclient
@@ -0,0 +1,37 @@
+#!/bin/bash
+# run dhclient.d scripts in an emulated environment
+
+PATH=/bin:/usr/bin:/sbin
+ETCDIR=/etc/dhcp
+SAVEDIR=/var/lib/dhclient
+interface=$1
+
+for optname in "${!DHCP4_@}"; do
+    newoptname=${optname,,};
+    newoptname=new_${newoptname#dhcp4_};
+    export "${newoptname}"="${!optname}";
+done
+
+[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
+
+[ -f /etc/sysconfig/network-scripts/ifcfg-"${interface}" ] && \
+    . /etc/sysconfig/network-scripts/ifcfg-"${interface}"
+
+if [ -d $ETCDIR/dhclient.d ]; then
+    for f in $ETCDIR/dhclient.d/*.sh; do
+        if [ -x "${f}" ]; then
+            subsystem="${f%.sh}"
+            subsystem="${subsystem##*/}"
+            . "${f}"
+            if [ "$2" = "up" ]; then
+                "${subsystem}_config"
+            elif [ "$2" = "dhcp4-change" ]; then
+                if [ "$subsystem" = "chrony" -o "$subsystem" = "ntp" ]; then
+                    "${subsystem}_config"
+                fi
+            elif [ "$2" = "down" ]; then
+                "${subsystem}_restore"
+            fi
+        fi
+    done
+fi
diff --git a/SOURCES/56dhclient b/SOURCES/56dhclient
new file mode 100644
index 0000000..7f185f1
--- /dev/null
+++ b/SOURCES/56dhclient
@@ -0,0 +1,61 @@
+#!/bin/sh
+# If we are running dhclient, shutdown running instances cleanly and
+# bring them back up on resume.
+
+. "${PM_FUNCTIONS}"
+
+PM_DHCLIENT_RUNDIR="${PM_UTILS_RUNDIR}/network"
+PM_DHCLIENT_SUSPEND="${PM_DHCLIENT_RUNDIR}/dhclient.suspend"
+
+suspend_dhclient() {
+    [ ! -d /etc/sysconfig/network-scripts ] && return
+    [ ! -x /sbin/ifdown ] && return
+
+    [ ! -d ${PM_DHCLIENT_RUNDIR} ] && /bin/mkdir -p ${PM_DHCLIENT_RUNDIR}
+    [ -f ${PM_DHCLIENT_SUSPEND} ] && /bin/rm -f ${PM_DHCLIENT_SUSPEND}
+
+    cd /etc/sysconfig/network-scripts
+    for ifcfg in ifcfg-* ; do
+        # Clear relevant parameters set by previous interface
+        # (lo doesn't set them)
+        NM_CONTROLLED=
+        BOOTPROTO=
+
+        . ./"${ifcfg}"
+
+        if [ "${NM_CONTROLLED}" = "no" ] || [ "${NM_CONTROLLED}" = "n" ] || [ "${NM_CONTROLLED}" = "false" ]; then
+            if [ "${BOOTPROTO}" = "bootp" ] || [ "${BOOTPROTO}" = "dhcp" ] || [ -z "${BOOTPROTO}" ]; then
+                # device is not NetworkManager controlled and uses dhcp,
+                # now see if it's actually up at the moment
+                /sbin/ip link show ${DEVICE} | /bin/grep -qE "state (UP|UNKNOWN)" >/dev/null 2>&1
+                if [ $? -eq 0 ]; then
+                    echo "${DEVICE}" >> ${PM_DHCLIENT_SUSPEND}
+                    /sbin/ifdown ${DEVICE}
+                fi
+            fi
+        fi
+    done
+}
+
+resume_dhclient() {
+    [ ! -f ${PM_DHCLIENT_SUSPEND} ] && return
+    [ ! -x /sbin/ifup ] && return
+
+    cd /etc/sysconfig/network-scripts
+    while read device ; do
+        /sbin/ifup ${device}
+    done < ${PM_DHCLIENT_SUSPEND}
+
+    /bin/rm -f ${PM_DHCLIENT_SUSPEND}
+}
+
+case "$1" in
+    hibernate|suspend)
+        suspend_dhclient
+        ;;
+    thaw|resume)
+        resume_dhclient
+        ;;
+    *) exit $NA
+        ;;
+esac
diff --git a/SOURCES/README.dhclient.d b/SOURCES/README.dhclient.d
new file mode 100644
index 0000000..6899aaa
--- /dev/null
+++ b/SOURCES/README.dhclient.d
@@ -0,0 +1,47 @@
+The /etc/dhcp/dhclient.d directory allows other packages and system
+administrators to create application-specific option handlers for dhclient.
+
+When dhclient is run, any option listed in the dhcp-options(5) man page can
+be requested.  dhclient-script does not handle every option available
+because doing so would make the script unmaintainable as the components
+using those options might change over time.  The knowledge of how to handle
+those options should be under the responsibility of the package maintainer
+for that component (e.g., NTP options belong in a handler in the ntp
+package).
+
+To make maintenance easier, application specific DHCP options can be handled
+by creating a bash script with two functions and placing it in /etc/dhcp/dhclient.d
+
+The script must follow a specific form:
+
+(1) The script must be named NAME.sh.  NAME can be anything, but it makes
+    sense to name it for the service it handles.  e.g., ntp.sh
+
+(2) The script must provide a NAME_config() function to read the options and
+    do whatever it takes to put those options in place.
+
+(3) The script must provide a NAME_restore() function to restore original
+    configuration state when dhclient stops.
+
+(4) The script must be 'chmod +x' or dhclient-script will ignore it.
+
+The scripts execute in the same environment as dhclient-script.  That means
+all of the functions and variables available to it are available to your
+NAME.sh script.  Things of note:
+
+    ${SAVEDIR} is where original configuration files are saved.  Save your
+    original configuration files here before you take the DHCP provided
+    values and generate new files.
+
+    Variables set in /etc/sysconfig/network, /etc/sysconfig/networking/network,
+    and /etc/sysconfig/network-scripts/ifcfg-$interface are available to
+    you.
+
+See the scripts in /etc/dhcp/dhclient.d for examples.
+
+NOTE:  Do not use functions defined in /usr/sbin/dhclient-script.  Consider
+dhclient-script a black box.  This script may change over time, so the
+dhclient.d scripts should not be using functions defined in it.
+
+-- 
+David Cantrell <dcantrell@redhat.com>
diff --git a/SOURCES/dhclient-script b/SOURCES/dhclient-script
new file mode 100644
index 0000000..5f58112
--- /dev/null
+++ b/SOURCES/dhclient-script
@@ -0,0 +1,975 @@
+#!/bin/bash
+#
+# dhclient-script: Network interface configuration script run by
+#                  dhclient based on DHCP client communication
+#
+# Copyright (C) 2008-2014  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): David Cantrell <dcantrell@redhat.com>
+#            Jiri Popelka <jpopelka@redhat.com>
+#
+# ----------
+# This script is a rewrite/reworking on dhclient-script originally
+# included as part of dhcp-970306:
+# dhclient-script for Linux. Dan Halbert, March, 1997.
+# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
+# Modified by David Cantrell <dcantrell@redhat.com> for Fedora and RHEL
+# ----------
+#
+
+PATH=/bin:/usr/bin:/sbin
+# scripts in dhclient.d/ use $SAVEDIR (#833054)
+export SAVEDIR=/var/lib/dhclient
+
+LOGFACILITY="local7"
+LOGLEVEL="notice"
+
+ETCDIR="/etc/dhcp"
+
+RESOLVCONF="/etc/resolv.conf"
+
+logmessage() {
+    msg="${1}"
+    logger -p "${LOGFACILITY}.${LOGLEVEL}" -t "NET" "dhclient: ${msg}"
+}
+
+eventually_add_hostnames_domain_to_search() {
+# For the case when hostname for this machine has a domain that is not in domain_search list
+# 1) get a hostname with `ipcalc --hostname` or `hostnamectl --transient`
+# 2) get the domain from this hostname
+# 3) add this domain to search line in resolv.conf if it's not already
+#    there (domain list that we have recently added there is a parameter of this function)
+# We can't do this directly when generating resolv.conf in make_resolv_conf(), because
+# we need to first save the resolv.conf with obtained values before we can call `ipcalc --hostname`.
+# See bug 637763
+    search="${1}"
+    if need_hostname; then
+        status=1
+        OLD_HOSTNAME=$HOSTNAME
+        if [ -n "${new_ip_address}" ]; then
+            eval $(/usr/bin/ipcalc --silent --hostname "${new_ip_address}" ; echo "status=$?")
+        elif [ -n "${new_ip6_address}" ]; then
+            eval $(/usr/bin/ipcalc --silent --hostname "${new_ip6_address}" ; echo "status=$?")
+        fi
+
+        if [ ${status} -eq 0 ]; then
+            domain=$(echo "${HOSTNAME}" | cut -s -d "." -f 2-)
+        fi
+        HOSTNAME=$OLD_HOSTNAME
+    else
+          domain=$(hostnamectl --transient 2>/dev/null | cut -s -d "." -f 2-)
+    fi
+
+    if [ -n "${domain}" ] &&
+       [ ! "${domain}" = "localdomain" ] &&
+       [ ! "${domain}" = "localdomain6" ] &&
+       [ ! "${domain}" = "(none)" ] &&
+       [[ ! "${domain}" = *\ * ]]; then
+       is_in="false"
+       for s in ${search}; do
+           if [ "${s}" = "${domain}" ] ||
+              [ "${s}" = "${domain}." ]; then
+              is_in="true"
+           fi
+       done
+
+       if [ "${is_in}" = "false" ]; then
+           # Add domain name to search list (#637763)
+          sed -i -e "s/${search}/${search} ${domain}/" "${RESOLVCONF}"
+       fi
+    fi
+}
+
+make_resolv_conf() {
+    [ "${PEERDNS}" = "no" ] && return
+
+    if [ "${reason}" = "RENEW" ] &&
+       [ "${new_domain_name}" = "${old_domain_name}" ] &&
+       [ "${new_domain_name_servers}" = "${old_domain_name_servers}" ]; then
+        return
+    fi
+
+    if [ -n "${new_domain_name}" ] ||
+       [ -n "${new_domain_name_servers}" ] ||
+       [ -n "${new_domain_search}" ]; then
+        rscf="$(mktemp "${TMPDIR:-/tmp}/XXXXXX")"
+        [[ -z "${rscf}" ]] && return
+        echo "; generated by /usr/sbin/dhclient-script" > "${rscf}"
+
+        if [ -n "${SEARCH}" ]; then
+            search="${SEARCH}"
+        else
+            if [ -n "${new_domain_search}" ]; then
+                # Remove instaces of \032 (#450042)
+                search="${new_domain_search//\\032/ }"
+            elif [ -n "${new_domain_name}" ]; then
+                # Note that the DHCP 'Domain Name Option' is really just a domain
+                # name, and that this practice of using the domain name option as
+                # a search path is both nonstandard and deprecated.
+                search="${new_domain_name}"
+            fi
+        fi
+
+        if [ -n "${search}" ]; then
+            echo "search ${search}" >> "${rscf}"
+        fi
+
+        if [ -n "${RES_OPTIONS}" ]; then
+            echo "options ${RES_OPTIONS}" >> "${rscf}"
+        fi
+
+        if [ -n "${new_domain_name_servers}" ]; then
+            for nameserver in ${new_domain_name_servers} ; do
+                echo "nameserver ${nameserver}" >> "${rscf}"
+            done
+        else # keep 'old' nameservers
+            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p "${RESOLVCONF}" >> "${rscf}"
+        fi
+
+        change_resolv_conf "${rscf}"
+        rm -f "${rscf}"
+
+        if [ -n "${search}" ]; then
+            eventually_add_hostnames_domain_to_search "${search}"
+        fi
+    elif [ -n "${new_dhcp6_name_servers}" ] ||
+         [ -n "${new_dhcp6_domain_search}" ]; then
+        rscf="$(mktemp "${TMPDIR:-/tmp}/XXXXXX")"
+        [[ -z "${rscf}" ]] && return
+        echo "; generated by /usr/sbin/dhclient-script" > "${rscf}"
+
+        if [ -n "${SEARCH}" ]; then
+            search="${SEARCH}"
+        else
+            if [ -n "${new_dhcp6_domain_search}" ]; then
+                search="${new_dhcp6_domain_search//\\032/ }"
+            fi
+        fi
+
+        if [ -n "${search}" ]; then
+            echo "search ${search}" >> "${rscf}"
+        fi
+
+        if [ -n "${RES_OPTIONS}" ]; then
+            echo "options ${RES_OPTIONS}" >> "${rscf}"
+        fi
+
+        shopt -s nocasematch
+        if [ -n "${new_dhcp6_name_servers}" ]; then
+            for nameserver in ${new_dhcp6_name_servers} ; do
+                # If the nameserver has a link-local address
+                # add a <zone_id> (interface name) to it.
+                if  [[ "$nameserver" =~ ^fe80:: ]]
+                then
+                    zone_id="%${interface}"
+                else
+                    zone_id=
+                fi
+                echo "nameserver ${nameserver}$zone_id" >> "${rscf}"
+            done
+        else # keep 'old' nameservers
+            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p "${RESOLVCONF}" >> "${rscf}"
+        fi
+        shopt -u nocasematch
+
+        change_resolv_conf "${rscf}"
+        rm -f "${rscf}"
+
+        if [ -n "${search}" ]; then
+            eventually_add_hostnames_domain_to_search "${search}"
+        fi
+    fi
+}
+
+# run given script
+run_hook() {
+    local script
+    local exit_status
+    script="${1}"
+
+    if [ -f ${script} ]; then
+        . ${script}
+    fi
+
+    if [ -n "${exit_status}" ] && [ "${exit_status}" -ne 0 ]; then
+        logmessage "${script} returned non-zero exit status ${exit_status}"
+    fi
+
+    return ${exit_status}
+}
+
+# run scripts in given directory
+run_hookdir() {
+    local dir
+    dir="${1}"
+
+    if [ -d "${dir}" ]; then
+        for script in $(find $dir -executable ! -empty); do
+            run_hook ${script} || return $?
+        done
+    fi
+
+    return 0
+}
+
+exit_with_hooks() {
+    # Source the documented exit-hook script, if it exists
+    run_hook "${ETCDIR}/dhclient-exit-hooks" || exit $?
+    # Now run scripts in the hooks directory.
+    run_hookdir "${ETCDIR}/dhclient-exit-hooks.d" || exit $?
+
+    exit ${1}
+}
+
+quad2num() {
+    if [ $# -eq 4 ]; then
+        let n="${1} << 24 | ${2} << 16 | ${3} << 8 | ${4}"
+        echo "${n}"
+        return 0
+    else
+        echo "0"
+        return 1
+    fi
+}
+
+ip2num() {
+    IFS='.' quad2num ${1}
+}
+
+num2ip() {
+    let n="${1}"
+    let o1="(${n} >> 24) & 0xff"
+    let o2="(${n} >> 16) & 0xff"
+    let o3="(${n} >> 8) & 0xff"
+    let o4="${n} & 0xff"
+    echo "${o1}.${o2}.${o3}.${o4}"
+}
+
+get_network_address() {
+# get network address for the given IP address and (netmask or prefix)
+    ip="${1}"
+    nm="${2}"
+
+    if [ -n "${ip}" -a -n "${nm}" ]; then
+        if [[ "${nm}" = *.* ]]; then
+            ipcalc -s -n "${ip}" "${nm}" | cut -d '=' -f 2
+        else
+            ipcalc -s -n "${ip}/${nm}" | cut -d '=' -f 2
+        fi
+    fi
+}
+
+get_prefix() {
+# get prefix for the given IP address and mask
+    ip="${1}"
+    nm="${2}"
+
+    if [ -n "${ip}" -a -n "${nm}" ]; then
+        ipcalc -s -p "${ip}" "${nm}" | cut -d '=' -f 2
+    fi
+}
+
+class_bits() {
+    let ip=$(IFS='.' ip2num "${1}")
+    let bits=32
+    let mask='255'
+    for ((i=0; i <= 3; i++, 'mask<<=8')); do
+        let v='ip&mask'
+        if [ "$v" -eq 0 ] ; then
+             let bits-=8
+        else
+             break
+        fi
+    done
+    echo $bits
+}
+
+is_router_reachable() {
+    # handle DHCP servers that give us a router not on our subnet
+    router="${1}"
+    routersubnet="$(get_network_address "${router}" "${new_subnet_mask}")"
+    mysubnet="$(get_network_address "${new_ip_address}" "${new_subnet_mask}")"
+
+    if [ ! "${routersubnet}" = "${mysubnet}" ]; then
+        # TODO: This function should not have side effects such as adding or
+        # removing routes. Can this be done with "ip route get" or similar
+        # instead? Are there cases that rely on this route being created here?
+        ip -4 route replace "${router}/32" dev "${interface}"
+        if [ "$?" -ne 0 ]; then
+            logmessage "failed to create host route for ${router}"
+            return 1
+        fi
+    fi
+
+    return 0
+}
+
+add_default_gateway() {
+    router="${1}"
+
+    if is_router_reachable "${router}" ; then
+        if [ $# -gt 1 ] && [ -n "${2}" ] && [[ "${2}" -gt 0 ]]; then
+            ip -4 route replace default via "${router}" dev "${interface}" metric "${2}"
+        else
+            ip -4 route replace default via "${router}" dev "${interface}"
+        fi
+        if [ $? -ne 0 ]; then
+            logmessage "failed to create default route: ${router} dev ${interface} ${metric}"
+            return 1
+        else
+            return 0
+        fi
+    fi
+
+    return 1
+}
+
+execute_client_side_configuration_scripts() {
+# execute any additional client side configuration scripts we have
+    if [ "${1}" == "config" ] || [ "${1}" == "restore" ]; then
+        for f in ${ETCDIR}/dhclient.d/*.sh ; do
+            if [ -x "${f}" ]; then
+                subsystem="${f%.sh}"
+                subsystem="${subsystem##*/}"
+                . "${f}"
+                "${subsystem}_${1}"
+            fi
+        done
+    fi
+}
+
+flush_dev() {
+# Instead of bringing the interface down (#574568)
+# explicitly clear ARP cache and flush all addresses & routes.
+    ip -4 addr flush dev "${1}" >/dev/null 2>&1
+    ip -4 route flush dev "${1}" >/dev/null 2>&1
+    ip -4 neigh flush dev "${1}" >/dev/null 2>&1
+}
+
+remove_old_addr() {
+    if [ -n "${old_ip_address}" ]; then
+        if [ -n "${old_prefix}" ]; then
+            ip -4 addr del "${old_ip_address}/${old_prefix}" dev "${interface}" >/dev/null 2>&1
+        else
+            ip -4 addr del "${old_ip_address}" dev "${interface}" >/dev/null 2>&1
+        fi
+    fi
+}
+
+dhconfig() {
+    if [ -n "${old_ip_address}" ] && [ -n "${alias_ip_address}" ] &&
+       [ ! "${alias_ip_address}" = "${old_ip_address}" ]; then
+        # possible new alias, remove old alias first
+        ip -4 addr del "${old_ip_address}" dev "${interface}" label "${interface}:0"
+    fi
+
+    if [ -n "${old_ip_address}" ] &&
+       [ ! "${old_ip_address}" = "${new_ip_address}" ]; then
+        # IP address changed. Delete all routes, and clear the ARP cache.
+        flush_dev "${interface}"
+    fi
+
+    # make sure the interface is up
+    ip link set dev "${interface}" up
+
+    # replace = add if it doesn't exist or override (update lifetimes) if it's there
+    ip -4 addr replace "${new_ip_address}/${new_prefix}" broadcast "${new_broadcast_address}" dev "${interface}" \
+       valid_lft "${new_dhcp_lease_time}" preferred_lft "${new_dhcp_lease_time}" >/dev/null 2>&1
+
+    if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] ||
+       [ ! "${old_ip_address}" = "${new_ip_address}" ] ||
+       [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] ||
+       [ ! "${old_network_number}" = "${new_network_number}" ] ||
+       [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] ||
+       [ ! "${old_routers}" = "${new_routers}" ] ||
+       [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then
+
+        # The 576 MTU is only used for X.25 and dialup connections
+        # where the admin wants low latency.  Such a low MTU can cause
+        # problems with UDP traffic, among other things.  As such,
+        # disallow MTUs from 576 and below by default, so that broken
+        # MTUs are ignored, but higher stuff is allowed (1492, 1500, etc).
+        if [ -n "${new_interface_mtu}" ] && [ "${new_interface_mtu}" -gt 576 ]; then
+            ip link set dev "${interface}" mtu "${new_interface_mtu}"
+        fi
+
+        # static routes
+        if [ -n "${new_classless_static_routes}" ] ||
+           [ -n "${new_static_routes}" ]; then
+            if [ -n "${new_classless_static_routes}" ]; then
+                IFS=', |' static_routes=(${new_classless_static_routes})
+                # If the DHCP server returns both a Classless Static Routes option and
+                # a Router option, the DHCP client MUST ignore the Router option. (RFC3442)
+                new_routers=""
+            else
+                IFS=', |' static_routes=(${new_static_routes})
+            fi
+            route_targets=()
+
+            for((i=0; i<${#static_routes[@]}; i+=2)); do
+                target=${static_routes[$i]}
+                if [ -n "${new_classless_static_routes}" ]; then
+                    if [ "${target}" = "0" ]; then
+                        new_routers="${static_routes[$i+1]}"
+                        continue
+                    else
+                        prefix=${target%%.*}
+                        target=${target#*.}
+                        IFS="." target_arr=(${target})
+                        unset IFS
+                        ((pads=4-${#target_arr[@]}))
+                        for j in $(seq $pads); do
+                            target="${target}.0"
+                        done
+
+                        # Client MUST zero any bits in the subnet number where the corresponding bit in the mask is zero.
+                        # In other words, the subnet number installed in the routing table is the logical AND of
+                        # the subnet number and subnet mask given in the Classless Static Routes option. (RFC3442)
+                        target="$(get_network_address "${target}" "${prefix}")"
+                    fi
+                else
+                    prefix=$(class_bits "${target}")
+                fi
+                gateway=${static_routes[$i+1]}
+
+                # special case 0.0.0.0 to allow static routing for link-local addresses
+                # (including IPv4 multicast) which will not have a next-hop (#769463, #787318)
+                if [ "${gateway}" = "0.0.0.0" ]; then
+                    valid_gateway=0
+                    scope='scope link'
+                else
+                    is_router_reachable "${gateway}"
+                    valid_gateway=$?
+                    scope=''
+                fi
+                if [ "${valid_gateway}" -eq 0 ]; then
+                    metric=''
+                    for t in "${route_targets[@]}"; do
+                        if [ "${t}" = "${target}" ]; then
+                            if [ -z "${metric}" ]; then
+                                metric=1
+                            else
+                                ((metric=metric+1))
+                            fi
+                        fi
+                    done
+
+                    if [ -n "${metric}" ]; then
+                        metric="metric ${metric}"
+                    fi
+
+                    ip -4 route replace "${target}/${prefix}" proto static via "${gateway}" dev "${interface}" ${metric} ${scope}
+
+                    if [ $? -ne 0 ]; then
+                        logmessage "failed to create static route: ${target}/${prefix} via ${gateway} dev ${interface} ${metric}"
+                    else
+                        route_targets=(${route_targets[@]} ${target})
+                    fi
+                fi
+            done
+        fi
+
+        # gateways
+        if [[ ( "${DEFROUTE}" != "no" ) &&
+              (( -z "${GATEWAYDEV}" ) || ( "${GATEWAYDEV}" = "${interface}" )) ]]; then
+            if [[ ( -z "${GATEWAY}" ) ||
+                  (( -n "${DHCLIENT_IGNORE_GATEWAY}" ) && ( "${DHCLIENT_IGNORE_GATEWAY}" = [Yy]* )) ]]; then
+                metric="${METRIC:-}"
+                let i="${METRIC:-0}"
+                default_routers=()
+
+                for router in ${new_routers} ; do
+                    added_router=-
+
+                    for r in "${default_routers[@]}" ; do
+                        if [ "${r}" = "${router}" ]; then
+                            added_router=1
+                        fi
+                    done
+
+                    if [ -z "${router}" ] ||
+                       [ "${added_router}" = "1" ] ||
+                       [ "$(IFS='.' ip2num ${router})" -le 0 ] ||
+                       [[ ( "${router}" = "${new_broadcast_address}" ) &&
+                          ( "${new_subnet_mask}" != "255.255.255.255" ) ]]; then
+                        continue
+                    fi
+
+                    default_routers=(${default_routers[@]} ${router})
+                    add_default_gateway "${router}" "${metric}"
+                    let i=i+1
+                    metric=${i}
+                done
+            elif [ -n "${GATEWAY}" ]; then
+                routersubnet=$(get_network_address "${GATEWAY}" "${new_subnet_mask}")
+                mysubnet=$(get_network_address "${new_ip_address}" "${new_subnet_mask}")
+
+                if [ "${routersubnet}" = "${mysubnet}" ]; then
+                    ip -4 route replace default via "${GATEWAY}" dev "${interface}"
+                fi
+            fi
+        fi
+    fi
+
+    if [ ! "${new_ip_address}" = "${alias_ip_address}" ] &&
+       [ -n "${alias_ip_address}" ]; then
+        # Reset the alias address (fix: this should really only do this on changes)
+        ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
+        ip -4 addr replace "${alias_ip_address}/${alias_prefix}" broadcast "${alias_broadcast_address}" dev "${interface}" label "${interface}:0"
+        ip -4 route replace "${alias_ip_address}/32" dev "${interface}"
+    fi
+
+    # After dhclient brings an interface UP with a new IP address, subnet mask, 
+    # and routes, in the REBOOT/BOUND states -> search for "dhclient-up-hooks".
+    if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] ||
+       [ ! "${old_ip_address}" = "${new_ip_address}" ] ||
+       [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] ||
+       [ ! "${old_network_number}" = "${new_network_number}" ] ||
+       [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] ||
+       [ ! "${old_routers}" = "${new_routers}" ] ||
+       [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then
+
+        if [ -x "${ETCDIR}/dhclient-${interface}-up-hooks" ]; then
+            . "${ETCDIR}/dhclient-${interface}-up-hooks"
+        elif [ -x ${ETCDIR}/dhclient-up-hooks ]; then
+            . ${ETCDIR}/dhclient-up-hooks
+        fi
+    fi
+
+    make_resolv_conf
+
+    if [ -n "${new_host_name}" ] && need_hostname; then
+        hostnamectl set-hostname --transient --no-ask-password "${new_host_name}"
+    fi
+
+    if [[ ( "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" = [yY1]* ) &&
+          ( -n "${new_time_offset}" ) ]]; then
+        # DHCP option "time-offset" is requested by default and should be
+        # handled.  The geographical zone abbreviation cannot be determined
+        # from the GMT offset, but the $ZONEINFO/Etc/GMT$offset file can be
+        # used - note: this disables DST.
+        ((z=new_time_offset/3600))
+        ((hoursWest=$(printf '%+d' $z)))
+
+        if (( $hoursWest < 0 )); then
+            # tzdata treats negative 'hours west' as positive 'gmtoff'!
+            ((hoursWest*=-1))
+        fi
+
+        tzfile=/usr/share/zoneinfo/Etc/GMT$(printf '%+d' ${hoursWest})
+        if [ -e "${tzfile}" ]; then
+            cp -fp "${tzfile}" /etc/localtime
+            touch /etc/localtime
+        fi
+    fi
+
+    execute_client_side_configuration_scripts "config"
+}
+
+wait_for_link_local() {
+    # we need a link-local address to be ready (not tentative)
+    for i in $(seq 50); do
+        linklocal=$(ip -6 addr show dev "${interface}" scope link)
+        # tentative flag means DAD is still not complete
+        tentative=$(echo "${linklocal}" | grep tentative)
+        [[ -n "${linklocal}" && -z "${tentative}" ]] && exit_with_hooks 0
+        sleep 0.1
+    done
+}
+
+# Section 18.1.8. (Receipt of Reply Messages) of RFC 3315 says:
+# The client SHOULD perform duplicate address detection on each of
+# the addresses in any IAs it receives in the Reply message before
+# using that address for traffic.
+add_ipv6_addr_with_DAD() {
+            ip -6 addr replace "${new_ip6_address}/${new_ip6_prefixlen}" \
+                dev "${interface}" scope global valid_lft "${new_max_life}" \
+                                          preferred_lft "${new_preferred_life}"
+
+            # repeatedly test whether newly added address passed
+            # duplicate address detection (DAD)
+            for i in $(seq 5); do
+                sleep 1 # give the DAD some time
+
+                addr=$(ip -6 addr show dev "${interface}" \
+                       | grep "${new_ip6_address}/${new_ip6_prefixlen}")
+
+                # tentative flag == DAD is still not complete
+                tentative=$(echo "${addr}" | grep tentative)
+                # dadfailed flag == address is already in use somewhere else
+                dadfailed=$(echo "${addr}" | grep dadfailed)
+
+                if [ -n "${dadfailed}" ] ; then
+                    # address was added with valid_lft/preferred_lft 'forever', remove it
+                    ip -6 addr del "${new_ip6_address}/${new_ip6_prefixlen}" dev "${interface}"
+                    exit_with_hooks 3
+                fi
+                if [ -z "${tentative}" ] ; then
+                    if [ -n "${addr}" ]; then
+                        # DAD is over
+                        return 0
+                    else
+                        # address was auto-removed (or not added at all)
+                        exit_with_hooks 3
+                    fi
+                fi
+            done
+            return 0
+}
+
+dh6config() {
+    if [ -n "${old_ip6_prefix}" ] ||
+       [ -n "${new_ip6_prefix}" ]; then
+        echo "Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}"
+        exit_with_hooks 0
+    fi
+
+    case "${reason}" in
+        BOUND6)
+            if [ -z "${new_ip6_address}" ] ||
+               [ -z "${new_ip6_prefixlen}" ]; then
+                exit_with_hooks 2
+            fi
+
+            add_ipv6_addr_with_DAD
+
+            make_resolv_conf
+            ;;
+
+        RENEW6|REBIND6)
+            if [[ -n "${new_ip6_address}" ]] &&
+               [[ -n "${new_ip6_prefixlen}" ]]; then
+               if [[  ! "${new_ip6_address}" = "${old_ip6_address}" ]]; then
+                   [[ -n "${old_ip6_address}" ]] && ip -6 addr del "${old_ip6_address}" dev "${interface}"
+               fi
+               # call it even if new_ip6_address = old_ip6_address to update lifetimes
+               add_ipv6_addr_with_DAD
+            fi
+
+            if [ ! "${new_dhcp6_name_servers}" = "${old_dhcp6_name_servers}" ] ||
+               [ ! "${new_dhcp6_domain_search}" = "${old_dhcp6_domain_search}" ]; then
+                make_resolv_conf
+            fi
+            ;;
+
+        DEPREF6)
+            if [ -z "${new_ip6_prefixlen}" ]; then
+                exit_with_hooks 2
+            fi
+
+            ip -6 addr change "${new_ip6_address}/${new_ip6_prefixlen}" \
+                dev "${interface}" scope global preferred_lft 0
+            ;;
+    esac
+
+    execute_client_side_configuration_scripts "config"
+}
+
+# Functions from /etc/sysconfig/network-scripts/network-functions
+
+need_hostname ()
+{
+    CHECK_HOSTNAME=$(hostnamectl --transient)
+    if [[ "${CHECK_HOSTNAME}" = "(none)" ]] ||
+       [[ "${CHECK_HOSTNAME}" = "localhost" ]] ||
+       [[ "${CHECK_HOSTNAME}" = "localhost.localdomain" ]]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+# Takes one argument - temporary resolv.conf file
+change_resolv_conf ()
+{
+    options=$(grep '^[\ \	]*option' "${RESOLVCONF}" 2>/dev/null);
+    if [[ -n "${options}" ]]; then
+       # merge options from existing resolv.conf with specified resolv.conf content
+       newres="${options}"$'\n'$(grep -vF "${options}" "${1}");
+    else
+       newres=$(cat "${1}");
+    fi;
+
+    eval $(echo "${newres}" > "${RESOLVCONF}"; echo "status=$?")
+    if [[ $status -eq 0 ]]; then
+        logger -p local7.notice -t "NET" -i "${0} : updated ${RESOLVCONF}";
+        [[ -e /var/run/nscd/socket ]] && /usr/sbin/nscd -i hosts; # invalidate cache
+    fi;
+    return $status;
+}
+
+get_config_by_name ()
+{
+    LANG=C grep -E -i -l \
+        "^[[:space:]]*NAME=\"(Auto |System )?${1}\"" \
+        /etc/sysconfig/network-scripts/ifcfg-* \
+        | LC_ALL=C sed -e "$__sed_discard_ignored_files"
+}
+
+get_hwaddr ()
+{
+    if [ -f /sys/class/net/${1}/address ]; then
+        awk '{ print toupper($0) }' < /sys/class/net/${1}/address
+    elif [ -d "/sys/class/net/${1}" ]; then
+        LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
+            awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
+                                        "\\1", 1)); }'
+    fi
+}
+
+validate_resolv_conf()
+{
+    # It's possible to have broken symbolic link $RESOLVCONF -> <some_nm_dir>
+    # https://bugzilla.redhat.com/1475279
+    # Remove broken link and hope NM will survive
+    if [ -h "${RESOLVCONF}" -a ! -e "${RESOLVCONF}" ];
+    then
+        logmessage "${RESOLVCONF} is broken symlink. Recreating..."
+        unlink "${RESOLVCONF}"
+        touch "${RESOLVCONF}"
+    fi;
+}
+
+
+get_config_by_hwaddr ()
+{
+    LANG=C grep -il "^[[:space:]]*HWADDR=\"\?${1}\"\?\([[:space:]#]\|$\)" /etc/sysconfig/network-scripts/ifcfg-* \
+      | LC_ALL=C sed -e "$__sed_discard_ignored_files"
+}
+
+get_config_by_device ()
+{
+    LANG=C grep -l "^[[:space:]]*DEVICE=\"\?${1}\"\?\([[:space:]#]\|$\)" \
+        /etc/sysconfig/network-scripts/ifcfg-* \
+        | LC_ALL=C sed -e "$__sed_discard_ignored_files"
+}
+
+need_config ()
+{
+    # A sed expression to filter out the files that is_ignored_file recognizes
+    __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
+
+    local nconfig
+
+    CONFIG="ifcfg-${1}"
+    [ -f "${CONFIG}" ] && return
+    CONFIG="${1##*/}"
+    [ -f "${CONFIG}" ] && return
+    nconfig=$(get_config_by_name "${1}")
+    if [ -n "$nconfig" ] && [ -f "$nconfig" ]; then
+      CONFIG=${nconfig##*/}
+      return
+    fi
+    local addr=$(get_hwaddr ${1})
+    if [ -n "$addr" ]; then
+      nconfig=$(get_config_by_hwaddr ${addr})
+      if [ -n "$nconfig" ] ; then
+        CONFIG=${nconfig##*/}
+        [ -f "${CONFIG}" ] && return
+      fi
+    fi
+    nconfig=$(get_config_by_device ${1})
+    if [ -n "$nconfig" ] && [ -f "$nconfig" ]; then
+      CONFIG=${nconfig##*/}
+      return
+    fi
+}
+
+# We need this because of PEERDNS
+source_config ()
+{
+    CONFIG=${CONFIG##*/}
+    . /etc/sysconfig/network-scripts/$CONFIG
+}
+
+#
+# ### MAIN
+#
+
+# Invoke the local dhcp client enter hooks, if they exist.
+run_hook "${ETCDIR}/dhclient-enter-hooks" || exit $?
+run_hookdir "${ETCDIR}/dhclient-enter-hooks.d" || exit $?
+
+[ "${PEERDNS}" = "no" ] || validate_resolv_conf
+
+if [ -f /etc/sysconfig/network ]; then
+    . /etc/sysconfig/network
+fi
+
+if [ -f /etc/sysconfig/networking/network ]; then
+    . /etc/sysconfig/networking/network
+fi
+
+## it's possible initscripts package is not installed
+## for example in container. Don't flood stderr then
+if [ -d /etc/sysconfig/network-scripts ]; then
+        cd /etc/sysconfig/network-scripts
+        CONFIG="${interface}"
+        need_config "${CONFIG}"
+        source_config >/dev/null 2>&1
+fi;
+
+# In case there's some delay in rebinding, it might happen, that the valid_lft drops to 0,
+# address is removed by kernel and then re-added few seconds later by dhclient-script.
+# With this work-around the address lives a minute longer.
+# "4294967235" = infinite (forever) - 60
+[[ "${new_dhcp_lease_time}" -lt "4294967235" ]] && new_dhcp_lease_time=$((new_dhcp_lease_time + 60))
+[[ "${new_max_life}" -lt "4294967235" ]] && new_max_life=$((new_max_life + 60))
+
+new_prefix="$(get_prefix "${new_ip_address}" "${new_subnet_mask}")"
+old_prefix="$(get_prefix "${old_ip_address}" "${old_subnet_mask}")"
+alias_prefix="$(get_prefix "${alias_ip_address}" "${alias_subnet_mask}")"
+
+case "${reason}" in
+    MEDIUM|ARPCHECK|ARPSEND)
+        # Do nothing
+        exit_with_hooks 0
+        ;;
+
+    PREINIT)
+        if [ -n "${alias_ip_address}" ]; then
+            # Flush alias, its routes will disappear too.
+            ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
+        fi
+
+        # upstream dhclient-script removes (ifconfig $interface 0 up) old adresses in PREINIT,
+        # but we sometimes (#125298) need (for iSCSI/nfs root to have a dhcp interface) to keep the existing ip
+        # flush_dev ${interface}
+        ip link set dev "${interface}" up
+        if [ -n "${DHCLIENT_DELAY}" ] && [ "${DHCLIENT_DELAY}" -gt 0 ]; then
+            # We need to give the kernel some time to get the interface up.
+            sleep "${DHCLIENT_DELAY}"
+        fi
+
+        exit_with_hooks 0
+        ;;
+
+    PREINIT6)
+        # ensure interface is up
+        ip link set dev "${interface}" up
+
+        # Removing stale addresses from aborted clients shouldn't be needed
+        # since we've been adding addresses with lifetimes.
+        # Which means that kernel eventually removes them automatically.
+        # ip -6 addr flush dev "${interface}" scope global permanent
+
+        wait_for_link_local
+
+        exit_with_hooks 0
+        ;;
+
+    BOUND|RENEW|REBIND|REBOOT)
+        if [ -z "${interface}" ] || [ -z "${new_ip_address}" ]; then
+            exit_with_hooks 2
+        fi
+        if arping -D -q -c2 -I "${interface}" "${new_ip_address}"; then
+            dhconfig
+            exit_with_hooks 0
+        else  # DAD failed, i.e. address is already in use
+            ARP_REPLY=$(arping -D -c2 -I "${interface}" "${new_ip_address}" | grep reply | awk '{print toupper($5)}' | cut -d "[" -f2 | cut -d "]" -f1)
+            OUR_MACS=$(ip link show | grep link | awk '{print toupper($2)}' | uniq)
+            if [[ "${OUR_MACS}" = *"${ARP_REPLY}"* ]]; then
+                # the reply can come from our system, that's OK (#1116004#c33)
+                dhconfig
+                exit_with_hooks 0
+            else
+                exit_with_hooks 1
+            fi
+        fi
+        ;;
+
+    BOUND6|RENEW6|REBIND6|DEPREF6)
+        dh6config
+        exit_with_hooks 0
+        ;;
+
+    EXPIRE6|RELEASE6|STOP6)
+        if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then
+            exit_with_hooks 2
+        fi
+
+        ip -6 addr del "${old_ip6_address}/${old_ip6_prefixlen}" \
+            dev "${interface}"
+
+        execute_client_side_configuration_scripts "restore"
+
+        if [ -x "${ETCDIR}/dhclient-${interface}-down-hooks" ]; then
+            . "${ETCDIR}/dhclient-${interface}-down-hooks"
+        elif [ -x ${ETCDIR}/dhclient-down-hooks ]; then
+            . ${ETCDIR}/dhclient-down-hooks
+        fi
+
+        exit_with_hooks 0
+        ;;
+
+    EXPIRE|FAIL|RELEASE|STOP)
+        execute_client_side_configuration_scripts "restore"
+
+        if [ -x "${ETCDIR}/dhclient-${interface}-down-hooks" ]; then
+            . "${ETCDIR}/dhclient-${interface}-down-hooks"
+        elif [ -x ${ETCDIR}/dhclient-down-hooks ]; then
+            . ${ETCDIR}/dhclient-down-hooks
+        fi
+
+        if [ -n "${alias_ip_address}" ]; then
+            # Flush alias
+            ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
+        fi
+
+        # upstream script sets interface down here,
+        # we only remove old ip address
+        #flush_dev ${interface}
+        remove_old_addr
+
+        if [ -n "${alias_ip_address}" ]; then
+            ip -4 addr replace "${alias_ip_address}/${alias_prefix}" broadcast "${alias_broadcast_address}" dev "${interface}" label "${interface}:0"
+            ip -4 route replace "${alias_ip_address}/32" dev "${interface}"
+        fi
+
+        exit_with_hooks 0
+        ;;
+
+    TIMEOUT)
+        if [ -n "${new_routers}" ]; then
+            if [ -n "${alias_ip_address}" ]; then
+                ip -4 addr flush dev "${interface}" label "${interface}:0" >/dev/null 2>&1
+            fi
+
+            ip -4 addr replace "${new_ip_address}/${new_prefix}" \
+                broadcast "${new_broadcast_address}" dev "${interface}" \
+                valid_lft "${new_dhcp_lease_time}" preferred_lft "${new_dhcp_lease_time}"
+            set ${new_routers}
+
+            if ping -q -c 1 -w 10 -I "${interface}" "${1}"; then
+                dhconfig
+                exit_with_hooks 0
+            fi
+
+            #flush_dev ${interface}
+            remove_old_addr
+            exit_with_hooks 1
+        else
+            exit_with_hooks 1
+        fi
+        ;;
+
+    *)
+        logmessage "unhandled state: ${reason}"
+        exit_with_hooks 1
+        ;;
+esac
+
+exit_with_hooks 0
diff --git a/SOURCES/dhcpd.service b/SOURCES/dhcpd.service
new file mode 100644
index 0000000..7363d7d
--- /dev/null
+++ b/SOURCES/dhcpd.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=DHCPv4 Server Daemon
+Documentation=man:dhcpd(8) man:dhcpd.conf(5)
+Wants=network-online.target
+After=network-online.target
+After=time-sync.target
+
+[Service]
+Type=notify
+EnvironmentFile=-/etc/sysconfig/dhcpd
+ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid $DHCPDARGS
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/dhcpd6.service b/SOURCES/dhcpd6.service
new file mode 100644
index 0000000..ff844c0
--- /dev/null
+++ b/SOURCES/dhcpd6.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=DHCPv6 Server Daemon
+Documentation=man:dhcpd(8) man:dhcpd.conf(5)
+Wants=network-online.target
+After=network-online.target
+After=time-sync.target
+
+[Service]
+Type=notify
+EnvironmentFile=-/etc/sysconfig/dhcpd6
+ExecStart=/usr/sbin/dhcpd -f -6 -cf /etc/dhcp/dhcpd6.conf -user dhcpd -group dhcpd --no-pid $DHCPDARGS
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/dhcrelay.service b/SOURCES/dhcrelay.service
new file mode 100644
index 0000000..43a0ca3
--- /dev/null
+++ b/SOURCES/dhcrelay.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=DHCP Relay Agent Daemon
+Documentation=man:dhcrelay(8)
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=notify
+ExecStart=/usr/sbin/dhcrelay -d --no-pid
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SPECS/dhcp.spec b/SPECS/dhcp.spec
new file mode 100644
index 0000000..7066a4a
--- /dev/null
+++ b/SPECS/dhcp.spec
@@ -0,0 +1,1882 @@
+# SystemTap support is disabled by default
+%{!?sdt:%global sdt 0}
+
+#http://lists.fedoraproject.org/pipermail/devel/2011-August/155358.html
+%global _hardened_build 1
+
+# Where dhcp configuration files are stored
+%global dhcpconfdir %{_sysconfdir}/dhcp
+
+
+%global prever b1
+#global patchver P1
+%global DHCPVERSION %{version}%{?prever}%{?patchver:-%{patchver}}
+
+Summary:  Dynamic host configuration protocol software
+Name:     dhcp
+Version:  4.4.2
+Release:  15.b1%{?dist}
+
+# NEVER CHANGE THE EPOCH on this package.  The previous maintainer (prior to
+# dcantrell maintaining the package) made incorrect use of the epoch and
+# that's why it is at 12 now.  It should have never been used, but it was.
+# So we are stuck with it.
+Epoch:    12
+License:  ISC
+Url:      https://www.isc.org/dhcp/
+Source0:  ftp://ftp.isc.org/isc/dhcp/%{DHCPVERSION}/dhcp-%{DHCPVERSION}.tar.gz
+Source1:  dhclient-script
+Source2:  README.dhclient.d
+Source3:  11-dhclient
+Source5:  56dhclient
+Source6:  dhcpd.service
+Source7:  dhcpd6.service
+Source8:  dhcrelay.service
+
+Patch1 : 0001-change-bug-url.patch
+Patch2 : 0002-additional-dhclient-options.patch
+Patch3 : 0003-Handle-releasing-interfaces-requested-by-sbin-ifup.patch
+Patch4 : 0004-Support-unicast-BOOTP-for-IBM-pSeries-systems-and-ma.patch
+Patch5 : 0005-Change-default-requested-options.patch
+Patch6 : 0006-Various-man-page-only-fixes.patch
+Patch7 : 0007-Change-paths-to-conform-to-our-standards.patch
+Patch8 : 0008-Make-sure-all-open-file-descriptors-are-closed-on-ex.patch
+Patch9 : 0009-Fix-garbage-in-format-string-error.patch
+Patch10 : 0010-Handle-null-timeout.patch
+Patch11 : 0011-Drop-unnecessary-capabilities.patch
+Patch12 : 0012-RFC-3442-Classless-Static-Route-Option-for-DHCPv4-51.patch
+Patch13 : 0013-DHCPv6-over-PPP-support-626514.patch
+Patch14 : 0014-IPoIB-support-660681.patch
+Patch15 : 0015-Add-GUID-DUID-to-dhcpd-logs-1064416.patch
+Patch16 : 0016-Turn-on-creating-sending-of-DUID.patch
+Patch17 : 0017-Send-unicast-request-release-via-correct-interface.patch
+Patch18 : 0018-No-subnet-declaration-for-iface-should-be-info-not-e.patch
+Patch19 : 0019-dhclient-write-DUID_LLT-even-in-stateless-mode-11563.patch
+Patch20 : 0020-Discover-all-hwaddress-for-xid-uniqueness.patch
+Patch21 : 0021-Load-leases-DB-in-non-replay-mode-only.patch
+Patch22 : 0022-dhclient-make-sure-link-local-address-is-ready-in-st.patch
+Patch23 : 0023-option-97-pxe-client-id.patch
+Patch24 : 0024-Detect-system-time-changes.patch
+Patch25 : 0025-bind-Detect-system-time-changes.patch
+Patch26 : 0026-Add-dhclient-5-B-option-description.patch
+Patch27:  0027-Add-missed-sd-notify-patch-to-manage-dhcpd-with-syst.patch
+Patch28:  0028-Fix-for-CVE-2021-25217.patch
+Patch29:  0029-Use-system-getaddrinfo-for-dhcp.patch
+
+
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: make
+BuildRequires: libtool
+BuildRequires: openldap-devel
+# --with-ldap-gssapi
+BuildRequires: krb5-devel
+BuildRequires: libcap-ng-devel
+# https://fedorahosted.org/fpc/ticket/502#comment:3
+BuildRequires: systemd systemd-devel
+# dhcp-sd_notify.patch
+BuildRequires: pkgconfig(libsystemd)
+%if ! 0%{?_module_build}
+BuildRequires: doxygen
+%endif
+%if %{sdt}
+BuildRequires: systemtap-sdt-devel
+%global tapsetdir    /usr/share/systemtap/tapset
+%endif
+
+# In _docdir we ship some perl scripts and module from contrib subdirectory.
+# Because nothing under _docdir is allowed to "require" anything,
+# prevent _docdir from being scanned. (#674058)
+%filter_requires_in %{_docdir}
+%{filter_setup}
+
+%description
+DHCP (Dynamic Host Configuration Protocol)
+
+%package server
+Summary: Provides the ISC DHCP server
+Requires: %{name}-common = %{epoch}:%{version}-%{release}
+Requires(pre): shadow-utils
+Requires(post): coreutils grep sed
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+
+%description server
+DHCP (Dynamic Host Configuration Protocol) is a protocol which allows
+individual devices on an IP network to get their own network
+configuration information (IP address, subnetmask, broadcast address,
+etc.) from a DHCP server. The overall purpose of DHCP is to make it
+easier to administer a large network.
+
+This package provides the ISC DHCP server.
+
+%package relay
+Summary: Provides the ISC DHCP relay agent
+Requires: %{name}-common = %{epoch}:%{version}-%{release}
+Requires(post): grep sed
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+
+%description relay
+DHCP (Dynamic Host Configuration Protocol) is a protocol which allows
+individual devices on an IP network to get their own network
+configuration information (IP address, subnetmask, broadcast address,
+etc.) from a DHCP server. The overall purpose of DHCP is to make it
+easier to administer a large network.
+
+This package provides the ISC DHCP relay agent.
+
+
+%package client
+Summary: Provides the ISC DHCP client daemon and dhclient-script
+Provides: dhclient = %{epoch}:%{version}-%{release}
+Obsoletes: dhclient < %{epoch}:%{version}-%{release}
+# dhclient-script requires:
+Requires: coreutils gawk grep ipcalc iproute iputils sed systemd
+Requires: %{name}-common = %{epoch}:%{version}-%{release}
+# Old NetworkManager expects the dispatcher scripts in a different place
+Conflicts: NetworkManager < 1.20
+
+%description client
+DHCP (Dynamic Host Configuration Protocol) is a protocol which allows
+individual devices on an IP network to get their own network
+configuration information (IP address, subnetmask, broadcast address,
+etc.) from a DHCP server. The overall purpose of DHCP is to make it
+easier to administer a large network.
+
+This package provides the ISC DHCP client.
+
+%package common
+Summary: Common files used by ISC dhcp client, server and relay agent
+BuildArch: noarch
+Obsoletes: dhcp-libs < %{epoch}:%{version}
+
+
+
+%description common
+DHCP (Dynamic Host Configuration Protocol) is a protocol which allows
+individual devices on an IP network to get their own network
+configuration information (IP address, subnetmask, broadcast address,
+etc.) from a DHCP server. The overall purpose of DHCP is to make it
+easier to administer a large network.
+
+This package provides common files used by dhcp and dhclient package.
+
+%package libs-static
+Summary: Shared libraries used by ISC dhcp client and server
+Provides: %{name}-libs%{?_isa} =  %{epoch}:%{version}-%{release}
+Provides: %{name}-libs =  %{epoch}:%{version}-%{release}
+Provides: bundled(bind-export-libs)
+Provides: bundled(bind)
+
+%description libs-static
+This package contains shared libraries used by ISC dhcp client and server
+
+
+%package devel
+Summary: Development headers and libraries for interfacing to the DHCP server
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
+
+%description devel
+Header files and API documentation for using the ISC DHCP libraries.  The
+libdhcpctl and libomapi static libraries are also included in this package.
+
+%if ! 0%{?_module_build}
+%package devel-doc
+Summary: Developer's Guide for ISC DHCP
+Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+BuildArch: noarch
+
+%description devel-doc
+This documentation is intended for developers, contributors and other
+programmers that are interested in internal operation of the code.
+This package contains doxygen-generated documentation.
+%endif
+
+%prep
+%setup -n dhcp-%{DHCPVERSION}
+pushd bind
+tar -xvf bind.tar.gz
+ln -s bind-9* bind
+popd
+%autopatch -p1 
+
+# Update paths in all man pages
+for page in client/dhclient.conf.5 client/dhclient.leases.5 \
+            client/dhclient-script.8 client/dhclient.8 ; do
+    sed -i -e 's|CLIENTBINDIR|%{_sbindir}|g' \
+                -e 's|RUNDIR|%{_localstatedir}/run|g' \
+                -e 's|DBDIR|%{_localstatedir}/lib/dhclient|g' \
+                -e 's|ETCDIR|%{dhcpconfdir}|g' $page
+done
+
+for page in server/dhcpd.conf.5 server/dhcpd.leases.5 server/dhcpd.8 ; do
+    sed -i -e 's|CLIENTBINDIR|%{_sbindir}|g' \
+                -e 's|RUNDIR|%{_localstatedir}/run|g' \
+                -e 's|DBDIR|%{_localstatedir}/lib/dhcpd|g' \
+                -e 's|ETCDIR|%{dhcpconfdir}|g' $page
+done
+
+sed -i -e 's|/var/db/|%{_localstatedir}/lib/dhcpd/|g' contrib/dhcp-lease-list.pl
+
+## FIXME drop unused bind components 
+
+%build
+#libtoolize --copy --force
+autoreconf --verbose --force --install
+
+CFLAGS="%{optflags} -fno-strict-aliasing -fcommon" \
+%configure \
+    --with-srv-lease-file=%{_localstatedir}/lib/dhcpd/dhcpd.leases \
+    --with-srv6-lease-file=%{_localstatedir}/lib/dhcpd/dhcpd6.leases \
+    --with-cli-lease-file=%{_localstatedir}/lib/dhclient/dhclient.leases \
+    --with-cli6-lease-file=%{_localstatedir}/lib/dhclient/dhclient6.leases \
+    --with-srv-pid-file=%{_localstatedir}/run/dhcpd.pid \
+    --with-srv6-pid-file=%{_localstatedir}/run/dhcpd6.pid \
+    --with-cli-pid-file=%{_localstatedir}/run/dhclient.pid \
+    --with-cli6-pid-file=%{_localstatedir}/run/dhclient6.pid \
+    --with-relay-pid-file=%{_localstatedir}/run/dhcrelay.pid \
+    --with-ldap \
+    --with-ldapcrypto \
+    --with-ldap-gssapi \
+    --enable-log-pid \
+%if %{sdt}
+    --enable-systemtap \
+    --with-tapset-install-dir=%{tapsetdir} \
+%endif
+    --enable-paranoia --enable-early-chroot \
+    --enable-binary-leases \
+    --with-systemd
+make -j1
+
+%if ! 0%{?_module_build}
+pushd doc
+make %{?_smp_mflags} devel
+popd
+%endif
+
+%install
+make DESTDIR=%{buildroot} install %{?_smp_mflags}
+
+# We don't want example conf files in /etc
+rm -f %{buildroot}%{_sysconfdir}/dhclient.conf.example
+rm -f %{buildroot}%{_sysconfdir}/dhcpd.conf.example
+
+# dhclient-script
+install -D -p -m 0755 %{SOURCE1} %{buildroot}%{_sbindir}/dhclient-script
+
+# README.dhclient.d
+install -p -m 0644 %{SOURCE2} .
+
+# Empty directory for dhclient.d scripts
+mkdir -p %{buildroot}%{dhcpconfdir}/dhclient.d
+
+# NetworkManager dispatcher script
+mkdir -p %{buildroot}%{_prefix}/lib/NetworkManager/dispatcher.d
+install -p -m 0755 %{SOURCE3} %{buildroot}%{_prefix}/lib/NetworkManager/dispatcher.d
+
+# pm-utils script to handle suspend/resume and dhclient leases
+install -D -p -m 0755 %{SOURCE5} %{buildroot}%{_libdir}/pm-utils/sleep.d/56dhclient
+
+# systemd unit files
+mkdir -p %{buildroot}%{_unitdir}
+install -m 644 %{SOURCE6} %{buildroot}%{_unitdir}
+install -m 644 %{SOURCE7} %{buildroot}%{_unitdir}
+install -m 644 %{SOURCE8} %{buildroot}%{_unitdir}
+
+# Start empty lease databases
+mkdir -p %{buildroot}%{_localstatedir}/lib/dhcpd/
+touch %{buildroot}%{_localstatedir}/lib/dhcpd/dhcpd.leases
+touch %{buildroot}%{_localstatedir}/lib/dhcpd/dhcpd6.leases
+mkdir -p %{buildroot}%{_localstatedir}/lib/dhclient/
+
+# default sysconfig file for dhcpd
+mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
+cat <<EOF > %{buildroot}%{_sysconfdir}/sysconfig/dhcpd
+# WARNING: This file is NOT used anymore.
+
+# If you are here to restrict what interfaces should dhcpd listen on,
+# be aware that dhcpd listens *only* on interfaces for which it finds subnet
+# declaration in dhcpd.conf. It means that explicitly enumerating interfaces
+# also on command line should not be required in most cases.
+
+# If you still insist on adding some command line options,
+# copy dhcpd.service from /lib/systemd/system to /etc/systemd/system and modify
+# it there.
+# https://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
+
+# example:
+# $ cp /usr/lib/systemd/system/dhcpd.service /etc/systemd/system/
+# $ vi /etc/systemd/system/dhcpd.service
+# $ ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid <your_interface_name(s)>
+# $ systemctl --system daemon-reload
+# $ systemctl restart dhcpd.service
+EOF
+
+# Copy sample conf files into position (called by doc macro)
+cp -p doc/examples/dhclient-dhcpv6.conf client/dhclient6.conf.example
+cp -p doc/examples/dhcpd-dhcpv6.conf server/dhcpd6.conf.example
+
+cat << EOF > client/dhclient-enter-hooks
+#!/bin/bash
+
+# For dhclient/dhclient-script debugging.
+# Copy this into /etc/dhcp/ and make it executable.
+# Run 'dhclient -d <interface>' to see info passed from dhclient to dhclient-script.
+# See also HOOKS section in dhclient-script(8) man page.
+
+echo "interface: ${interface}"
+echo "reason: ${reason}"
+
+( set -o posix ; set ) | grep "old_"
+( set -o posix ; set ) | grep "new_"
+( set -o posix ; set ) | grep "alias_"
+( set -o posix ; set ) | grep "requested_"
+EOF
+
+# Install default (empty) dhcpd.conf:
+mkdir -p %{buildroot}%{dhcpconfdir}
+cat << EOF > %{buildroot}%{dhcpconfdir}/dhcpd.conf
+#
+# DHCP Server Configuration file.
+#   see /usr/share/doc/dhcp-server/dhcpd.conf.example
+#   see dhcpd.conf(5) man page
+#
+EOF
+
+# Install default (empty) dhcpd6.conf:
+cat << EOF > %{buildroot}%{dhcpconfdir}/dhcpd6.conf
+#
+# DHCPv6 Server Configuration file.
+#   see /usr/share/doc/dhcp-server/dhcpd6.conf.example
+#   see dhcpd.conf(5) man page
+#
+EOF
+
+# Install dhcp.schema for LDAP configuration
+install -D -p -m 0644 contrib/ldap/dhcp.schema %{buildroot}%{_sysconfdir}/openldap/schema/dhcp.schema
+
+# Don't package libtool *.la files
+find %{buildroot} -type f -name "*.la" -delete -print
+
+%pre server
+# /usr/share/doc/setup/uidgid
+%global gid_uid 177
+getent group dhcpd >/dev/null || groupadd --force --gid %{gid_uid} --system dhcpd
+if ! getent passwd dhcpd >/dev/null ; then
+    if ! getent passwd %{gid_uid} >/dev/null ; then
+      useradd --system --uid %{gid_uid} --gid dhcpd --home / --shell /sbin/nologin --comment "DHCP server" dhcpd
+    else
+      useradd --system --gid dhcpd --home / --shell /sbin/nologin --comment "DHCP server" dhcpd
+    fi
+fi
+exit 0
+
+%post server
+# Initial installation
+%systemd_post dhcpd.service dhcpd6.service
+
+
+for servicename in dhcpd dhcpd6; do
+  etcservicefile=%{_sysconfdir}/systemd/system/${servicename}.service
+  if [ -f ${etcservicefile} ]; then
+    grep -q Type= ${etcservicefile} || sed -i '/\[Service\]/a Type=notify' ${etcservicefile}
+    sed -i 's/After=network.target/Wants=network-online.target\nAfter=network-online.target/' ${etcservicefile}
+  fi
+done
+exit 0
+
+%post relay
+# Initial installation
+%systemd_post dhcrelay.service
+
+for servicename in dhcrelay; do
+  etcservicefile=%{_sysconfdir}/systemd/system/${servicename}.service
+  if [ -f ${etcservicefile} ]; then
+    grep -q Type= ${etcservicefile} || sed -i '/\[Service\]/a Type=notify' ${etcservicefile}
+    sed -i 's/After=network.target/Wants=network-online.target\nAfter=network-online.target/' ${etcservicefile}
+  fi
+done
+exit 0
+
+%preun server
+# Package removal, not upgrade
+%systemd_preun dhcpd.service dhcpd6.service
+
+%preun relay
+# Package removal, not upgrade
+%systemd_preun dhcrelay.service
+
+
+%postun server
+# Package upgrade, not uninstall
+%systemd_postun_with_restart dhcpd.service dhcpd6.service
+
+%postun relay
+# Package upgrade, not uninstall
+%systemd_postun_with_restart dhcrelay.service
+
+
+%triggerun -- dhcp
+# convert DHC*ARGS from /etc/sysconfig/dhc* to /etc/systemd/system/dhc*.service
+for servicename in dhcpd dhcpd6 dhcrelay; do
+  if [ -f %{_sysconfdir}/sysconfig/${servicename} ]; then
+    # get DHCPDARGS/DHCRELAYARGS value from /etc/sysconfig/${servicename}
+    source %{_sysconfdir}/sysconfig/${servicename}
+    if [ "${servicename}" == "dhcrelay" ]; then
+        args=$DHCRELAYARGS
+    else
+        args=$DHCPDARGS
+    fi
+    # value is non-empty (i.e. user modified) and there isn't a service unit yet
+    if [ -n "${args}" -a ! -f %{_sysconfdir}/systemd/system/${servicename}.service ]; then
+      # in $args replace / with \/ otherwise the next sed won't take it
+      args=$(echo $args | sed 's/\//\\\//'g)
+      # add $args to the end of ExecStart line
+      sed -r -e "/ExecStart=/ s/$/ ${args}/" \
+                < %{_unitdir}/${servicename}.service \
+                > %{_sysconfdir}/systemd/system/${servicename}.service
+    fi
+  fi
+done
+
+%files server
+%doc server/dhcpd.conf.example server/dhcpd6.conf.example
+%doc contrib/ldap/ contrib/dhcp-lease-list.pl
+%attr(0750,root,root) %dir %{dhcpconfdir}
+%attr(0755,dhcpd,dhcpd) %dir %{_localstatedir}/lib/dhcpd
+%attr(0644,dhcpd,dhcpd) %verify(mode) %config(noreplace) %{_localstatedir}/lib/dhcpd/dhcpd.leases
+%attr(0644,dhcpd,dhcpd) %verify(mode) %config(noreplace) %{_localstatedir}/lib/dhcpd/dhcpd6.leases
+%config(noreplace) %{_sysconfdir}/sysconfig/dhcpd
+%config(noreplace) %{dhcpconfdir}/dhcpd.conf
+%config(noreplace) %{dhcpconfdir}/dhcpd6.conf
+%dir %{_sysconfdir}/openldap/schema
+%config(noreplace) %{_sysconfdir}/openldap/schema/dhcp.schema
+%attr(0644,root,root)   %{_unitdir}/dhcpd.service
+%attr(0644,root,root)   %{_unitdir}/dhcpd6.service
+%{_sbindir}/dhcpd
+%{_bindir}/omshell
+%attr(0644,root,root) %{_mandir}/man1/omshell.1.gz
+%attr(0644,root,root) %{_mandir}/man5/dhcpd.conf.5.gz
+%attr(0644,root,root) %{_mandir}/man5/dhcpd.leases.5.gz
+%attr(0644,root,root) %{_mandir}/man8/dhcpd.8.gz
+%if %{sdt}
+%{tapsetdir}/*.stp
+%endif
+
+%files relay
+%{_sbindir}/dhcrelay
+%attr(0644,root,root) %{_unitdir}/dhcrelay.service
+%attr(0644,root,root) %{_mandir}/man8/dhcrelay.8.gz
+
+%files client
+%doc README.dhclient.d
+%doc client/dhclient.conf.example client/dhclient6.conf.example client/dhclient-enter-hooks
+%attr(0750,root,root) %dir %{dhcpconfdir}
+%dir %{dhcpconfdir}/dhclient.d
+%dir %{_localstatedir}/lib/dhclient
+%dir %{_prefix}/lib/NetworkManager
+%dir %{_prefix}/lib/NetworkManager/dispatcher.d
+%{_prefix}/lib/NetworkManager/dispatcher.d/11-dhclient
+%{_sbindir}/dhclient
+%{_sbindir}/dhclient-script
+%attr(0755,root,root) %{_libdir}/pm-utils/sleep.d/56dhclient
+%attr(0644,root,root) %{_mandir}/man5/dhclient.conf.5.gz
+%attr(0644,root,root) %{_mandir}/man5/dhclient.leases.5.gz
+%attr(0644,root,root) %{_mandir}/man8/dhclient.8.gz
+%attr(0644,root,root) %{_mandir}/man8/dhclient-script.8.gz
+
+%files common
+%{!?_licensedir:%global license %%doc}
+%{license} LICENSE
+%doc README RELNOTES doc/References.txt
+%attr(0644,root,root) %{_mandir}/man5/dhcp-options.5.gz
+%attr(0644,root,root) %{_mandir}/man5/dhcp-eval.5.gz
+
+%files libs-static
+%{_libdir}/libdhcp*.a
+%{_libdir}/libomapi.a
+
+%files devel
+%doc doc/IANA-arp-parameters doc/api+protocol
+%{_includedir}/dhcpctl
+%{_includedir}/omapip
+%attr(0644,root,root) %{_mandir}/man3/dhcpctl.3.gz
+%attr(0644,root,root) %{_mandir}/man3/omapi.3.gz
+
+%if ! 0%{?_module_build}
+%files devel-doc
+%doc doc/html/
+%endif
+
+%changelog
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 12:4.4.2-15.b1
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Thu Jul  8 2021 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-14.b1
+- Fix for CVE-2021-25217
+
+* Mon Jun 14 2021 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-13.b1
+- Do not export getaddrinfo from irs libs (#1969858)
+
+* Fri Jun 11 2021 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-11.b1
+- Drop compat package finally
+
+* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 12:4.4.2-10.b1
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.4.2-9.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Wed Jul 29 2020 Pavel Zhukov <pavel@pzhukov-pc.home.redhat.com> - 12:4.4.2-8.b1
+- Fix IB patch (#1860689)
+
+* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.4.2-7.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Wed Apr 22 2020 Pavel Zhukov <pavel@desktop.zhukoff.net> - 12:4.4.2-6.b1
+- Change upstream URL
+
+* Fri Feb 21 2020 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-5.b1
+- Workarounnd for gcc10
+
+* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.4.2-4.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Mon Jan  6 2020 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-3.b1
+- Drop NetworkManager 12-dhcpd script. It's deprecated by wait-online (#1780861) 
+
+* Mon Jan  6 2020 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.2-1.b1
+- Dropped all (pre 4.0.0) changelog
+- New version (4.4.2b1)
+
+* Wed Nov 27 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-20
+- Fix leak of file descriptors
+
+* Mon Nov 11 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-19
+- Reword -B option description
+
+* Thu Nov  7 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-18
+- Readd sd-notify patch
+
+* Thu Aug 22 2019 Lubomir Rintel <lkundrak@v3.sk> - 12:4.4.1-17
+- Move the NetworkManager dispatcher script out of /etc
+
+* Thu Jul 25 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-16
+- Split timers patch to bind and dhcp parts
+
+* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.4.1-15
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Thu Jul 11 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-14
+- Detect time change and request lease renewal
+
+* Mon May 20 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-13
+- Unpack bind prior to patching
+- Provide noarch libs
+
+* Sat May 04 2019 Björn Esser <besser82@fedoraproject.org> - 12:4.4.1-12
+- rebuilt (bind)
+
+* Tue Apr  2 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-11
+- Specify epoch for obsolete
+
+* Tue Apr  2 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-10
+- Cherry-pick 00b7f9a Specify architecture for provides -
+
+* Tue Apr  2 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-9
+- Move obsolete to common section
+
+* Wed Mar 27 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-8
+- Add sd_notify patch to support systemd notify (1687040)
+
+* Mon Mar 18 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-7
+- Provides specific version of libs
+
+* Mon Mar 18 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-6
+- Obsolete dhcp-libs
+
+* Wed Mar 13 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-5
+- Do not require static libs for non devel installations
+
+* Thu Feb 28 2019 Pavel Zhukov <pzhukov@redhat.com> - 12:4.4.1-3
+- New version 4.4.1
+
+* Mon Sep 24 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-29
+- Resolves: 1632246 - Do not fail if iface has no hwaddr
+
+* Thu Aug 30 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-28
+- Do not try to map leases file in memory if not in replay mode
+
+* Fri Jul 13 2018 Petr Menšík <pemensik@redhat.com> - 12:4.3.6-27
+- Update to bind 9.11.4
+
+* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.3.6-26
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Mon Jun 18 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-25
+- Resolves: 1592239 - Handle dhcp4-change event properly
+
+* Mon May 21 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-24
+- Fix few more shellcheck warnings
+
+* Fri May 18 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-23
+- Get rid of eval in 11-dhclient
+- Credits to legolegs user of linux.org.ru
+
+* Tue May 15 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-21
+- Fix for CVE-2018-1111
+
+* Fri Apr  6 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-20
+- Discover hwaddr for all interfaces for xid uniqueness
+
+* Wed Mar 21 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-19
+- Don't use run-parts for hooks discovery (#1558612)
+
+* Fri Mar 09 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-18
+- Own ldap schema directory (#1553432)
+
+* Thu Mar  1 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-17
+- Fix CVE-2018-5732 CVE-2018-5733 (#1550246)
+
+* Thu Feb 22 2018 Petr Menšík <pemensik@redhat.com> - 12:4.3.6-16
+- Compile with recent bind includes, that does not include isc/util.h
+
+* Thu Feb 22 2018 Petr Menšík <pemensik@redhat.com> - 12:4.3.6-15
+- Do not rely on ignoring case sensitivity of VERSION variable
+
+* Thu Feb 22 2018 Petr Menšík <pemensik@redhat.com> - 12:4.3.6-14
+- Use bind-export-libs package instead of bind99
+- Use isc-config.sh to configure bind libs
+- Change requirement to bind-export-devel
+
+* Thu Feb 22 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-13
+- Do not parse sysconfig/network-scripts if initscripts not installed (#1098172)
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.3.6-12
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 12:4.3.6-11
+- Switch to %%ldconfig_scriptlets
+
+* Wed Jan 10 2018 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-10
+- Use released version
+
+* Wed Dec 20 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.5-9
+- Change duid_uuid patch to not use std99 feature
+
+* Fri Dec  8 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-8
+- Fix omapi SD leak (#1523547)
+
+* Thu Nov  9 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-7
+- Add patch for proper signal handling with shared context (#1457871)
+
+* Wed Sep 20 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-6
+- Do now override hostname variable in script
+
+* Sun Sep 10 2017 Peter Robinson <pbrobinson@fedoraproject.org> 12:4.3.6-5
+- Rebuild for bind 9.9.11
+
+* Tue Aug  1 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-4
+- Fix typos in dhclient-script
+
+* Thu Jul 27 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-3
+- Recreate /etc/resolv.conf if NetworkManager screwed it up (#1475279)
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.3.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+
+* Fri Jul 14 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.6-1
+- New version 4.3.6
+
+* Fri Jul 07 2017 Igor Gnatenko <ignatenko@redhat.com> - 12:4.3.5-10
+- Rebuild due to bug in RPM (RHBZ #1468476)
+
+* Mon Jul 03 2017 Petr Menšík <pemensik@redhat.com> - 12:4.3.5-9
+- Rebuild for bind 9.9.10
+
+* Wed May 31 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.5-8
+- Drop chown from the post section
+
+* Tue May 23 2017 Pavel Zhukov <pzhukov@redhat.com> - 12:4.3.5-7
+- Don't open ddns port until it's needed. Credits to Petr Menšík for the original idea
+
+* Wed Apr 19 2017 Dominika Hodovska <dhodovsk@redhat.com> - 12:4.3.5-5
+- don't build doxygen documentation during modular build
+
+* Tue Apr 04 2017 Pavel Zhukov <landgraf@fedoraproject.org> - 12:4.3.5-4
+- Add EnvironmentFile parameter for backward compatibility
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.3.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Wed Nov 30 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.5-2
+- get BUG_REPORT_URL from /etc/os-release (#1399351)
+
+* Wed Oct 05 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.5-1
+- 4.3.5
+
+* Mon Sep 12 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.5-0.1b1
+- 4.3.5b1
+
+* Wed Aug 03 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.4-3
+- [dhclient] rename -R option to --request-options (#1357947)
+- [dhclient] rename -timeout option to --timeout
+
+* Thu May 26 2016 Tomas Hozza <thozza@redhat.com> - 12:4.3.4-2
+- Rebuild against bind99-9.9.9-P1
+
+* Fri Apr 29 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.4-1
+- 4.3.4
+- disable systemtap (I don't think anybody ever used it)
+
+* Wed Mar 23 2016 Zdenek Dohnal zdohnal@redhat.com - 12:4.3.3-13.P1
+- Mentioning the bash script is needed in README.dhclient.d
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 12:4.3.3-12.P1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jan 13 2016 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-11.P1
+- 4.3.3-P1 - fix for CVE-2015-8605 (#1298077)
+
+* Wed Dec 16 2015 Tomas Hozza <thozza@redhat.com> - 12:4.3.3-10
+- Rebuild against bind-9.9.8-P2
+
+* Mon Dec 14 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-9
+- implement DUID-UUID (RFC 6355) and make it default DUID type (#560361#60)
+
+* Tue Nov 24 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-8
+- dispatcher.d/12-dhcpd: use reset-failed command
+
+* Mon Nov 23 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-7
+- dhclient-script: hostname -> hostnamectl --transient
+
+* Tue Nov 03 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-6
+- dhclient-script: source ifcfg-* because of PEERDNS (#1277253)
+
+* Tue Oct 13 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-5
+- dhclient-script: fix for gateway not in the end of rfc3442 routes list (#1251644)
+
+* Tue Oct 13 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-4
+- dhclient-script: make_resolv_conf(): keep old nameservers
+  if server sends domain-name/search, but no nameservers (#1269595)
+
+* Tue Sep 22 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-3
+- dhclient: make sure link-local address is ready in stateless mode (#1263466)
+
+* Mon Sep 07 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-2
+- VLAN ID is only bottom 12-bits of TCI (#1259552)
+
+* Fri Sep 04 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-1
+- 4.3.3
+
+* Tue Aug 11 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-0.2b1
+- dhclient-script: respect DEFROUTE/GATEWAYDEV if Classless Static Routes are offered (#1251644)
+
+* Mon Aug 10 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.3-0.1b1
+- 4.3.3b1
+- enable krb5/gssapi authentication for OpenLDAP
+- enable support for binary insertion of leases
+
+* Wed Jul 15 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-12
+- fix ipcalc requires
+
+* Tue Jul 14 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-11
+- remove dependency on initscripts (#1098172)
+- make path to resolv.conf configurable (#1086425)
+
+* Thu Jul 09 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-10
+- spec cleanup
+
+* Thu Jul 02 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-9
+- test upstream fix for #866714 (paranoia.patch)
+
+* Wed Jun 24 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-8
+- add more randomness into xid generation (#1195693)
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.3.2-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue May 26 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-6
+- dhclient-script: run also scripts in dhclient-[enter/exit]-hooks.d dir
+
+* Tue Apr 21 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-5
+- dhclient-script: add a minute to address lifetimes (#1188423)
+
+* Mon Apr 13 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-4
+- dhclient-script: amend previous change (#1210984)
+
+* Wed Mar 25 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-3
+- dhclient-script: fix shellcheck.net suggestions
+
+* Fri Mar 13 2015 Tomas Hozza <thozza@redhat.com> - 12:4.3.2-2
+- rebuild against bind99 9.9.7 package
+
+* Thu Mar 05 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-1
+- 4.3.2
+
+* Wed Feb 25 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-0.6b1
+- correctly set IB's hw->hlen (#1185075)
+
+* Wed Feb 25 2015 Tomas Hozza <thozza@redhat.com> - 12:4.3.2-0.5b1
+- Rebuild against bind-9.10.2rc2
+
+* Tue Feb 17 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-0.4b1
+- dhclient-script: use 'ip addr replace' for both BOUND & RENEW
+
+* Tue Feb 17 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-0.3b1
+- doc/dhclient/dhclient-enter-hooks for dhclient-script debugging
+
+* Fri Feb 13 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-0.2b1
+- dhclient-script: s/addr add/addr replace/
+
+* Sun Feb 08 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.2-0.1b1
+- 4.3.2b1
+
+* Tue Feb 03 2015 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-21
+- send unicast request/release via correct interface (#800561, #1177351)
+
+* Mon Feb 02 2015 Tomas Hozza <thozza@redhat.com> - 12:4.3.1-20
+- rebuild against bind-9.10.2rc1
+
+* Wed Jan 14 2015 Tomas Hozza <thozza@redhat.com> - 12:4.3.1-19
+- rebuild against bind 9.10.1-P1
+
+* Thu Dec 18 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-18
+- dhclient: write DUID_LLT even in stateless mode (#1156356)
+
+* Wed Dec 17 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-17
+- option 97 - pxe-client-id (#1058674)
+
+* Wed Nov 19 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-16
+- amend post scriptlets for #1120656
+
+* Mon Nov 10 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-15
+- dhclient-script: restorecon calls shouldn't be needed
+                   as we have SELinux transition rules (#1161500)
+
+* Tue Nov 04 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-14
+- GSSAPI support for ldap authentication (#1150542)
+
+* Fri Oct 31 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-13
+- redefine DHCLIENT_DEFAULT_PREFIX_LEN  64 -> 128
+
+* Fri Oct 10 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-12
+- Relay-forward Message's Hop Limit should be 32 (#1147240)
+
+* Wed Oct 08 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-11
+- dhcpd generates spurious responses when seeing requests
+  from vlans on plain interface (#1150587)
+
+* Fri Oct 03 2014 Tomas Hozza <thozza@redhat.com> - 12:4.3.1-10
+- rebuild against bind-9.9.6
+
+* Thu Sep 04 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-9
+- [dhclient -6] infinite preferred/valid lifetime represented as -1 (#1133839)
+
+* Mon Sep 01 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-8
+- better obsoletes for server & client
+
+* Sat Aug 30 2014 Kalev Lember <kalevlember@gmail.com> - 12:4.3.1-7
+- Fix dhclient obsoletes version
+
+* Tue Aug 26 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-6
+- dhclient-script: another improvement of add_ipv6_addr_with_DAD()
+
+* Mon Aug 25 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-5
+- spec: use -D with 'install'
+- dhclient-script: IPv6 address which fails DAD is auto-removed when it was
+  added with valid_lft/preferred_lft other then 'forever' (#1133465)
+
+* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.3.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Thu Aug 14 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-3
+- dhclient-script: one more fix for #1129500
+
+* Thu Aug 14 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-2
+- dhclient-script: PREINIT6: make sure link-local address is available (#1129500)
+
+* Tue Aug 12 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-1
+- 4.3.1
+
+* Tue Aug 05 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-0.4.b1
+- dhclient-script: it's OK if the arping reply comes from our system (#1116004)
+
+* Tue Jul 22 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-0.3.b1
+- Use network-online.target instead of network.target (#1120656)
+
+* Fri Jul 11 2014 Tom Callaway <spot@fedoraproject.org> 12:4.3.1-0.2.b1
+- fix license handling
+
+* Thu Jul 10 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.1-0.1.b1
+- 4.3.1b1
+
+* Thu Jun 12 2014 Filipe Brandenburger <filbranden@google.com> - 12:4.3.0-15
+- dhclient-script: fix issue with classless static routes that breaks Fedora 20 on GCE cloud (#1102830)
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.3.0-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Fri May 30 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-13
+- systemtap: fixed dtrace input file (#1102797)
+
+* Thu May 29 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-12
+- dhcp-sd_notify.patch BuildRequires: pkgconfig(libsystemd)
+
+* Wed May 28 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-11
+- dhclient-script: fix stateless DHCPv6 mode (#1101149)
+
+* Wed May 07 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-10
+- use StandardError=null instead of log_perror.patch
+
+* Tue Mar 18 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-9
+- support for sending startup notifications to systemd (#1077666)
+
+* Fri Mar 07 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-8
+- rename doc subpackage do devel-doc
+
+* Mon Mar 03 2014 Jaromír Končický <jkoncick@redhat.com> - 12:4.3.0-7
+- added 'doc' package containing doxygen-generated documentation
+
+* Wed Feb 19 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-6
+- dhclient: rename our -I option to -C as upstream now uses -I
+
+* Wed Feb 19 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-5
+- dhclient-script: don't flush all addresses, just the used one
+
+* Tue Feb 18 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-4
+- IPoIB: add GUID/DUID to dhcpd logs (#1064416)
+
+* Mon Feb 17 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-3
+- don't try to run tests because there's no atf package since F21
+
+* Mon Feb 17 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-2
+- turn on using of DUID with DHCPv4 clients (#560361,c#40)
+- remove default /etc/dhcp/dhclient.conf
+
+* Tue Feb 04 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-1
+- 4.3.0
+
+* Wed Jan 29 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.7.rc1
+- 4.3.0rc1
+
+* Tue Jan 28 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.6.b1
+- don't apply retransmission.patch for now (RHBZ#1026565)
+
+* Sun Jan 26 2014 Kevin Fenzi <kevin@scrye.com> 12:4.3.0-0.5.b1
+- Rebuild for new bind
+
+* Tue Jan 21 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.4.b1
+- 4.3.0b1
+- ship dhcp-lease-list.pl
+- dhclient-script: don't ping router (#1055181)
+
+* Mon Jan 13 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.3.a1
+- update address lifetimes on RENEW/RENEW6 (#1032809)
+
+* Tue Jan 07 2014 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.2.a1
+- make it actually build
+
+* Thu Dec 19 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.3.0-0.1.a1
+- 4.3.0a1: requires bind-9.9.5
+
+* Thu Nov 21 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-28
+- dhclient-script: set address lifetimes (#1032809)
+
+* Thu Nov 14 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-27
+- dhclient-script(RENEW6|REBIND6): delete old ip6_address if it changed (#1015729)
+
+* Thu Oct 31 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-26
+- Provide default /etc/dhcp/dhclient.conf
+- Client always sends dhcp-client-identifier (#560361)
+
+* Thu Oct 24 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-25
+- use upstream patch for #1001742 ([ISC-Bugs #34784])
+
+* Mon Oct 07 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-24
+- dhcpd rejects the udp packet with checksum=0xffff (#1015997)
+
+* Fri Sep 27 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-23
+- 'No subnet declaration for <iface>' should be info, not error
+- decrease the sleep in 12-dhcpd due to timeout (#1003695#8)
+
+* Wed Sep 18 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-22
+- fix segfault introduced with previous commit
+
+* Tue Sep 17 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-21
+- 12-dhcpd: wait a few seconds before restarting services (#1003695)
+- another solution for #1001742 (#1005814#c10)
+
+* Thu Sep 12 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-20
+- bind DHCPv6 client to link-local address instead of 0 address (#1001742)
+
+* Mon Aug 26 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-19
+- don't crash on aliased infiniband interface (#996518)
+
+* Sun Aug 04 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-18
+- BuildRequires: systemd due to  %%{_unitdir}
+
+* Mon Jul 29 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-17
+- 12-dhcpd previously exited with error status 1 (#989207)
+
+* Mon Jul 15 2013 Tomas Hozza <thozza@redhat.com> - 12:4.2.5-16
+- rebuild against new bind
+
+* Tue Jul 02 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-15
+- fix several memory leaks in omapi (#978420)
+- remove send_release.patch (#979510)
+
+* Tue Jun 18 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-14
+- rebuilt against bind once more
+
+* Fri Jun 14 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-13
+- return /etc/sysconfig/dhcpd back, but do NOT use it (#909733)
+
+* Tue May 14 2013 Adam Williamson <awilliam@redhat.com> - 12:4.2.5-12
+- rebuild against new bind
+
+* Tue Apr 30 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-11
+- add missing conversion specifier in log_fatal() call (#957371)
+
+* Tue Apr 16 2013 Adam Tkac <atkac redhat com> - 12:4.2.5-10
+- rebuild against new bind
+
+* Wed Apr 03 2013 Tomas Hozza <thozza@redhat.com> - 12:4.2.5-9
+- Expose next-server DHCPv4 option to dhclient script
+
+* Tue Mar 26 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-8
+- describe -user/-group/-chroot in dhcpd.8
+
+* Fri Feb 22 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-7
+- remove triggerun condition (#895475)
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.2.5-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Thu Jan 24 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-5
+- remove missing-ipv6-not-fatal.patch because the concerning code is later
+  removed with getifaddrs.patch
+
+* Wed Jan 23 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-4
+- Make sure range6 is correct for subnet6 where it's declared (#902966)
+
+* Fri Jan 18 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-3
+- simplify the previously added triggerun scriptlet
+
+* Thu Jan 17 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-2
+- during update convert DHC*ARGS from /etc/sysconfig/dhc*
+  to /etc/systemd/system/dhc*.service (#895475)
+- 12-dhcpd NM dispatcher script now restarts also dhcpd6 service
+
+* Thu Jan 10 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-1
+- 4.2.5
+
+* Wed Jan 02 2013 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-0.3.rc1
+- run %%check in Fedora only, there's no atf package in RHEL
+
+* Thu Dec 20 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-0.2.rc1
+- don't package ancient contrib/* files
+
+* Thu Dec 20 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.5-0.1.rc1
+- 4.2.5rc1
+  - added %%check - upstream unit tests (Automated Test Framework - ATF)
+
+* Fri Nov 30 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-23.P2
+- fix two resource leaks in lpf-ib.patch
+
+* Mon Nov 26 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-22.P2
+- add After=time-sync.target to dhcpd[6].service (#878293)
+- remove groff from BuildRequires (no idea why it's been there)
+
+* Fri Nov 16 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-21.P2
+- multiple key statements in zone definition causes inappropriate error (#873794)
+
+* Fri Oct 26 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-20.P2
+- fix path to dhcpd6.leases in dhcpd6.conf.sample (#870458)
+
+* Wed Oct 17 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-19.P2
+- dhcpd needs to chown leases file created before de-rooting itself (#866714)
+
+* Thu Oct 11 2012 Adam Tkac <atkac redhat com> - 12:4.2.4-18.P2
+- rebuild against new bind-libs-lite
+
+* Tue Oct 09 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-17.P2
+- do-forward-updates statement wasn't recognized (#863646)
+
+* Wed Sep 26 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-16.P2
+- dhclient-usage.patch+part of manpages.patch merged with dhclient-options.patch
+
+* Thu Sep 13 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-15.P2
+- 4.2.4-P2: fix for CVE-2012-3955 (#856770)
+
+* Fri Aug 24 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-14.P1
+- SystemD unit files don't use Environment files any more (#850558)
+- NetworkManager dispatcher script doesn't use DHCPDARGS any more
+
+* Wed Aug 22 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-13.P1
+- fixed SPEC file so it comply with new systemd-rpm macros guidelines (#850089)
+
+* Mon Aug 20 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-12.P1
+- dhclient-script: fixed CONFIG variable value passed to need_config (#848858)
+- dhclient-script: calling dhclient-up-hooks after setting up route, gateways
+                   & interface alias (#848869)
+
+* Fri Aug 17 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-11.P1
+- don't build libdst, it hasn't been used since 4.2.0 (#849166)
+
+* Fri Jul 27 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-10.P1
+- isc_time_nowplusinterval() is not safe with 64-bit time_t (#662254, #789601)
+
+* Fri Jul 27 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.2.4-9.P1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Wed Jul 25 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-8.P1
+- Dhclient does not correctly parse zero-length options in
+  dhclient6.leases (#633318)
+
+* Wed Jul 25 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-7.P1
+- 4.2.4-P1: fix for CVE-2012-3570 CVE-2012-3571 and CVE-2012-3954 (#842892)
+
+* Mon Jul 23 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-6
+- ib.patch: added fall-back method (using ioctl(SIOCGIFHWADDR)) when getting
+            of HW address with getifaddrs() fails (#626514-c#63, #840601).
+
+* Mon Jul 23 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-5
+- Dhcpd does not correctly follow DhcpFailOverPeerDN (#838400)
+
+* Wed Jul 18 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-4
+- allow dhcpd to listen on alias interfaces (#840601)
+
+* Mon Jul 09 2012 Tomas Hozza <thozza@redhat.com> - 12:4.2.4-3
+- changed list of %%verify on the leases files (#837474)
+
+* Mon Jun 18 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-2
+- define $SAVEDIR in dhclient-script (#833054)
+
+* Wed Jun 06 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-1
+- 4.2.4
+
+* Tue Jun 05 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.8.rc2
+- return prematurely removed 12-dhcpd (NM dispatcher script) (#828522)
+
+* Fri May 25 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.7.rc2
+- getifaddrs.patch: use HAVE_SA_LEN macro
+
+* Wed May 23 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.6.rc2
+- 4.2.4rc2
+
+* Mon May 07 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.5.rc1
+- dhcpd.service: explicitly add -cf to indicate what conf file we use (#819325)
+- no need to copy /etc/*.conf to /etc/dhcp/*.conf in %%prep anymore
+
+* Tue May 01 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.4.rc1
+- 4.2.4rc1
+
+* Thu Apr 26 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.3.b1
+- remove inherit-leases.patch - it's probably not needed anymore (#815355)
+
+* Wed Apr 18 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.2.b1
+- update paths.patch and source URL
+
+* Mon Apr 16 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.4-0.1.b1
+- 4.2.4b1: noprefixavail.patch merged upstream
+
+* Fri Mar 30 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-25.P2
+- move dhclient & dhclient-script from /sbin to /usr/sbin
+
+* Fri Mar 23 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-24.P2
+- one more fix (#806342)
+
+* Fri Mar 23 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-23.P2
+- improve #449946 fix (#806342)
+
+* Wed Mar 21 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-22.P2
+- RFC5970 - DHCPv6 Options for Network Boot (#798735)
+
+* Wed Mar 21 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-21.P2
+- don't use fallback_interface when releasing lease (#800561)
+
+* Wed Mar 21 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-20.P2
+- use getifaddrs() to scan for interfaces on Linux (#449946)
+
+* Wed Feb 22 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-19.P2
+- don't send log messages to the standard error descriptor by default (#790387)
+
+* Mon Feb 13 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-18.P2
+- -timeout option (command line) with value 3 or less was driving dhclient mad (#789719)
+
+* Tue Feb 07 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-17.P2
+- dhclient-script: install link-local static routes with correct scope (#787318)
+
+* Wed Feb  1 2012 Adam Williamson <awilliam@redhat.com> - 12:4.2.3-16.P2
+- rebuild for new bind-libs-lite
+
+* Tue Jan 31 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-15.P2
+- revert previous change (#782499)
+- remove the rest of the sysvinit scriptlets
+
+* Tue Jan 17 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-14.P2
+- use PrivateTmp=true in service files (#782499)
+
+* Fri Jan 13 2012 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-13.P2
+- 4.2.3-P2: fix for CVE-2011-4868 (#781246)
+- clean up old Provides and Obsoletes
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.2.3-12.P1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Wed Dec 21 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-11.P1
+- revert change made in 4.2.3-3 because of failing failover inicialization (#765967)
+  the procedure is now:
+  init lease file, init failover, init PID file, change effective user/group ID
+- don't need to fix lease files ownership before starting service
+- dhclient-script: allow static route with a 0.0.0.0 next-hop address (#769463)
+
+* Tue Dec 20 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-10.P1
+- hopefully we don't need 12-dhcpd anymore as 'After=network.target'
+  in dhcpd[6].service should take care of the original problem (#565921)
+
+* Mon Dec 19 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-9.P1
+- don't ship legacy SysV initscripts
+- dhcpd6: move '-cf /etc/dhcp/dhcpd6.conf' from sysconfig/dhcpd6 to dhcpd6.service
+- run 'chown -R dhcpd:dhcpd /var/lib/dhcpd/' before starting dhcpd/dhcpd6 service
+  for the case where leases file is owned by root:root as a
+  consequence of running dhcpd without '-user dhcpd -group dhcpd' (#744292)
+
+* Fri Dec 09 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-8.P1
+- 4.2.3-P1: fix for CVE-2011-4539 (#765681)
+
+* Thu Nov 24 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-7
+- Send DHCPDECLINE and exit(2) when duplicate address was detected and
+  dhclient had been started with '-1' (#756759).
+- Don't build with -D_GNU_SOURCE, configure.ac uses AC_USE_SYSTEM_EXTENSIONS
+
+* Mon Nov 14 2011 Adam Tkac <atkac redhat com> - 12:4.2.3-6
+- rebuild against new bind
+
+* Fri Nov 11 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-5
+- dhclient-script: arping address in BOUND|RENEW|REBIND|REBOOT (#752116)
+
+* Wed Oct 26 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.2.3-4
+- Rebuilt for glibc bug#747377
+
+* Wed Oct 26 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-3
+- Write lease file AFTER changing of the effective user/group ID.
+- Move omshell from dhcp-common to main package (where it originally was).
+
+* Thu Oct 20 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-2
+- Write PID file BEFORE changing of the effective user/group ID.
+- Really define _hardened_build this time
+
+* Thu Oct 20 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-1
+- 4.2.3
+
+* Tue Oct 18 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.3-0.1.rc1
+- 4.2.3rc1
+
+* Sun Oct 09 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-12
+- change ownership of /var/lib/dhcpd/ to dhcpd:dhcpd (#744292)
+- no need to drop capabilies in dhcpd since it's been running as regular user
+
+* Fri Sep 30 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-11
+- 56dhclient: ifcfg file was not sourced (#742482)
+
+* Thu Sep 29 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-10
+- dhclient-script: address alias handling fixes from Scott Shambarger (#741786)
+
+* Thu Sep 22 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-9
+- dhclient-script: do not backup&restore /etc/resolv.conf and /etc/localtime.
+
+* Wed Sep 21 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-8
+- SystemTap support: spec file change, some dummy probes, tapset, simple script
+
+* Mon Sep 19 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-7
+- Support for IPoIB (IP over InfiniBand) interfaces (#660681)
+- Hopefully last tweak of adding of user and group (#699713)
+
+* Fri Sep 09 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-6
+- PIE-RELRO.patch is not needed anymore, defining _hardened_build does the same
+- One more tweak of adding of user and group (#699713)
+
+* Fri Sep 09 2011 Adam Tkac <atkac redhat com> - 12:4.2.2-5
+- rebuild against new bind
+
+* Fri Aug 26 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-4
+- Fix adding of user and group (#699713)
+
+* Fri Aug 19 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-3
+- Tighten explicit libs sub-package requirement so that it includes
+  the correct architecture as well.
+
+* Fri Aug 12 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-2
+- #699713:
+  - Use '--enable-paranoia --enable-early-chroot' configure flags
+  - Create/delete dhcpd user in %%post/%%postun
+  - Run dhcpd/dhcpd6 services with '-user dhcpd -group dhcpd'
+
+* Thu Aug 11 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-1
+- 4.2.2: fix for CVE-2011-2748, CVE-2011-2749 (#729850)
+
+* Wed Aug 10 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-0.4.rc1
+- Do not ship default /etc/dhcp/dhclient.conf (#560361,c#9)
+
+* Mon Jul 25 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-0.3.rc1
+- Improve capabilities patch to be able to run with PARANOIA & EARLY_CHROOT (#699713)
+
+* Mon Jul 18 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-0.2.rc1
+- 4.2.2rc1
+
+* Fri Jul 01 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.2-0.1.b1
+- 4.2.2b1: upstream merged initialization-delay.patch
+- Drop all capabilities in dhcpd/dhcrelay (#699713)
+
+* Fri Jun 17 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-12.P1
+- Removed upstream-merged IFNAMSIZ.patch
+- Polished patches according to results from static analysis of code.
+
+* Thu Jun 16 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-11.P1
+- Add triggerpostun scriptlet tied to dhcp-sysvinit
+- Make it possible to build without downstream patches (Kamil Dudka)
+
+* Tue May 17 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-10.P1
+- Fix typo in triggerun scriptlet (#705417)
+
+* Mon May 16 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-9.P1
+- Packages dhcp/dhclient/dhcp-common explicitly require the libs sub-package
+  with the same version and release (bug #705037).
+- Fix triggerun scriptlet
+
+* Mon May 09 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-8.P1
+- Fix 11-dhclient to export variables (#702735)
+
+* Fri Apr 29 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-7.P1
+- Comply with guidelines for systemd services
+
+* Wed Apr 27 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-6.P1
+- Fix NetworkManager dispatcher script for dhcpd to support arbitrary interface names
+
+* Wed Apr 06 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-5.P1
+- Better fix for CVE-2011-0997: making domain-name check more lenient (#694005)
+
+* Wed Apr 06 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-4.P1
+- 4.2.1-P1: fix for CVE-2011-0997 (#694005)
+
+* Fri Mar 25 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-3
+- Polished patches according to results from static analysis of code.
+
+* Mon Mar 07 2011 Rex Dieter <rdieter@fedoraproject.org> - 12:4.2.1-2
+- rebuild (bind)
+
+* Wed Mar 02 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-1
+- 4.2.1
+
+* Wed Feb 23 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-0.6.rc1
+- 4.2.1rc1
+- Fixed typo in dhclient.leases(5) (#676284)
+
+* Mon Feb 21 2011 Adam Tkac <atkac redhat com> - 12:4.2.1-0.5.b1
+- rebuild against new bind-libs-lite
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.2.1-0.4.b1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Jan 31 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-0.3.b1
+- Prevent anything under _docdir from being scanned. (#674058)
+
+* Fri Jan 28 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-0.2.b1
+- dhclient-script improvements, thanks to Ville Skyttä (#672279)
+
+* Thu Jan 27 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.1-0.1.b1
+- 4.2.1b1: fix for CVE-2011-0413 (#672996)
+- No longer need invalid-dhclient-conf, parse_date and release6-elapsed patches
+
+* Thu Jan 13 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-26.P2
+- Fix loading of configuration when LDAP is used (#668276)
+
+* Mon Jan 03 2011 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-25.P2
+- Fix OMAPI (#666441)
+
+* Tue Dec 21 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-24.P2
+- Provide default /etc/dhcp/dhclient.conf
+- Client always sends dhcp-client-identifier (#560361)
+
+* Wed Dec 15 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-23.P2
+- Add dhcp-common subpackage (#634673)
+
+* Mon Dec 13 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-22.P2
+- 4.2.0-P2: fix for CVE-2010-3616 (#662326)
+- Use upstream fix for #628258
+- Provide versioned symbols for rpmlint
+
+* Tue Dec 07 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-21.P1
+- Porting dhcpd/dhcpd6/dhcrelay services from SysV to Systemd
+
+* Tue Nov 23 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-20.P1
+- Remove explicit Obsoletes (#656310)
+
+* Fri Nov 19 2010 Dan Horák <dan[at]danny.cz> - 12:4.2.0-19.P1
+- fix build on sparc and s390
+
+* Tue Nov 09 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-18.P1
+- Applied Patrik Lahti's patch for DHCPv6 over PPP support (#626514)
+
+* Fri Nov 05 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-17.P1
+- fix broken dependencies
+
+* Thu Nov 04 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-16.P1
+- 4.2.0-P1: fix for CVE-2010-3611 (#649880)
+- dhclient-script: when updating 'search' statement in resolv.conf,
+  add domain part of hostname if it's not already there (#637763)
+
+* Wed Oct 20 2010 Adam Tkac <atkac redhat com> - 12:4.2.0-15
+- build dhcp's libraries as shared libs instead of static libs
+
+* Wed Oct 20 2010 Adam Tkac <atkac redhat com> - 12:4.2.0-14
+- fire away bundled BIND source
+
+* Wed Oct 20 2010 Adam Tkac <atkac redhat com> - 12:4.2.0-13
+- improve PIE patch (build libraries with -fpic, not with -fpie)
+
+* Wed Oct 13 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-12
+- Server was ignoring client's
+  Solicit (where client included address/prefix as a preference) (#634842)
+
+* Thu Oct 07 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-11
+- Use ping instead of arping in dhclient-script to handle
+  not-on-local-net gateway in ARP-less device (#524298)
+
+* Thu Oct 07 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-10
+- Check whether there is any unexpired address in previous lease
+  prior to confirming (INIT-REBOOT) the lease (#585418)
+
+* Mon Oct 04 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-9
+- RFC 3442 - ignore Router option only if
+  Classless Static Routes option contains default router
+
+* Thu Sep 30 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-8
+- Explicitly clear the ARP cache and flush all addresses & routes
+  instead of bringing the interface down (#574568)
+
+* Tue Sep 07 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-7
+- Hardening dhcpd/dhcrelay/dhclient by making them PIE & RELRO
+
+* Thu Sep 02 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-6
+- Another fix for handling time values on 64-bit platforms (#628258)
+
+* Wed Sep 01 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-5
+- Fix parsing of lease file dates & times on 64-bit platforms (#628258)
+
+* Tue Aug 31 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-4
+- RFC 3442 - Classless Static Route Option for DHCPv4 (#516325)
+
+* Fri Aug 20 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-3
+- Add DHCRELAYARGS variable to /etc/sysconfig/dhcrelay
+
+* Fri Jul 30 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-2
+- Add 12-dhcpd NM dispatcher script (#565921)
+- Rename 10-dhclient to 11-dhclient (10-sendmail already exists)
+
+* Wed Jul 21 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.2.0-1
+- 4.2.0: includes ldap-for-dhcp
+
+* Mon Jul 12 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-26.P1
+- Add LICENSE file to dhclient subpackage.
+
+* Thu Jul 01 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-25.P1
+- Adhere to Static Library Packaging Guidelines (#609605)
+
+* Tue Jun 29 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-24.P1
+- Fix parsing of date (#514828)
+
+* Thu Jun 03 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-23.P1
+- 4.1.1-P1: pair of bug fixes including one for CVE-2010-2156 (#601405)
+- Compile with -fno-strict-aliasing
+
+* Mon May 03 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-22
+- Fix the initialization-delay.patch (#587070)
+
+* Thu Apr 29 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-21
+- Cut down the 0-4 second delay before sending first DHCPDISCOVER (#587070)
+
+* Wed Apr 28 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-20
+- Move /etc/NetworkManager/dispatcher.d/10-dhclient script
+  from dhcp to dhclient subpackage (#586999)
+
+* Wed Apr 28 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-19
+- Add domain-search to the list of default requested DHCP options (#586906)
+
+* Wed Apr 21 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-18
+- If the Reply was received in response to Renew or Rebind message,
+  client adds any new addresses in the IA option to the IA (#578097)
+
+* Mon Apr 19 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-17
+- Fill in Elapsed Time Option in Release/Decline messages (#582939)
+
+* Thu Mar 25 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-16
+- In client initiated message exchanges stop retransmission
+  upon reaching the MRD rather than at some point after it (#559153)
+
+* Wed Mar 24 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-15
+- In dhclient-script check whether bound address
+  passed duplicate address detection (DAD) (#559147)
+- If the bound address failed DAD (is found to be in use on the link),
+  the dhcpv6 client sends a Decline message to the server
+  as described in section 18.1.7 of RFC-3315 (#559147)
+
+* Fri Mar 19 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-14
+- Fix UseMulticast.patch to not repeatedly parse dhcpd.conf for unicast option
+- Fix dhclient-script to set interface MTU only when it's greater than 576 (#574629)
+
+* Fri Mar 12 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-13
+- Discard unicast Request/Renew/Release/Decline message
+  (unless we set unicast option) and respond with Reply
+  with UseMulticast Status Code option (#573090)
+- Remove DHCPV6 OPERATION section from dhclient.conf.5
+  describing deprecated 'send dhcp6.oro' syntax
+
+* Thu Feb 25 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-12
+- Fix paths in man pages (#568031)
+- Remove odd tests in %%preun
+
+* Mon Feb 22 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-11
+- Add interface-mtu to the list of default requested DHCP options (#566873)
+
+* Fri Feb 19 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-10
+- Fix pm-utils/sleep.d/ directory ownership conflict
+
+* Fri Feb 19 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-9
+- In dhclient-script:
+  - use ip command options '-4' or '-6' as shortcuts for '-f[amily] inet' resp. '-f[amily] inet6'
+  - do not use IP protocol family identifier with 'ip link'
+
+* Thu Feb 18 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-8
+- Fix installation of pm-utils script (#479639, c#16)
+
+* Tue Feb 16 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-7
+- ldap-for-dhcp-4.1.1-2 (#564810)
+
+* Tue Feb 16 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-6
+- Fix ldap patch to explicitly link with liblber (#564810)
+
+* Mon Feb 08 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-5
+- Fix dhclient-decline-backoff.patch (#562854)
+
+* Fri Feb 05 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-4
+- Fix dhclient-script to delete address which the client is going to release
+  as soon as it begins the Release message exchange process (#559142)
+
+* Wed Feb 03 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-3
+- move /etc/dhcp.conf to /etc/dhcp.conf.rpmsave in %%post (#561094)
+- document -nc option in dhclient(8) man page
+
+* Tue Feb 02 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-2
+- Fix capability patch (#546765)
+
+* Wed Jan 20 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.1-1
+- Upgraded to ISC dhcp-4.1.1
+
+* Mon Jan 18 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-18
+- Hide startup info when starting dhcpd6 service.
+- Remove -TERM from calling killproc when stopping dhcrelay (#555672)
+
+* Fri Jan 15 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-17
+- Added init script to also start dhcpd for IPv6 (#552453)
+- Added dhcpd6.conf.sample
+
+* Thu Jan 07 2010 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-16
+- Use %%global instead of %%define.
+
+* Mon Dec 14 2009 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-15
+- dhclient logs its pid to make troubleshooting NM managed systems
+  with multiple dhclients running easier (#546792)
+
+* Mon Nov 23 2009 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-14
+- Honor DEFROUTE=yes|no for all connection types (#530209)
+
+* Fri Oct 30 2009 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-13
+- Make dhclient-script add IPv6 address to interface (#531997)
+
+* Tue Oct 13 2009 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-12
+- Fix 56dhclient so network comes back after suspend/hibernate (#527641)
+
+* Thu Sep 24 2009 Jiri Popelka <jpopelka@redhat.com> - 12:4.1.0p1-11
+- Make dhcpd and dhcrelay init scripts LSB compliant (#522134, #522146)
+
+* Mon Sep 21 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-10
+- Obsolete the dhcpv6 and dhcpv6-client packages
+
+* Fri Sep 18 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-9
+- Update dhclient-script with handlers for DHCPv6 states
+
+* Wed Aug 26 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-8
+- Conditionalize restorecon calls in post scriptlets (#519479)
+
+* Wed Aug 26 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-7
+- Do not require policycoreutils for post scriptlet (#519479)
+
+* Fri Aug 21 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-6
+- BR libcap-ng-devel (#517649)
+
+* Tue Aug 18 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-5
+- Drop unnecessary capabilities in dhclient (#517649)
+
+* Fri Aug 14 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-4
+- Upgrade to latest ldap-for-dhcp patch which makes sure that only
+  dhcpd links with OpenLDAP (#517474)
+
+* Wed Aug 12 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-3
+- Update NetworkManager dispatcher script to remove case conversion
+  and source /etc/sysconfig/network
+
+* Thu Aug 06 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-2
+- Add /usr/lib[64]/pm-utils/sleep.d/56dhclient to handle suspend and
+  resume with active dhclient leases (#479639)
+
+* Wed Aug 05 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0p1-1
+- Upgrade to dhcp-4.1.0p1, which is the official upstream release to fix
+  CVE-2009-0692
+
+* Wed Aug 05 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-27
+- Fix for CVE-2009-0692
+- Fix for CVE-2009-1892 (#511834)
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.1.0-26
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Thu Jul 23 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-25
+- Include NetworkManager dispatcher script to run dhclient.d scripts (#459276)
+
+* Thu Jul 09 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-24
+- Ensure 64-bit platforms parse lease file dates & times correctly (#448615)
+
+* Thu Jul 09 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-23
+- Upgrade to ldap-for-dhcp-4.1.0-4
+
+* Wed Jul 01 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-22
+- Set permissions on /etc/dhcp to 0750 (#508247)
+- Update to new ldap-for-dhcp patch set
+- Correct problems when upgrading from a previous release and your
+  dhcpd.conf file not being placed in /etc/dhcp (#506600)
+
+* Fri Jun 26 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-21
+- Handle cases in add_timeout() where the function is called with a NULL
+  value for the 'when' parameter (#506626)
+- Fix SELinux denials in dhclient-script when the script makes backup
+  configuration files and restores them later (#483747)
+
+* Wed May 06 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-20
+- Obsolete libdhcp4client <= 12:4.0.0-34.fc10 (#499290)
+
+* Mon Apr 20 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-19
+- Restrict interface names given on the dhcpd command line to length
+  IFNAMSIZ or shorter (#441524)
+- Change to /etc/sysconfig/network-scripts in dhclient-script before
+  calling need_config or source_config (#496233)
+
+* Mon Apr 20 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-18
+- Make dhclient-script work with pre-configured wireless interfaces (#491157)
+
+* Thu Apr 16 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-17
+- Fix setting default route when client IP address changes (#486512, #473658)
+- 'reload' and 'try-restart' on dhcpd and dhcrelay init scripts
+  will display usage information and return code 3
+
+* Mon Apr 13 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-16
+- Correct %%post problems in dhclient package (#495361)
+- Read hooks scripts from /etc/dhcp (#495361)
+- Update to latest ldap-for-dhcp
+
+* Fri Apr 03 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-15
+- Obsolete libdhcp and libdhcp-devel (#493547)
+
+* Thu Apr 02 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-14
+- Obsolete libdhcp and libdhcp-devel (#493547)
+
+* Tue Mar 31 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-13
+- dhclient obsoletes libdhcp4client (#493213)
+- dhcp-devel obsolets libdhcp4client-devel (#493213)
+
+* Wed Mar 11 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-12
+- Fix problems with dhclient.d script execution (#488864)
+
+* Mon Mar 09 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-11
+- Use LDAP configuration patch from upstream tarball
+
+* Thu Mar 05 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-10
+- restorecon fixes for /etc/localtime and /etc/resolv.conf (#488470)
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 12:4.1.0-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Wed Feb 18 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-8
+- Correct subsystem execution in dhclient-script (#486251)
+
+* Wed Feb 18 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-7
+- Do not segfault if the ipv6 kernel module is not loaded (#486097)
+
+* Mon Feb 16 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-6
+- Enable dhcpv6 support (#480798)
+- Fix config file migration in scriptlets (#480543)
+- Allow dhclient-script expansion with /etc/dhcp/dhclient.d/*.sh scripts
+
+* Thu Jan 15 2009 Tomas Mraz <tmraz@redhat.com> - 12:4.1.0-5
+- rebuild with new openssl
+
+* Tue Jan 13 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-4
+- Updated LSB init script header to reference /etc/dhcp/dhcpd.conf (#479012)
+
+* Sun Jan 11 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-3
+- Correct syntax errors in %%post script (#479012)
+
+* Sat Jan 10 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-2
+- Make sure all /etc/dhcp config files are marked in the manifest
+- Include new config file directies in the dhcp and dhclient packages
+- Do not overwrite new config files if they already exist
+
+* Tue Jan 06 2009 David Cantrell <dcantrell@redhat.com> - 12:4.1.0-1
+- Upgraded to ISC dhcp-4.1.0
+- Had to rename the -T option to -timeout as ISC is now using -T
+- Allow package rebuilders to easily enable DHCPv6 support with:
+      rpmbuild --with DHCPv6 dhcp.spec
+  Note that Fedora is still using the 'dhcpv6' package, but some
+  users may want to experiment with the ISC DHCPv6 implementation
+  locally.
+
+* Thu Dec 18 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-34
+- Move /etc/dhclient.conf to /etc/dhcp/dhclient.conf
+- Move /etc/dhcpd.conf to /etc/dhcp/dhcpd.conf
+
+* Thu Dec 18 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-33
+- Remove unnecessary success/failure lines in init scripts (#476846)
+
+* Wed Dec 03 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-32
+- Enable LDAP/SSL support in dhcpd (#467740)
+- Do not calculate a prefix for an address we did not receive (#473885)
+- Removed libdhcp4client because libdhcp has been removed from Fedora
+
+* Wed Oct 29 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-31
+- Use O_CLOEXEC in open(2) calls and "e" mode in fopen(3) calls, build
+  with -D_GNU_SOURCE so we pick up O_CLOEXEC (#468984)
+- Add missing prototype for validate_port() in common/inet.c
+
+* Thu Oct 23 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-30
+- Fix dhclient.conf man page and sample config file to say 'supersede
+  domain-search', which is what was actually demonstrated (#467955)
+
+* Wed Oct 01 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-29
+- Make sure /etc/resolv.conf has restorecon run on it (#451560)
+
+* Tue Sep 30 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-28
+- Forgot to actually include <errno.h> (#438149)
+
+* Tue Sep 30 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-27
+- Fix patch fuzziness and include errno.h in includes/dhcpd.h (#438149)
+
+* Tue Sep 30 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-26
+- Validate port numbers for dhclient, dhcpd, and dhcrelay to ensure
+  that are within the correct range (#438149)
+
+* Mon Sep 29 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-25
+- Fix dhcpd so it can find configuration data via LDAP (#452985)
+
+* Tue Sep 16 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-24
+- 'server' -> 'service' in dhclient-script (#462343)
+
+* Fri Aug 29 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-23
+- Prevent $metric from being set to '' (#460640)
+- Remove unnecessary warning messages
+- Do not source config file (ifcfg-DEVICE) unless it exists
+
+* Sun Aug 24 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-22
+- Add missing '[' to dhclient-script (#459860)
+- Correct test statement in add_default_gateway() in dhclient-script (#459860)
+
+* Sat Aug 23 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-21
+- Fix syntax error in dhclient-script (#459860)
+
+* Fri Aug 22 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-20
+- Rewrite of /sbin/dhclient-script (make the script a little more readable,
+  discontinue use of ifconfig in favor of ip, store backup copies of orig
+  files in /var rather than in /etc)
+
+* Wed Aug 06 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-19
+- Remove 'c' from the domain-search format string in common/tables.c
+- Prevent \032 from appearing in resolv.conf search line (#450042)
+- Restore SELinux context on saved /etc files (#451560)
+
+* Sun Aug 03 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 12:4.0.0-18
+- filter out false positive perl requires
+
+* Fri Aug 01 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-17
+- Carry over RES_OPTIONS from ifcfg-ethX files to /etc/resolv.conf (#202923)
+- Clean up Requires tags for devel packages
+- Allow SEARCH variable in ifcfg files to override search path (#454152)
+- Do not down interface if there is an active lease (#453982)
+- Clean up how dhclient-script restarts ypbind
+- Set close-on-exec on dhclient.leases for SELinux (#446632)
+
+* Sat Jun 21 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-16
+- Remove instaces of \032 in domain search option (#450042)
+- Make 'service dhcpd configtest' display text indicating the status
+
+* Fri May 16 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-15
+- Set close-on-exec on dhclient.leases for SELinux (#446632)
+
+* Tue Apr 01 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-14
+- Avoid dhclient crash when run via NetworkManager (#439796)
+
+* Tue Mar 25 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-13
+- Update dhclient-script to handle domain-search correctly (#437840)
+
+* Tue Mar 25 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-12
+- Remove Requires on openldap-server (#432180)
+- Replace CLIENTBINDIR, ETCDIR, DBDIR, and RUNDIR in the man pages with the
+  correct paths
+
+* Wed Feb 13 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-11
+- Add missing newline to usage() screen in dhclient
+
+* Thu Feb 07 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-10
+- Save conf files adding '.predhclient.$interface' to the name (#306381)
+- Only restore conf files on EXPIRE/FAIL/RELEASE/STOP if there are no other
+  dhclient processes running (#306381)
+
+* Wed Feb 06 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-9
+- Match LDAP server option values in stables.c and dhcpd.h (#431003)
+- Fix invalid sprintf() statement in server/ldap.c (#431003)
+
+* Wed Feb 06 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-8
+- Remove invalid fclose() patch
+
+* Tue Feb 05 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-7
+- Don't leak /var/lib/dhclient/dhclient.leases file descriptors (#429890)
+
+* Tue Jan 22 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-6
+- read_function() comes from the LDAP patch, so fix it there
+- Init new struct universe structs in libdhcp4client so we don't crash on
+  multiple DHCP attempts (#428203)
+
+* Thu Jan 17 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-5
+- Patch read_function() to handle size_t from read() correctly (#429207)
+
+* Wed Jan 16 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-4
+- Fix dhclient.lease file parsing problems (#428785)
+- Disable IPv6 support for now as we already ship dhcpv6 (#428987)
+
+* Tue Jan 15 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-3
+- Fix segfault in next_iface4() and next_iface6() (#428870)
+
+* Mon Jan 14 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-2
+- -fvisibility fails me again
+
+* Mon Jan 14 2008 David Cantrell <dcantrell@redhat.com> - 12:4.0.0-1
+- Upgrade to ISC dhcp-4.0.0 (#426634)
+     - first ISC release to incorporate DHCPv6 protocol support
+     - source tree now uses GNU autoconf/automake
+- Removed the libdhcp4client-static package
+