diff --git a/SOURCES/1010-shared-extend-NM_IN_STRSET-and-NM_IN_SET-rh1847814.patch b/SOURCES/1010-shared-extend-NM_IN_STRSET-and-NM_IN_SET-rh1847814.patch
new file mode 100644
index 0000000..7198d00
--- /dev/null
+++ b/SOURCES/1010-shared-extend-NM_IN_STRSET-and-NM_IN_SET-rh1847814.patch
@@ -0,0 +1,42 @@
+From 4468cfce13bdbc0ac865ee59722ed0e4f1b537a1 Mon Sep 17 00:00:00 2001
+From: Antonio Cardace <acardace@redhat.com>
+Date: Tue, 4 Aug 2020 18:36:39 +0200
+Subject: [PATCH] shared: extend NM_IN_STRSET and NM_IN_SET to support up to 20
+ args
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1847814
+(cherry picked from commit 2e70391033b5b3414491edcd8656499512342619)
+(cherry picked from commit 908d1f6cb79739f3307bfcfd64b338e215f9e4a6)
+---
+ shared/nm-glib-aux/nm-macros-internal.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/shared/nm-glib-aux/nm-macros-internal.h b/shared/nm-glib-aux/nm-macros-internal.h
+index f56ed8569..15bcd7e58 100644
+--- a/shared/nm-glib-aux/nm-macros-internal.h
++++ b/shared/nm-glib-aux/nm-macros-internal.h
+@@ -732,6 +732,10 @@ NM_G_ERROR_MSG (GError *error)
+ #define _NM_IN_SET_EVAL_14(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_13 (op, _x, __VA_ARGS__)
+ #define _NM_IN_SET_EVAL_15(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_14 (op, _x, __VA_ARGS__)
+ #define _NM_IN_SET_EVAL_16(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__)
++#define _NM_IN_SET_EVAL_17(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_16 (op, _x, __VA_ARGS__)
++#define _NM_IN_SET_EVAL_18(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_17 (op, _x, __VA_ARGS__)
++#define _NM_IN_SET_EVAL_19(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_18 (op, _x, __VA_ARGS__)
++#define _NM_IN_SET_EVAL_20(op, _x, y, ...)      (_x == (y)) op _NM_IN_SET_EVAL_19 (op, _x, __VA_ARGS__)
+ 
+ #define _NM_IN_SET_EVAL_N2(op, _x, n, ...)      (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
+ #define _NM_IN_SET_EVAL_N(op, type, x, n, ...)                      \
+@@ -798,6 +802,10 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
+ #define _NM_IN_STRSET_EVAL_14(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_13 (op, _x, __VA_ARGS__)
+ #define _NM_IN_STRSET_EVAL_15(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_14 (op, _x, __VA_ARGS__)
+ #define _NM_IN_STRSET_EVAL_16(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_15 (op, _x, __VA_ARGS__)
++#define _NM_IN_STRSET_EVAL_17(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_16 (op, _x, __VA_ARGS__)
++#define _NM_IN_STRSET_EVAL_18(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_17 (op, _x, __VA_ARGS__)
++#define _NM_IN_STRSET_EVAL_19(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_18 (op, _x, __VA_ARGS__)
++#define _NM_IN_STRSET_EVAL_20(op, _x, y, ...)   _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_19 (op, _x, __VA_ARGS__)
+ 
+ #define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...)   (_NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__))
+ #define _NM_IN_STRSET_EVAL_N(op, x, n, ...)                       \
+-- 
+2.26.2
+
diff --git a/SOURCES/1011-bond-fix-can_reapply_change-rh1847814.patch b/SOURCES/1011-bond-fix-can_reapply_change-rh1847814.patch
new file mode 100644
index 0000000..b047183
--- /dev/null
+++ b/SOURCES/1011-bond-fix-can_reapply_change-rh1847814.patch
@@ -0,0 +1,88 @@
+From 957e8465acdb9aaca0fbc797ac6df1efc2270f57 Mon Sep 17 00:00:00 2001
+From: Antonio Cardace <acardace@redhat.com>
+Date: Tue, 4 Aug 2020 18:19:47 +0200
+Subject: [PATCH] bond: fix can_reapply_change() false positives
+
+can_reapply_change() would wrongly return true for
+unsupported reapply values because it used 'nm_setting_bond_get_option_default()'
+that is ill-named because it returns the overriden option other than
+its default value.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1847814
+
+Fixes: 9bd07336ef16 ('bond: bond options logic rework')
+(cherry picked from commit 04d6ca1fb8bdbfffd70a257424f9e8c29fcb8037)
+(cherry picked from commit 63b5274dda0c52148ec8e8ca41e94e47b1e7d653)
+---
+ src/devices/nm-device-bond.c | 31 +++++++------------------------
+ 1 file changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
+index e36eba61b..164f6aaa7 100644
+--- a/src/devices/nm-device-bond.c
++++ b/src/devices/nm-device-bond.c
+@@ -516,14 +516,12 @@ create_and_realize (NMDevice *device,
+ static gboolean
+ check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error)
+ {
+-	guint i, num;
+-	const char *name = NULL, *value_a = NULL, *value_b = NULL;
++	const char **option_list;
+ 
+-	/* Check that options in @s_a have compatible changes in @s_b */
++	option_list = nm_setting_bond_get_valid_options (NULL);
+ 
+-	num = nm_setting_bond_get_num_options (s_a);
+-	for (i = 0; i < num; i++) {
+-		nm_setting_bond_get_option (s_a, i, &name, &value_a);
++	for (; *option_list; ++option_list) {
++		const char *name = *option_list;
+ 
+ 		/* We support changes to these */
+ 		if (NM_IN_STRSET (name,
+@@ -532,15 +530,9 @@ check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error)
+ 			continue;
+ 		}
+ 
+-		/* Missing in @s_b, but has a default value in @s_a */
+-		value_b = nm_setting_bond_get_option_by_name (s_b, name);
+-		if (   !value_b
+-		    && nm_streq0 (value_a, nm_setting_bond_get_option_default (s_a, name))) {
+-			continue;
+-		}
+-
+ 		/* Reject any other changes */
+-		if (!nm_streq0 (value_a, value_b)) {
++		if (!nm_streq0 (nm_setting_bond_get_option_normalized (s_a, name),
++		                nm_setting_bond_get_option_normalized (s_b, name))) {
+ 			g_set_error (error,
+ 			             NM_DEVICE_ERROR,
+ 			             NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
+@@ -562,7 +554,6 @@ can_reapply_change (NMDevice *device,
+                     GError **error)
+ {
+ 	NMDeviceClass *device_class;
+-	NMSettingBond *s_bond_old, *s_bond_new;
+ 
+ 	/* Only handle bond setting here, delegate other settings to parent class */
+ 	if (nm_streq (setting_name, NM_SETTING_BOND_SETTING_NAME)) {
+@@ -572,15 +563,7 @@ can_reapply_change (NMDevice *device,
+ 		                                        NM_SETTING_BOND_OPTIONS))
+ 			return FALSE;
+ 
+-		s_bond_old = NM_SETTING_BOND (s_old);
+-		s_bond_new = NM_SETTING_BOND (s_new);
+-
+-		if (   !check_changed_options (s_bond_old, s_bond_new, error)
+-		    || !check_changed_options (s_bond_new, s_bond_old, error)) {
+-			return FALSE;
+-		}
+-
+-		return TRUE;
++		return check_changed_options (NM_SETTING_BOND (s_old), NM_SETTING_BOND (s_new), error);
+ 	}
+ 
+ 	device_class = NM_DEVICE_CLASS (nm_device_bond_parent_class);
+-- 
+2.26.2
+
diff --git a/SOURCES/1012-bond-let-reapply-reapply-rh1847814.patch b/SOURCES/1012-bond-let-reapply-reapply-rh1847814.patch
new file mode 100644
index 0000000..32185a6
--- /dev/null
+++ b/SOURCES/1012-bond-let-reapply-reapply-rh1847814.patch
@@ -0,0 +1,216 @@
+From ff509fd95afb6f5d183eeafcc1ef467d8102181f Mon Sep 17 00:00:00 2001
+From: Antonio Cardace <acardace@redhat.com>
+Date: Tue, 4 Aug 2020 17:49:04 +0200
+Subject: [PATCH] bond: let 'reapply()' reapply all supported options
+
+Reapply now handles all the options supported by kernel and NM, meaning
+that some options are simply not allowed to be set while keeping the
+bond up, one of those options is the mode for instance.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1847814
+(cherry picked from commit 746dc119a6bceb6a08b4dc9f3798d0b59a4b8575)
+(cherry picked from commit 88a399637a5279f43fd8fc7c511547fa1d179295)
+---
+ src/devices/nm-device-bond.c | 141 +++++++++++++++++++++++++----------
+ 1 file changed, 101 insertions(+), 40 deletions(-)
+
+diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c
+index 164f6aaa7..71332ba39 100644
+--- a/src/devices/nm-device-bond.c
++++ b/src/devices/nm-device-bond.c
+@@ -183,7 +183,6 @@ master_update_slave_connection (NMDevice *self,
+ 
+ static void
+ set_arp_targets (NMDevice *device,
+-                 NMBondMode mode,
+                  const char *cur_arp_ip_target,
+                  const char *new_arp_ip_target)
+ {
+@@ -296,15 +295,39 @@ set_bond_attr_active_slave (NMDevice *device, NMSettingBond *s_bond)
+ 	_set_bond_attr (device, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, value);
+ }
+ 
++static void
++set_bond_attrs_or_default (NMDevice *device, NMSettingBond *s_bond, const char *const *attr_v)
++{
++	nm_assert (NM_IS_DEVICE (device));
++	nm_assert (s_bond);
++	nm_assert (attr_v);
++
++	for ( ; *attr_v ; ++attr_v)
++		set_bond_attr_or_default (device, s_bond, *attr_v);
++}
++
++static void
++set_bond_arp_ip_targets (NMDevice *device, NMSettingBond *s_bond)
++{
++	int           ifindex           = nm_device_get_ifindex (device);
++	gs_free char *cur_arp_ip_target = NULL;
++
++	/* ARP targets: clear and initialize the list */
++	cur_arp_ip_target = nm_platform_sysctl_master_get_option (nm_device_get_platform (device),
++	                                                          ifindex,
++	                                                          NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
++	set_arp_targets (device,
++	                 cur_arp_ip_target,
++	                 nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET));
++}
++
+ static gboolean
+ apply_bonding_config (NMDeviceBond *self)
+ {
+ 	NMDevice *device = NM_DEVICE (self);
+-	int ifindex = nm_device_get_ifindex (device);
+ 	NMSettingBond *s_bond;
+ 	NMBondMode mode;
+ 	const char *mode_str;
+-	gs_free char *cur_arp_ip_target = NULL;
+ 
+ 	s_bond = nm_device_get_applied_setting (device, NM_TYPE_SETTING_BOND);
+ 	g_return_val_if_fail (s_bond, FALSE);
+@@ -318,40 +341,34 @@ apply_bonding_config (NMDeviceBond *self)
+ 	 */
+ 	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MODE);
+ 
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MIIMON);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_UPDELAY);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_ARP_VALIDATE);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
+-
+-	/* ARP targets: clear and initialize the list */
+-	cur_arp_ip_target = nm_platform_sysctl_master_get_option (nm_device_get_platform (device),
+-	                                                          ifindex,
+-	                                                          NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
+-	set_arp_targets (device,
+-	                 mode,
+-	                 cur_arp_ip_target,
+-	                 nm_setting_bond_get_option_or_default (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET));
+-
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM);
++	set_bond_arp_ip_targets (device, s_bond);
+ 	set_bond_attr_active_slave (device, s_bond);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_AD_SELECT);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_LACP_RATE);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_LP_INTERVAL);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_MIN_LINKS);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY);
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP);
++
++	set_bond_attrs_or_default (device,
++	                           s_bond,
++	                           NM_MAKE_STRV (NM_SETTING_BOND_OPTION_MIIMON,
++	                                         NM_SETTING_BOND_OPTION_UPDELAY,
++	                                         NM_SETTING_BOND_OPTION_DOWNDELAY,
++	                                         NM_SETTING_BOND_OPTION_ARP_INTERVAL,
++	                                         NM_SETTING_BOND_OPTION_ARP_VALIDATE,
++	                                         NM_SETTING_BOND_OPTION_PRIMARY,
++	                                         NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
++	                                         NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
++	                                         NM_SETTING_BOND_OPTION_AD_SELECT,
++	                                         NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY,
++	                                         NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
++	                                         NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
++	                                         NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
++	                                         NM_SETTING_BOND_OPTION_LACP_RATE,
++	                                         NM_SETTING_BOND_OPTION_LP_INTERVAL,
++	                                         NM_SETTING_BOND_OPTION_MIN_LINKS,
++	                                         NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
++	                                         NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
++	                                         NM_SETTING_BOND_OPTION_RESEND_IGMP,
++	                                         NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB,
++	                                         NM_SETTING_BOND_OPTION_USE_CARRIER,
++	                                         NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
++	                                         NM_SETTING_BOND_OPTION_NUM_GRAT_ARP));
+ 	return TRUE;
+ }
+ 
+@@ -525,8 +542,26 @@ check_changed_options (NMSettingBond *s_a, NMSettingBond *s_b, GError **error)
+ 
+ 		/* We support changes to these */
+ 		if (NM_IN_STRSET (name,
+-		                  NM_SETTING_BOND_OPTION_ACTIVE_SLAVE,
+-		                  NM_SETTING_BOND_OPTION_PRIMARY)) {
++		                  NM_SETTING_BOND_OPTION_PRIMARY,
++		                  NM_SETTING_BOND_OPTION_MIIMON,
++		                  NM_SETTING_BOND_OPTION_UPDELAY,
++		                  NM_SETTING_BOND_OPTION_DOWNDELAY,
++		                  NM_SETTING_BOND_OPTION_ARP_INTERVAL,
++		                  NM_SETTING_BOND_OPTION_ARP_VALIDATE,
++		                  NM_SETTING_BOND_OPTION_PRIMARY,
++		                  NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
++		                  NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
++		                  NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
++		                  NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
++		                  NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
++		                  NM_SETTING_BOND_OPTION_LP_INTERVAL,
++		                  NM_SETTING_BOND_OPTION_MIN_LINKS,
++		                  NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
++		                  NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
++		                  NM_SETTING_BOND_OPTION_RESEND_IGMP,
++		                  NM_SETTING_BOND_OPTION_USE_CARRIER,
++		                  NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
++		                  NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)) {
+ 			continue;
+ 		}
+ 
+@@ -579,8 +614,8 @@ static void
+ reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_new)
+ {
+ 	NMDeviceBond *self = NM_DEVICE_BOND (device);
+-	const char *value;
+ 	NMSettingBond *s_bond;
++	const char *value;
+ 	NMBondMode mode;
+ 
+ 	NM_DEVICE_CLASS (nm_device_bond_parent_class)->reapply_connection (device,
+@@ -595,8 +630,34 @@ reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_n
+ 	mode = _nm_setting_bond_mode_from_string (value);
+ 	g_return_if_fail (mode != NM_BOND_MODE_UNKNOWN);
+ 
+-	set_bond_attr_or_default (device, s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
++	/* Below we set only the bond options that kernel allows to modify
++	 * while keeping the bond interface up */
++
+ 	set_bond_attr_active_slave (device, s_bond);
++	set_bond_arp_ip_targets (device, s_bond);
++
++	set_bond_attrs_or_default (device,
++	                           s_bond,
++	                           NM_MAKE_STRV (NM_SETTING_BOND_OPTION_PRIMARY,
++	                                         NM_SETTING_BOND_OPTION_MIIMON,
++	                                         NM_SETTING_BOND_OPTION_UPDELAY,
++	                                         NM_SETTING_BOND_OPTION_DOWNDELAY,
++	                                         NM_SETTING_BOND_OPTION_ARP_INTERVAL,
++	                                         NM_SETTING_BOND_OPTION_ARP_VALIDATE,
++	                                         NM_SETTING_BOND_OPTION_PRIMARY,
++	                                         NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM,
++	                                         NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO,
++	                                         NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE,
++	                                         NM_SETTING_BOND_OPTION_ARP_ALL_TARGETS,
++	                                         NM_SETTING_BOND_OPTION_FAIL_OVER_MAC,
++	                                         NM_SETTING_BOND_OPTION_LP_INTERVAL,
++	                                         NM_SETTING_BOND_OPTION_MIN_LINKS,
++	                                         NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE,
++	                                         NM_SETTING_BOND_OPTION_PRIMARY_RESELECT,
++	                                         NM_SETTING_BOND_OPTION_RESEND_IGMP,
++	                                         NM_SETTING_BOND_OPTION_USE_CARRIER,
++	                                         NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY,
++	                                         NM_SETTING_BOND_OPTION_NUM_GRAT_ARP));
+ }
+ 
+ /*****************************************************************************/
+-- 
+2.26.2
+
diff --git a/SOURCES/1013-dhcp6-hostname-rh1858344.patch b/SOURCES/1013-dhcp6-hostname-rh1858344.patch
new file mode 100644
index 0000000..9b345b7
--- /dev/null
+++ b/SOURCES/1013-dhcp6-hostname-rh1858344.patch
@@ -0,0 +1,444 @@
+From 40422ede3f44f4018377a81db1056fb3439107b2 Mon Sep 17 00:00:00 2001
+From: Beniamino Galvani <bgalvani@redhat.com>
+Date: Wed, 22 Jul 2020 05:03:47 +0200
+Subject: [PATCH 1/4] systemd: dhcp6: remove assertions in
+ dhcp6_option_parse_domainname()
+
+Assertions are for programming errors; here the input comes directly
+from the DHCP response packet.
+
+https://github.com/systemd/systemd/commit/af710b535b4ceacd0aecec6748a4f8ee57742e99
+(cherry picked from commit e2248143af0d4ec61e571c4f358d5d7f1044289c)
+---
+ src/systemd/src/libsystemd-network/dhcp6-option.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
+index d596752b3b91..717fcdffb815 100644
+--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
++++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
+@@ -649,8 +649,10 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
+         _cleanup_strv_free_ char **names = NULL;
+         int r;
+ 
+-        assert_return(optlen > 1, -ENODATA);
+-        assert_return(optval[optlen - 1] == '\0', -EINVAL);
++        if (optlen <= 1)
++                return -ENODATA;
++        if (optval[optlen - 1] != '\0')
++                return -EINVAL;
+ 
+         while (pos < optlen) {
+                 _cleanup_free_ char *ret = NULL;
+-- 
+2.26.2
+
+
+From ab72f05d16d641bccaa1b4870bfb91c03661f1c5 Mon Sep 17 00:00:00 2001
+From: Beniamino Galvani <bgalvani@redhat.com>
+Date: Thu, 6 Aug 2020 10:49:07 +0200
+Subject: [PATCH 2/4] systemd: dhcp6: parse the FQDN option
+
+Parse option 39 (Client Fully Qualified Domain Name, RFC 4704) from the DHCP
+reply, which specifies the FQDN assigned by the server to the client.
+
+https://github.com/systemd/systemd/commit/c43eea9f2effbb066901a61eafef473558d37b0f
+(cherry picked from commit 813fb7d64ee4cb0f935a3a15b9f5b8f5771655da)
+---
+ .../src/libsystemd-network/dhcp6-internal.h   |   5 +-
+ .../libsystemd-network/dhcp6-lease-internal.h |   2 +
+ .../src/libsystemd-network/dhcp6-option.c     | 118 ++++++++++++------
+ .../src/libsystemd-network/sd-dhcp6-client.c  |   7 ++
+ .../src/libsystemd-network/sd-dhcp6-lease.c   |  39 +++++-
+ src/systemd/src/systemd/sd-dhcp6-lease.h      |   1 +
+ 6 files changed, 129 insertions(+), 43 deletions(-)
+
+diff --git a/src/systemd/src/libsystemd-network/dhcp6-internal.h b/src/systemd/src/libsystemd-network/dhcp6-internal.h
+index b0d1216eed84..068dcade0583 100644
+--- a/src/systemd/src/libsystemd-network/dhcp6-internal.h
++++ b/src/systemd/src/libsystemd-network/dhcp6-internal.h
+@@ -109,8 +109,9 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat
+ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
+                                 struct in6_addr **addrs, size_t count,
+                                 size_t *allocated);
+-int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
+-                                  char ***str_arr);
++int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen,
++                                       char ***str_arr);
++int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str);
+ 
+ int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
+ int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
+diff --git a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
+index e004f48b4e24..df6c95e0b360 100644
+--- a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
++++ b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h
+@@ -35,6 +35,7 @@ struct sd_dhcp6_lease {
+         size_t ntp_allocated;
+         char **ntp_fqdn;
+         size_t ntp_fqdn_count;
++        char *fqdn;
+ };
+ 
+ int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
+@@ -57,5 +58,6 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
+ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen);
+ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval,
+                          size_t optlen) ;
++int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen);
+ 
+ int dhcp6_lease_new(sd_dhcp6_lease **ret);
+diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
+index 717fcdffb815..a6dad9340643 100644
+--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
++++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
+@@ -644,61 +644,103 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
+         return count;
+ }
+ 
+-int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
+-        size_t pos = 0, idx = 0;
+-        _cleanup_strv_free_ char **names = NULL;
++static int parse_domain(const uint8_t **data, uint16_t *len, char **out_domain) {
++        _cleanup_free_ char *ret = NULL;
++        size_t n = 0, allocated = 0;
++        const uint8_t *optval = *data;
++        uint16_t optlen = *len;
++        bool first = true;
+         int r;
+ 
+         if (optlen <= 1)
+                 return -ENODATA;
+-        if (optval[optlen - 1] != '\0')
+-                return -EINVAL;
+ 
+-        while (pos < optlen) {
+-                _cleanup_free_ char *ret = NULL;
+-                size_t n = 0, allocated = 0;
+-                bool first = true;
+-
+-                for (;;) {
+-                        const char *label;
+-                        uint8_t c;
++        for (;;) {
++                const char *label;
++                uint8_t c;
+ 
+-                        c = optval[pos++];
++                if (optlen == 0)
++                        break;
+ 
+-                        if (c == 0)
+-                                /* End of name */
+-                                break;
+-                        if (c > 63)
+-                                return -EBADMSG;
++                c = *optval;
++                optval++;
++                optlen--;
+ 
+-                        /* Literal label */
+-                        label = (const char *)&optval[pos];
+-                        pos += c;
+-                        if (pos >= optlen)
+-                                return -EMSGSIZE;
++                if (c == 0)
++                        /* End label */
++                        break;
++                if (c > 63)
++                        return -EBADMSG;
++                if (c > optlen)
++                        return -EMSGSIZE;
+ 
+-                        if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+-                                return -ENOMEM;
++                /* Literal label */
++                label = (const char *)optval;
++                optval += c;
++                optlen -= c;
+ 
+-                        if (first)
+-                                first = false;
+-                        else
+-                                ret[n++] = '.';
++                if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
++                        return -ENOMEM;
+ 
+-                        r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
+-                        if (r < 0)
+-                                return r;
++                if (first)
++                        first = false;
++                else
++                        ret[n++] = '.';
+ 
+-                        n += r;
+-                }
++                r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
++                if (r < 0)
++                        return r;
+ 
+-                if (n == 0)
+-                        continue;
++                n += r;
++        }
+ 
++        if (n) {
+                 if (!GREEDY_REALLOC(ret, allocated, n + 1))
+                         return -ENOMEM;
+-
+                 ret[n] = 0;
++        }
++
++        *out_domain = TAKE_PTR(ret);
++        *data = optval;
++        *len = optlen;
++
++        return n;
++}
++
++int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char **str) {
++        _cleanup_free_ char *domain = NULL;
++        int r;
++
++        r = parse_domain(&optval, &optlen, &domain);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return -ENODATA;
++        if (optlen != 0)
++                return -EINVAL;
++
++        *str = TAKE_PTR(domain);
++        return 0;
++}
++
++int dhcp6_option_parse_domainname_list(const uint8_t *optval, uint16_t optlen, char ***str_arr) {
++        size_t idx = 0;
++        _cleanup_strv_free_ char **names = NULL;
++        int r;
++
++        if (optlen <= 1)
++                return -ENODATA;
++        if (optval[optlen - 1] != '\0')
++                return -EINVAL;
++
++        while (optlen > 0) {
++                _cleanup_free_ char *ret = NULL;
++
++                r = parse_domain(&optval, &optlen, &ret);
++                if (r < 0)
++                        return r;
++                if (r == 0)
++                        continue;
+ 
+                 r = strv_extend(&names, ret);
+                 if (r < 0)
+diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+index d653b2571c00..b80e4e5406d9 100644
+--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
++++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+@@ -1288,6 +1288,13 @@ static int client_parse_message(
+ 
+                         break;
+ 
++                case SD_DHCP6_OPTION_FQDN:
++                        r = dhcp6_lease_set_fqdn(lease, optval, optlen);
++                        if (r < 0)
++                                return r;
++
++                        break;
++
+                 case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+                         if (optlen != 4)
+                                 return -EINVAL;
+diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
+index b6dc02791504..5f5a7fe616fa 100644
+--- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
++++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c
+@@ -238,7 +238,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
+         if (!optlen)
+                 return 0;
+ 
+-        r = dhcp6_option_parse_domainname(optval, optlen, &domains);
++        r = dhcp6_option_parse_domainname_list(optval, optlen, &domains);
+         if (r < 0)
+                 return 0;
+ 
+@@ -296,8 +296,8 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
+                         break;
+ 
+                 case DHCP6_NTP_SUBOPTION_SRV_FQDN:
+-                        r = dhcp6_option_parse_domainname(subval, sublen,
+-                                                          &servers);
++                        r = dhcp6_option_parse_domainname_list(subval, sublen,
++                                                               &servers);
+                         if (r < 0)
+                                 return 0;
+ 
+@@ -367,6 +367,38 @@ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn) {
+         return -ENOENT;
+ }
+ 
++int dhcp6_lease_set_fqdn(sd_dhcp6_lease *lease, const uint8_t *optval,
++                         size_t optlen) {
++        int r;
++        char *fqdn;
++
++        assert_return(lease, -EINVAL);
++        assert_return(optval, -EINVAL);
++
++        if (optlen < 2)
++                return -ENODATA;
++
++        /* Ignore the flags field, it doesn't carry any useful
++           information for clients. */
++        r = dhcp6_option_parse_domainname(optval + 1, optlen - 1, &fqdn);
++        if (r < 0)
++                return r;
++
++        return free_and_replace(lease->fqdn, fqdn);
++}
++
++int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn) {
++        assert_return(lease, -EINVAL);
++        assert_return(fqdn, -EINVAL);
++
++        if (lease->fqdn) {
++                *fqdn = lease->fqdn;
++                return 0;
++        }
++
++        return -ENOENT;
++}
++
+ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
+         assert(lease);
+ 
+@@ -375,6 +407,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
+         dhcp6_lease_free_ia(&lease->pd);
+ 
+         free(lease->dns);
++        free(lease->fqdn);
+ 
+         lease->domains = strv_free(lease->domains);
+ 
+diff --git a/src/systemd/src/systemd/sd-dhcp6-lease.h b/src/systemd/src/systemd/sd-dhcp6-lease.h
+index 4301c6db878b..240df74af8c5 100644
+--- a/src/systemd/src/systemd/sd-dhcp6-lease.h
++++ b/src/systemd/src/systemd/sd-dhcp6-lease.h
+@@ -43,6 +43,7 @@ int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **addrs)
+ int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***domains);
+ int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **addrs);
+ int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ntp_fqdn);
++int sd_dhcp6_lease_get_fqdn(sd_dhcp6_lease *lease, const char **fqdn);
+ 
+ sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
+ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
+-- 
+2.26.2
+
+
+From 98d88e272c9d49876ad2c2b1507a4fda9456531e Mon Sep 17 00:00:00 2001
+From: Beniamino Galvani <bgalvani@redhat.com>
+Date: Wed, 22 Jul 2020 13:56:39 +0200
+Subject: [PATCH 3/4] dhcp: export the DHCPv6 FQDN option
+
+The dhclient backend already exports all the option passed by
+dhclient, including the FDQN. Export it also for the systemd backend.
+
+(cherry picked from commit 1621a6ddb1b3f5c51ad774012150bd56cf65fcea)
+(cherry picked from commit c6a7618f2be4236997362db43cf44a3fdee2d9c9)
+---
+ src/dhcp/nm-dhcp-options.c | 1 +
+ src/dhcp/nm-dhcp-options.h | 2 ++
+ src/dhcp/nm-dhcp-systemd.c | 8 ++++++++
+ 3 files changed, 11 insertions(+)
+
+diff --git a/src/dhcp/nm-dhcp-options.c b/src/dhcp/nm-dhcp-options.c
+index b10635fc674a..d902c77c8c21 100644
+--- a/src/dhcp/nm-dhcp-options.c
++++ b/src/dhcp/nm-dhcp-options.c
+@@ -183,6 +183,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
+ 	REQ (NM_DHCP_OPTION_DHCP6_DNS_SERVERS,                      "dhcp6_name_servers",  TRUE ),
+ 	REQ (NM_DHCP_OPTION_DHCP6_DOMAIN_LIST,                      "dhcp6_domain_search", TRUE ),
+ 	REQ (NM_DHCP_OPTION_DHCP6_SNTP_SERVERS,                     "dhcp6_sntp_servers",  TRUE ),
++	REQ (NM_DHCP_OPTION_DHCP6_FQDN,                             "fqdn_fqdn",           FALSE ),
+ 	REQ (NM_DHCP_OPTION_DHCP6_MUD_URL,                          "dhcp6_mud_url",       FALSE ),
+ 
+ 	/* Internal values */
+diff --git a/src/dhcp/nm-dhcp-options.h b/src/dhcp/nm-dhcp-options.h
+index 7c0121702dad..bc3df5acd330 100644
+--- a/src/dhcp/nm-dhcp-options.h
++++ b/src/dhcp/nm-dhcp-options.h
+@@ -160,7 +160,9 @@ typedef enum {
+ 	NM_DHCP_OPTION_DHCP6_DNS_SERVERS       = 23,
+ 	NM_DHCP_OPTION_DHCP6_DOMAIN_LIST       = 24,
+ 	NM_DHCP_OPTION_DHCP6_SNTP_SERVERS      = 31,
++	NM_DHCP_OPTION_DHCP6_FQDN              = 39,
+ 	NM_DHCP_OPTION_DHCP6_MUD_URL           = 112,
++
+ 	/* Internal values */
+ 	NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS     = 1026,
+ 	NM_DHCP_OPTION_DHCP6_NM_PREFIXLEN      = 1027,
+diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c
+index f65937d8e035..7ee101128b43 100644
+--- a/src/dhcp/nm-dhcp-systemd.c
++++ b/src/dhcp/nm-dhcp-systemd.c
+@@ -740,6 +740,7 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
+ 	uint32_t lft_pref, lft_valid;
+ 	char addr_str[NM_UTILS_INET_ADDRSTRLEN];
+ 	char **domains;
++	const char *s;
+ 	nm_auto_free_gstring GString *str = NULL;
+ 	int num, i;
+ 
+@@ -808,6 +809,13 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
+ 		                           str->str);
+ 	}
+ 
++	if (sd_dhcp6_lease_get_fqdn (lease, &s) >= 0) {
++		nm_dhcp_option_add_option (options,
++		                           _nm_dhcp_option_dhcp6_options,
++		                           NM_DHCP_OPTION_DHCP6_FQDN,
++		                           s);
++	}
++
+ 	NM_SET_OUT (out_options, g_steal_pointer (&options));
+ 	return g_steal_pointer (&ip6_config);
+ }
+-- 
+2.26.2
+
+
+From bce988af55e0444a23a4c3881a075ff2387b798a Mon Sep 17 00:00:00 2001
+From: Beniamino Galvani <bgalvani@redhat.com>
+Date: Wed, 22 Jul 2020 13:49:42 +0200
+Subject: [PATCH 4/4] policy: get the DHCPv6 hostname from the FQDN option
+
+There isn't any 'host-name' option for DHCPv6. Read instead the
+'fqdn-fqdn' option that carries the FQDN assigned by the server to the
+client.
+
+(cherry picked from commit 1f74ea52f5818c6e7d5cacd1dffdb2e1f5ee1913)
+(cherry picked from commit 4e1da002a920888daf5bb3aa4bd21a2d61e3214b)
+---
+ src/nm-policy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/nm-policy.c b/src/nm-policy.c
+index e571034bc345..04cbace6019a 100644
+--- a/src/nm-policy.c
++++ b/src/nm-policy.c
+@@ -764,7 +764,7 @@ update_system_hostname (NMPolicy *self, const char *msg)
+ 		/* Grab a hostname out of the device's DHCP6 config */
+ 		dhcp_config = nm_device_get_dhcp_config (get_default_device (self, AF_INET6), AF_INET6);
+ 		if (dhcp_config) {
+-			dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "host_name");
++			dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "fqdn_fqdn");
+ 			if (dhcp_hostname && dhcp_hostname[0]) {
+ 				p = nm_str_skip_leading_spaces (dhcp_hostname);
+ 				if (p[0]) {
+-- 
+2.26.2
+
diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec
index e395e91..c58e91d 100644
--- a/SPECS/NetworkManager.spec
+++ b/SPECS/NetworkManager.spec
@@ -7,7 +7,7 @@
 %global epoch_version 1
 %global rpm_version 1.26.0
 %global real_version 1.26.0
-%global release_version 3
+%global release_version 4
 %global snapshot %{nil}
 %global git_sha %{nil}
 
@@ -159,6 +159,10 @@ Patch1006: 1006-n-dhcp4-fix-bpf-for-big-endian-arch-rh1861488.patch
 Patch1007: 1007-core-no-warn-setting-mtu-with-ipv6-disabled-rh1840989.patch
 Patch1008: 1008-wifi-avoid-crash-due-to-incomplete-Wi-Fi-API-info-rh1866395.patch
 Patch1009: 1009-cloud-setup-fix-allocating-buffer-for-GetConfigMetad-rh1866395.patch
+Patch1010: 1010-shared-extend-NM_IN_STRSET-and-NM_IN_SET-rh1847814.patch
+Patch1011: 1011-bond-fix-can_reapply_change-rh1847814.patch
+Patch1012: 1012-bond-let-reapply-reapply-rh1847814.patch
+Patch1013: 1013-dhcp6-hostname-rh1858344.patch
 
 # The pregenerated docs contain default values and paths that depend
 # on the configure options when creating the source tarball.
@@ -1106,7 +1110,11 @@ fi
 
 
 %changelog
-* Wed Aug  6 2020 Thomas Haller <thaller@redhat.com> - 1:1.26.0-3
+* Tue Aug 11 2020 Antonio Cardace <acardace@redhat.com> - 1:1.26.0-4
+- bond: fix Reapply does not update bond options (rh #1847814)
+- dhcp: support DHCPv6 fqdn_fqdn option for hostname (rh #1858344)
+
+* Thu Aug  6 2020 Thomas Haller <thaller@redhat.com> - 1:1.26.0-3
 - core: fix managing devices after resuming from sleep (rh #1855563)
 - dhcp: fix BPF filter for internal client on big endian arch (rh #1861488)
 - core: support warning log setting IPv6 MTU with IPv6 disabled (rh #1840989)