diff --git a/SOURCES/Consolidate-DEBUGP-macros.patch b/SOURCES/Consolidate-DEBUGP-macros.patch
new file mode 100644
index 0000000..50d0ef9
--- /dev/null
+++ b/SOURCES/Consolidate-DEBUGP-macros.patch
@@ -0,0 +1,165 @@
+From 7fcb3a907824af6220007d91ef49095f990b1733 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:15:52 +0200
+Subject: [PATCH] Consolidate DEBUGP macros
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1668475
+Upstream Status: iptables commit 78b9d438037f2
+Conflicts:
+* Context change due to missing commit 2963a8df2175b
+  ("iptables: Remove explicit static variables initalization.")
+* Dropped changes to non-existing files iptables/nft-shared.h and
+  iptables/xtables-restore.c.
+
+commit 78b9d438037f2c83a7bbb73eb1b86cc295967905
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Thu Aug 2 17:05:15 2018 +0200
+
+    Consolidate DEBUGP macros
+
+    This debug printing macro was defined in various places, always
+    identical. Move it into xshared.h and drop it from sources including
+    that header. There are a few exceptions:
+
+    * iptables-xml.c did not include xshared.h, which this patch changes.
+
+    * Sources in extensions and libiptc mostly left alone since they don't
+      include xshared.h (and maybe shouldn't). Only libxt_set.h does, so
+      it's converted, too.
+
+    This also converts DEBUG define use in libip6t_hbh.c to avoid a compiler
+    warning.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libip6t_hbh.c     | 6 ++----
+ extensions/libxt_set.h       | 6 ------
+ iptables/ip6tables-restore.c | 6 ------
+ iptables/iptables-restore.c  | 6 ------
+ iptables/iptables-xml.c      | 7 +------
+ iptables/xshared.h           | 6 ++++++
+ 6 files changed, 9 insertions(+), 28 deletions(-)
+
+diff --git a/extensions/libip6t_hbh.c b/extensions/libip6t_hbh.c
+index c0389ed8bafde..1c49ee71ada13 100644
+--- a/extensions/libip6t_hbh.c
++++ b/extensions/libip6t_hbh.c
+@@ -5,8 +5,6 @@
+ #include <xtables.h>
+ #include <linux/netfilter_ipv6/ip6t_opts.h>
+ 
+-#define DEBUG		0
+-
+ enum {
+ 	O_HBH_LEN = 0,
+ 	O_HBH_OPTS,
+@@ -83,7 +81,7 @@ parse_options(const char *optsstr, uint16_t *opts)
+                         opts[i] |= (0x00FF);
+ 		}
+ 
+-#if DEBUG
++#ifdef DEBUG
+ 		printf("opts str: %s %s\n", cp, range);
+ 		printf("opts opt: %04X\n", opts[i]);
+ #endif
+@@ -92,7 +90,7 @@ parse_options(const char *optsstr, uint16_t *opts)
+ 
+ 	free(buffer);
+ 
+-#if DEBUG
++#ifdef DEBUG
+ 	printf("addr nr: %d\n", i);
+ #endif
+ 
+diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h
+index 5a1bdcf730cf2..41dfbd30fc7c1 100644
+--- a/extensions/libxt_set.h
++++ b/extensions/libxt_set.h
+@@ -8,12 +8,6 @@
+ #include <errno.h>
+ #include "../iptables/xshared.h"
+ 
+-#ifdef DEBUG
+-#define DEBUGP(x, args...) fprintf(stderr, x , ## args)
+-#else
+-#define DEBUGP(x, args...) 
+-#endif
+-
+ static int
+ get_version(unsigned *version)
+ {
+diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
+index fdcc0cb5b2c06..611430d930eda 100644
+--- a/iptables/ip6tables-restore.c
++++ b/iptables/ip6tables-restore.c
+@@ -20,12 +20,6 @@
+ #include "libiptc/libip6tc.h"
+ #include "ip6tables-multi.h"
+ 
+-#ifdef DEBUG
+-#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+-#else
+-#define DEBUGP(x, args...)
+-#endif
+-
+ static int binary = 0, counters = 0, verbose = 0, noflush = 0, wait = 0;
+ 
+ static struct timeval wait_interval = {
+diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
+index 5a8c2c738bb0f..b0da96d45d297 100644
+--- a/iptables/iptables-restore.c
++++ b/iptables/iptables-restore.c
+@@ -17,12 +17,6 @@
+ #include "libiptc/libiptc.h"
+ #include "iptables-multi.h"
+ 
+-#ifdef DEBUG
+-#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+-#else
+-#define DEBUGP(x, args...)
+-#endif
+-
+ static int binary = 0, counters = 0, verbose = 0, noflush = 0, wait = 0;
+ 
+ static struct timeval wait_interval = {
+diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
+index 92a5768f86903..c523a132b2240 100644
+--- a/iptables/iptables-xml.c
++++ b/iptables/iptables-xml.c
+@@ -16,12 +16,7 @@
+ #include "libiptc/libiptc.h"
+ #include "xtables-multi.h"
+ #include <xtables.h>
+-
+-#ifdef DEBUG
+-#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+-#else
+-#define DEBUGP(x, args...)
+-#endif
++#include "xshared.h"
+ 
+ struct xtables_globals iptables_xml_globals = {
+ 	.option_offset = 0,
+diff --git a/iptables/xshared.h b/iptables/xshared.h
+index 20dbbd12118ad..bfdb10b2701e5 100644
+--- a/iptables/xshared.h
++++ b/iptables/xshared.h
+@@ -9,6 +9,12 @@
+ #include <linux/netfilter_ipv4/ip_tables.h>
+ #include <linux/netfilter_ipv6/ip6_tables.h>
+ 
++#ifdef DEBUG
++#define DEBUGP(x, args...) fprintf(stdout, x, ## args)
++#else
++#define DEBUGP(x, args...)
++#endif
++
+ enum {
+ 	OPT_NONE        = 0,
+ 	OPT_NUMERIC     = 1 << 0,
+-- 
+2.21.0
+
diff --git a/SOURCES/Fix-a-few-cases-of-pointless-assignments.patch b/SOURCES/Fix-a-few-cases-of-pointless-assignments.patch
new file mode 100644
index 0000000..f4b4de3
--- /dev/null
+++ b/SOURCES/Fix-a-few-cases-of-pointless-assignments.patch
@@ -0,0 +1,163 @@
+From b0c800d08b90b84d5d693d63602bcc4b43a07b6f Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:34 +0100
+Subject: [PATCH] Fix a few cases of pointless assignments
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 7e50ebabbf9c3
+Conflicts: Dropped changes to non-existing nft-backend files.
+
+commit 7e50ebabbf9c3a5eeb9511d9f32c6104b56da5cd
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:17:04 2018 +0200
+
+    Fix a few cases of pointless assignments
+
+    This gets rid of a number of assignments which are either redundant or
+    not used afterwards.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/ip6tables-restore.c |  4 ++--
+ iptables/iptables-restore.c  |  4 ++--
+ iptables/iptables-xml.c      |  4 ++--
+ libxtables/xtoptions.c       |  2 +-
+ utils/nfnl_osf.c             | 13 +++++--------
+ 5 files changed, 12 insertions(+), 15 deletions(-)
+
+diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
+index d610360a1c1ff..fdcc0cb5b2c06 100644
+--- a/iptables/ip6tables-restore.c
++++ b/iptables/ip6tables-restore.c
+@@ -427,7 +427,6 @@ int ip6tables_restore_main(int argc, char *argv[])
+ 
+ 		} else if (in_table) {
+ 			int a;
+-			char *ptr = buffer;
+ 			char *pcnt = NULL;
+ 			char *bcnt = NULL;
+ 			char *parsestart;
+@@ -437,7 +436,8 @@ int ip6tables_restore_main(int argc, char *argv[])
+ 
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+-				ptr = strchr(buffer, ']');
++				char *ptr = strchr(buffer, ']');
++
+ 				if (!ptr)
+ 					xtables_error(PARAMETER_PROBLEM,
+ 						   "Bad line %u: need ]\n",
+diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
+index db77fb77b3c98..5a8c2c738bb0f 100644
+--- a/iptables/iptables-restore.c
++++ b/iptables/iptables-restore.c
+@@ -426,7 +426,6 @@ iptables_restore_main(int argc, char *argv[])
+ 
+ 		} else if (in_table) {
+ 			int a;
+-			char *ptr = buffer;
+ 			char *pcnt = NULL;
+ 			char *bcnt = NULL;
+ 			char *parsestart;
+@@ -436,7 +435,8 @@ iptables_restore_main(int argc, char *argv[])
+ 
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+-				ptr = strchr(buffer, ']');
++				char *ptr = strchr(buffer, ']');
++
+ 				if (!ptr)
+ 					xtables_error(PARAMETER_PROBLEM,
+ 						   "Bad line %u: need ]\n",
+diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
+index 962844762fc4e..92a5768f86903 100644
+--- a/iptables/iptables-xml.c
++++ b/iptables/iptables-xml.c
+@@ -731,7 +731,6 @@ iptables_xml_main(int argc, char *argv[])
+ 			ret = 1;
+ 		} else if (curTable[0]) {
+ 			unsigned int a;
+-			char *ptr = buffer;
+ 			char *pcnt = NULL;
+ 			char *bcnt = NULL;
+ 			char *parsestart;
+@@ -747,7 +746,8 @@ iptables_xml_main(int argc, char *argv[])
+ 
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+-				ptr = strchr(buffer, ']');
++				char *ptr = strchr(buffer, ']');
++
+ 				if (!ptr)
+ 					xtables_error(PARAMETER_PROBLEM,
+ 						   "Bad line %u: need ]\n",
+diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
+index 0c63c2d372dea..1ad4cb57f5836 100644
+--- a/libxtables/xtoptions.c
++++ b/libxtables/xtoptions.c
+@@ -282,7 +282,7 @@ static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap,
+ static void xtopt_parse_mint(struct xt_option_call *cb)
+ {
+ 	const struct xt_option_entry *entry = cb->entry;
+-	const char *arg = cb->arg;
++	const char *arg;
+ 	size_t esize = xtopt_esize_by_type(entry->type);
+ 	const uintmax_t lmax = xtopt_max_by_type(entry->type);
+ 	void *put = XTOPT_MKPTR(cb);
+diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c
+index c67485ee698b1..0f8b35b805016 100644
+--- a/utils/nfnl_osf.c
++++ b/utils/nfnl_osf.c
+@@ -157,7 +157,6 @@ static void xt_osf_parse_opt(struct xt_osf_opt *opt, __u16 *optnum, char *obuf,
+ 	i = 0;
+ 	while (ptr != NULL && i < olen && *ptr != 0) {
+ 		val = 0;
+-		op = 0;
+ 		wc = OSF_WSS_PLAIN;
+ 		switch (obuf[i]) {
+ 		case 'N':
+@@ -344,7 +343,7 @@ static int osf_load_line(char *buffer, int len, int del)
+ 	pend = xt_osf_strchr(pbeg, OSFPDEL);
+ 	if (pend) {
+ 		*pend = '\0';
+-		cnt = snprintf(obuf, sizeof(obuf), "%s,", pbeg);
++		snprintf(obuf, sizeof(obuf), "%s,", pbeg);
+ 		pbeg = pend + 1;
+ 	}
+ 
+@@ -352,25 +351,23 @@ static int osf_load_line(char *buffer, int len, int del)
+ 	if (pend) {
+ 		*pend = '\0';
+ 		if (pbeg[0] == '@' || pbeg[0] == '*')
+-			cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg + 1);
++			snprintf(f.genre, sizeof(f.genre), "%s", pbeg + 1);
+ 		else
+-			cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg);
++			snprintf(f.genre, sizeof(f.genre), "%s", pbeg);
+ 		pbeg = pend + 1;
+ 	}
+ 
+ 	pend = xt_osf_strchr(pbeg, OSFPDEL);
+ 	if (pend) {
+ 		*pend = '\0';
+-		cnt = snprintf(f.version, sizeof(f.version), "%s", pbeg);
++		snprintf(f.version, sizeof(f.version), "%s", pbeg);
+ 		pbeg = pend + 1;
+ 	}
+ 
+ 	pend = xt_osf_strchr(pbeg, OSFPDEL);
+ 	if (pend) {
+ 		*pend = '\0';
+-		cnt =
+-		    snprintf(f.subtype, sizeof(f.subtype), "%s", pbeg);
+-		pbeg = pend + 1;
++		snprintf(f.subtype, sizeof(f.subtype), "%s", pbeg);
+ 	}
+ 
+ 	xt_osf_parse_opt(f.opt, &f.opt_num, obuf, sizeof(obuf));
+-- 
+2.21.0
+
diff --git a/SOURCES/Mark-fall-through-cases-in-switch-statements.patch b/SOURCES/Mark-fall-through-cases-in-switch-statements.patch
new file mode 100644
index 0000000..f4c2152
--- /dev/null
+++ b/SOURCES/Mark-fall-through-cases-in-switch-statements.patch
@@ -0,0 +1,70 @@
+From 5527530396afccc43fddedbe6fdf1b4c6000b516 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:49:11 +0100
+Subject: [PATCH] Mark fall through cases in switch() statements
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 1788f545aae28
+Conflicts: Dropped changes to non-existing libebt_log.c, nft-shared.c
+           and revision 4 of libxt_set.c.
+
+commit 1788f545aae285fa3cd6595d5d25b2ae1b215282
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:45 2018 +0200
+
+    Mark fall through cases in switch() statements
+
+    Typical covscan complaint, non-empty fall throughs should be marked as
+    such. There was but a single case which should break instead, namely in
+    libebt_log.c: It is not critical, since the next case merely asserts
+    'invert' being zero (which can't be as it was checked before). But while
+    being at it, introduce log_chk_inv() to consolidate the semantically
+    equal cases for the various log types.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_set.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c
+index 2cb9e78a85f97..ec826367d6631 100644
+--- a/extensions/libxt_set.c
++++ b/extensions/libxt_set.c
+@@ -60,6 +60,7 @@ set_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+ 	case '2':
+ 		fprintf(stderr,
+ 			"--set option deprecated, please use --match-set\n");
++		/* fall through */
+ 	case '1':		/* --match-set <set> <flag>[,<flag> */
+ 		if (info->u.flags[0])
+ 			xtables_error(PARAMETER_PROBLEM,
+@@ -140,6 +141,7 @@ set_parse_v1(int c, char **argv, int invert, unsigned int *flags,
+ 	case '2':
+ 		fprintf(stderr,
+ 			"--set option deprecated, please use --match-set\n");
++		/* fall through */
+ 	case '1':		/* --match-set <set> <flag>[,<flag> */
+ 		if (info->dim)
+ 			xtables_error(PARAMETER_PROBLEM,
+@@ -238,6 +240,7 @@ set_parse_v2(int c, char **argv, int invert, unsigned int *flags,
+ 	case '2':
+ 		fprintf(stderr,
+ 			"--set option deprecated, please use --match-set\n");
++		/* fall through */
+ 	case '1':		/* --match-set <set> <flag>[,<flag> */
+ 		if (info->dim)
+ 			xtables_error(PARAMETER_PROBLEM,
+@@ -415,6 +418,7 @@ set_parse_v3(int c, char **argv, int invert, unsigned int *flags,
+ 	case '2':
+ 		fprintf(stderr,
+ 			"--set option deprecated, please use --match-set\n");
++		/* fall through */
+ 	case '1':		/* --match-set <set> <flag>[,<flag> */
+ 		if (info->match_set.dim)
+ 			xtables_error(PARAMETER_PROBLEM,
+-- 
+2.21.0
+
diff --git a/SOURCES/Share-print_ipv-4-6-_addr-from-xtables.patch b/SOURCES/Share-print_ipv-4-6-_addr-from-xtables.patch
new file mode 100644
index 0000000..80879cc
--- /dev/null
+++ b/SOURCES/Share-print_ipv-4-6-_addr-from-xtables.patch
@@ -0,0 +1,216 @@
+From 7c53ed370c79027455b4e342436da507be701e23 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] Share print_ipv{4,6}_addr() from xtables
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 8da04ffdca193
+Conflicts:
+* Dropped changes to non-existing nft-ipv4.c and nft-ipv6.c.
+* Context change in xshared.{c,h}.
+
+commit 8da04ffdca1931402a6bc22c43c1a2fa1c6f1e14
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:59 2018 +0200
+
+    Share print_ipv{4,6}_addr() from xtables
+
+    These functions contain code which occurs in legacy's print_firewall()
+    functions, so use them there.
+
+    Rename them to at least make clear they print more than a single
+    address.
+
+    Also introduce ipv{4,6}_addr_to_string() which take care of converting
+    an address/netmask pair into string representation in a way which
+    doesn't upset covscan (since that didn't detect that 'buf' may not be
+    exceeded by the strings written into it.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/ip6tables.c | 27 +-----------------
+ iptables/iptables.c  | 25 +----------------
+ iptables/xshared.c   | 66 ++++++++++++++++++++++++++++++++++++++++++++
+ iptables/xshared.h   |  3 ++
+ 4 files changed, 71 insertions(+), 50 deletions(-)
+
+diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
+index 76e36d44f6b25..fc2fd37cfe919 100644
+--- a/iptables/ip6tables.c
++++ b/iptables/ip6tables.c
+@@ -541,7 +541,6 @@ print_firewall(const struct ip6t_entry *fw,
+ {
+ 	const struct xtables_target *target = NULL;
+ 	const struct xt_entry_target *t;
+-	char buf[BUFSIZ];
+ 
+ 	if (!ip6tc_is_chain(targname, handle))
+ 		target = xtables_find_target(targname, XTF_TRY_LOAD);
+@@ -609,31 +608,7 @@ print_firewall(const struct ip6t_entry *fw,
+ 		printf(FMT("%-6s ","out %s "), iface);
+ 	}
+ 
+-	fputc(fw->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
+-	if (!memcmp(&fw->ipv6.smsk, &in6addr_any, sizeof in6addr_any)
+-	    && !(format & FMT_NUMERIC))
+-		printf(FMT("%-19s ","%s "), "anywhere");
+-	else {
+-		if (format & FMT_NUMERIC)
+-			strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.src));
+-		else
+-			strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.src));
+-		strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.smsk));
+-		printf(FMT("%-19s ","%s "), buf);
+-	}
+-
+-	fputc(fw->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
+-	if (!memcmp(&fw->ipv6.dmsk, &in6addr_any, sizeof in6addr_any)
+-	    && !(format & FMT_NUMERIC))
+-		printf(FMT("%-19s ","-> %s"), "anywhere");
+-	else {
+-		if (format & FMT_NUMERIC)
+-			strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.dst));
+-		else
+-			strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.dst));
+-		strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.dmsk));
+-		printf(FMT("%-19s ","-> %s"), buf);
+-	}
++	print_ipv6_addresses(fw, format);
+ 
+ 	if (format & FMT_NOTABLE)
+ 		fputs("  ", stdout);
+diff --git a/iptables/iptables.c b/iptables/iptables.c
+index bac9fe0905e9f..dc70cc6e9b0ec 100644
+--- a/iptables/iptables.c
++++ b/iptables/iptables.c
+@@ -526,7 +526,6 @@ print_firewall(const struct ipt_entry *fw,
+ 	const struct xtables_target *target = NULL;
+ 	const struct xt_entry_target *t;
+ 	uint8_t flags;
+-	char buf[BUFSIZ];
+ 
+ 	if (!iptc_is_chain(targname, handle))
+ 		target = xtables_find_target(targname, XTF_TRY_LOAD);
+@@ -595,29 +594,7 @@ print_firewall(const struct ipt_entry *fw,
+ 		printf(FMT("%-6s ","out %s "), iface);
+ 	}
+ 
+-	fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
+-	if (fw->ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC))
+-		printf(FMT("%-19s ","%s "), "anywhere");
+-	else {
+-		if (format & FMT_NUMERIC)
+-			strcpy(buf, xtables_ipaddr_to_numeric(&fw->ip.src));
+-		else
+-			strcpy(buf, xtables_ipaddr_to_anyname(&fw->ip.src));
+-		strcat(buf, xtables_ipmask_to_numeric(&fw->ip.smsk));
+-		printf(FMT("%-19s ","%s "), buf);
+-	}
+-
+-	fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
+-	if (fw->ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC))
+-		printf(FMT("%-19s ","-> %s"), "anywhere");
+-	else {
+-		if (format & FMT_NUMERIC)
+-			strcpy(buf, xtables_ipaddr_to_numeric(&fw->ip.dst));
+-		else
+-			strcpy(buf, xtables_ipaddr_to_anyname(&fw->ip.dst));
+-		strcat(buf, xtables_ipmask_to_numeric(&fw->ip.dmsk));
+-		printf(FMT("%-19s ","-> %s"), buf);
+-	}
++	print_ipv4_addresses(fw, format);
+ 
+ 	if (format & FMT_NOTABLE)
+ 		fputs("  ", stdout);
+diff --git a/iptables/xshared.c b/iptables/xshared.c
+index b8a81fd968361..742502154aa55 100644
+--- a/iptables/xshared.c
++++ b/iptables/xshared.c
+@@ -340,3 +340,69 @@ inline bool xs_has_arg(int argc, char *argv[])
+ 	       argv[optind][0] != '-' &&
+ 	       argv[optind][0] != '!';
+ }
++
++static const char *ipv4_addr_to_string(const struct in_addr *addr,
++				       const struct in_addr *mask,
++				       unsigned int format)
++{
++	static char buf[BUFSIZ];
++
++	if (!mask->s_addr && !(format & FMT_NUMERIC))
++		return "anywhere";
++
++	if (format & FMT_NUMERIC)
++		strncpy(buf, xtables_ipaddr_to_numeric(addr), BUFSIZ - 1);
++	else
++		strncpy(buf, xtables_ipaddr_to_anyname(addr), BUFSIZ - 1);
++	buf[BUFSIZ - 1] = '\0';
++
++	strncat(buf, xtables_ipmask_to_numeric(mask),
++		BUFSIZ - strlen(buf) - 1);
++
++	return buf;
++}
++
++void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format)
++{
++	fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
++	printf(FMT("%-19s ", "%s "),
++	       ipv4_addr_to_string(&fw->ip.src, &fw->ip.smsk, format));
++
++	fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
++	printf(FMT("%-19s ", "-> %s"),
++	       ipv4_addr_to_string(&fw->ip.dst, &fw->ip.dmsk, format));
++}
++
++static const char *ipv6_addr_to_string(const struct in6_addr *addr,
++				       const struct in6_addr *mask,
++				       unsigned int format)
++{
++	static char buf[BUFSIZ];
++
++	if (IN6_IS_ADDR_UNSPECIFIED(addr) && !(format & FMT_NUMERIC))
++		return "anywhere";
++
++	if (format & FMT_NUMERIC)
++		strncpy(buf, xtables_ip6addr_to_numeric(addr), BUFSIZ - 1);
++	else
++		strncpy(buf, xtables_ip6addr_to_anyname(addr), BUFSIZ - 1);
++	buf[BUFSIZ - 1] = '\0';
++
++	strncat(buf, xtables_ip6mask_to_numeric(mask),
++		BUFSIZ - strlen(buf) - 1);
++
++	return buf;
++}
++
++void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format)
++{
++	fputc(fw6->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
++	printf(FMT("%-19s ", "%s "),
++	       ipv6_addr_to_string(&fw6->ipv6.src,
++				   &fw6->ipv6.smsk, format));
++
++	fputc(fw6->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
++	printf(FMT("%-19s ", "-> %s"),
++	       ipv6_addr_to_string(&fw6->ipv6.dst,
++				   &fw6->ipv6.dmsk, format));
++}
+diff --git a/iptables/xshared.h b/iptables/xshared.h
+index c35dfee47577d..20dbbd12118ad 100644
+--- a/iptables/xshared.h
++++ b/iptables/xshared.h
+@@ -113,4 +113,7 @@ bool xs_has_arg(int argc, char *argv[]);
+ 
+ extern const struct xtables_afinfo *afinfo;
+ 
++void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
++void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
++
+ #endif /* IPTABLES_XSHARED_H */
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-Add-macro-_DEFAULT_SOURCE.patch b/SOURCES/extensions-Add-macro-_DEFAULT_SOURCE.patch
new file mode 100644
index 0000000..06a1fc9
--- /dev/null
+++ b/SOURCES/extensions-Add-macro-_DEFAULT_SOURCE.patch
@@ -0,0 +1,60 @@
+From 3dcd69e5655a2485d39efd64b5bd9fd38fdb4a04 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:52:42 +0100
+Subject: [PATCH] extensions: Add macro _DEFAULT_SOURCE.
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 27de281d8aca8
+
+commit 27de281d8aca84e3c841b3ae72a17616b1382ac4
+Author: Varsha Rao <rvarsha016@gmail.com>
+Date:   Thu Dec 21 09:05:45 2017 +0530
+
+    extensions: Add macro _DEFAULT_SOURCE.
+
+    Define _DEFAULT_SOURCE as _BSD_SOURCE is deprecated.
+    https://sourceware.org/glibc/wiki/Release/2.20#Packaging_Changes
+
+    This patch fixes the following warning:
+
+    warning: #warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use
+    _DEFAULT_SOURCE" [-Wcpp]
+     # warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use
+     # _DEFAULT_SOURCE"
+
+    Signed-off-by: Varsha Rao <rvarsha016@gmail.com>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_hashlimit.c | 1 +
+ extensions/libxt_limit.c     | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c
+index c5b8d7795c5e5..6d64017022c00 100644
+--- a/extensions/libxt_hashlimit.c
++++ b/extensions/libxt_hashlimit.c
+@@ -11,6 +11,7 @@
+  * Error corections by nmalykh@bilim.com (22.01.2005)
+  */
+ #define _BSD_SOURCE 1
++#define _DEFAULT_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #include <math.h>
+ #include <stdbool.h>
+diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c
+index f75ef2f87a74c..183a86e324211 100644
+--- a/extensions/libxt_limit.c
++++ b/extensions/libxt_limit.c
+@@ -4,6 +4,7 @@
+  * Hervé Eychenne    <rv@wallfire.org>
+  */
+ #define _BSD_SOURCE 1
++#define _DEFAULT_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #include <math.h>
+ #include <stdio.h>
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-Fix-ipvs-vproto-option-printing.patch b/SOURCES/extensions-Fix-ipvs-vproto-option-printing.patch
new file mode 100644
index 0000000..148cf4e
--- /dev/null
+++ b/SOURCES/extensions-Fix-ipvs-vproto-option-printing.patch
@@ -0,0 +1,42 @@
+From 21ef09de8df5a448df06a3fb6c7708440fe8b8ac Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:19:53 +0200
+Subject: [PATCH] extensions: Fix ipvs vproto option printing
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1679726
+Upstream Status: iptables commit dd1ad59f0df66
+
+commit dd1ad59f0df66811335c10ed90c33151a658a50e
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Thu Feb 21 20:09:31 2019 +0100
+
+    extensions: Fix ipvs vproto option printing
+
+    This was broken since day 1: vproto option was printed as 'proto' which
+    in turn iptables wouldn't accept anymore.
+
+    Fixes: c36d05e424069 ("libxt_ipvs: user-space lib for netfilter matcher xt_ipvs")
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_ipvs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/extensions/libxt_ipvs.c b/extensions/libxt_ipvs.c
+index fe98fef951686..51952be4245b3 100644
+--- a/extensions/libxt_ipvs.c
++++ b/extensions/libxt_ipvs.c
+@@ -165,7 +165,7 @@ static void ipvs_mt_dump(const void *ip, const struct xt_ipvs_mtinfo *data,
+ 	if (data->bitmask & XT_IPVS_PROTO) {
+ 		if (data->invert & XT_IPVS_PROTO)
+ 			printf(" !");
+-		printf(" %sproto %u", prefix, data->l4proto);
++		printf(" %svproto %u", prefix, data->l4proto);
+ 	}
+ 
+ 	if (data->bitmask & XT_IPVS_VADDR) {
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-Fix-ipvs-vproto-parsing.patch b/SOURCES/extensions-Fix-ipvs-vproto-parsing.patch
new file mode 100644
index 0000000..93109a2
--- /dev/null
+++ b/SOURCES/extensions-Fix-ipvs-vproto-parsing.patch
@@ -0,0 +1,57 @@
+From dab2ab10ed0cb30fb454097200f440660a0f3946 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:19:53 +0200
+Subject: [PATCH] extensions: Fix ipvs vproto parsing
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1679726
+Upstream Status: iptables commit fcbdc69e8a750
+
+commit fcbdc69e8a750fe02c9d7c7aced0efc91715132d
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Thu Feb 21 20:09:30 2019 +0100
+
+    extensions: Fix ipvs vproto parsing
+
+    This was broken by integration into guided option parser:
+
+    * Make 'vproto' option XTTYPE_PROTOCOL, otherwise its arguments are
+      parsed as garbage only.
+
+    * Drop O_VPROTO case from ipvs_mt_parse(), due to XTOPT_POINTER() and
+      above change there is nothing to do for it in there.
+
+    Fixes: 372203af4c70f ("libxt_ipvs: use guided option parser")
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_ipvs.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/extensions/libxt_ipvs.c b/extensions/libxt_ipvs.c
+index a6c57a030d2c6..fe98fef951686 100644
+--- a/extensions/libxt_ipvs.c
++++ b/extensions/libxt_ipvs.c
+@@ -27,7 +27,7 @@ enum {
+ static const struct xt_option_entry ipvs_mt_opts[] = {
+ 	{.name = "ipvs", .id = O_IPVS, .type = XTTYPE_NONE,
+ 	 .flags = XTOPT_INVERT},
+-	{.name = "vproto", .id = O_VPROTO, .type = XTTYPE_STRING,
++	{.name = "vproto", .id = O_VPROTO, .type = XTTYPE_PROTOCOL,
+ 	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, l4proto)},
+ 	{.name = "vaddr", .id = O_VADDR, .type = XTTYPE_HOSTMASK,
+ 	 .flags = XTOPT_INVERT},
+@@ -69,9 +69,6 @@ static void ipvs_mt_parse(struct xt_option_call *cb)
+ 
+ 	xtables_option_parse(cb);
+ 	switch (cb->entry->id) {
+-	case O_VPROTO:
+-		data->l4proto = cb->val.protocol;
+-		break;
+ 	case O_VADDR:
+ 		memcpy(&data->vaddr, &cb->val.haddr, sizeof(cb->val.haddr));
+ 		memcpy(&data->vmask, &cb->val.hmask, sizeof(cb->val.hmask));
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-Initialize-linear-mapping-of-symbols-in-_.patch b/SOURCES/extensions-Initialize-linear-mapping-of-symbols-in-_.patch
new file mode 100644
index 0000000..8752cae
--- /dev/null
+++ b/SOURCES/extensions-Initialize-linear-mapping-of-symbols-in-_.patch
@@ -0,0 +1,139 @@
+From 861155bef2343e0259469dc8e4acde60e2c6fb91 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:29:38 +0200
+Subject: [PATCH] extensions: Initialize linear mapping of symbols in _init()
+ of extension
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1657075
+Upstream Status: iptables commit 56aadc01b258e
+Conflicts: Whitespace change due to missing commit f7c26137b0d57
+           ("extensions: libipt_realm: Add translation to nft").
+
+commit 56aadc01b258ef7849463723ab5ddc4885db22f6
+Author: Serhey Popovych <serhe.popovych@gmail.com>
+Date:   Thu Mar 1 13:03:10 2018 +0200
+
+    extensions: Initialize linear mapping of symbols in _init() of extension
+
+    libxt_devgroup and libipt_realm currently unable to display symbolic
+    names in save/print commands because linear mapping is not initialized.
+
+    It looks bit confusing as linear mapping initialization is done in init()
+    of extension, which is expected to be called before any other function of
+    extension.
+
+    However init is called only when '-m' option specified on command line,
+    that is true only for insert, append, replace and destroy iptables
+    commands.
+
+    Move initialization to extension _init() function before calling
+    any function in extension.
+
+    Before:
+    -------
+    ... src-group 0x1 dst-group 0x2
+    ... src-group 0x2 dst-group 0x1
+
+    After:
+    ------
+    ... src-group grp1 dst-group grp2
+    ... src-group grp2 dst-group grp1
+
+    Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libipt_realm.c   | 17 +++++++----------
+ extensions/libxt_devgroup.c | 17 +++++++----------
+ 2 files changed, 14 insertions(+), 20 deletions(-)
+
+diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
+index a8d9dda0c00c0..fffb1218db7a6 100644
+--- a/extensions/libipt_realm.c
++++ b/extensions/libipt_realm.c
+@@ -28,17 +28,10 @@ static const struct xt_option_entry realm_opts[] = {
+ 	XTOPT_TABLEEND,
+ };
+ 
+-/* array of realms from /etc/iproute2/rt_realms */
++static const char f_realms[] = "/etc/iproute2/rt_realms";
++/* array of realms from f_realms[] */
+ static struct xtables_lmap *realms;
+ 
+-static void realm_init(struct xt_entry_match *m)
+-{
+-	const char file[] = "/etc/iproute2/rt_realms";
+-	realms = xtables_lmap_init(file);
+-	if (realms == NULL && errno != ENOENT)
+-		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
+-}
+-
+ static void realm_parse(struct xt_option_call *cb)
+ {
+ 	struct xt_realm_info *realminfo = cb->data;
+@@ -114,7 +107,6 @@ static struct xtables_match realm_mt_reg = {
+ 	.size		= XT_ALIGN(sizeof(struct xt_realm_info)),
+ 	.userspacesize	= XT_ALIGN(sizeof(struct xt_realm_info)),
+ 	.help		= realm_help,
+-	.init		= realm_init,
+ 	.print		= realm_print,
+ 	.save		= realm_save,
+ 	.x6_parse	= realm_parse,
+@@ -123,5 +115,10 @@ static struct xtables_match realm_mt_reg = {
+ 
+ void _init(void)
+ {
++	realms = xtables_lmap_init(f_realms);
++	if (realms == NULL && errno != ENOENT)
++		fprintf(stderr, "Warning: %s: %s\n", f_realms,
++			strerror(errno));
++
+ 	xtables_register_match(&realm_mt_reg);
+ }
+diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c
+index fb1fcb51c1bb2..ebfa2aee80cf2 100644
+--- a/extensions/libxt_devgroup.c
++++ b/extensions/libxt_devgroup.c
+@@ -31,17 +31,10 @@ static const struct xt_option_entry devgroup_opts[] = {
+ 	XTOPT_TABLEEND,
+ };
+ 
+-/* array of devgroups from /etc/iproute2/group */
++static const char f_devgroups[] = "/etc/iproute2/group";
++/* array of devgroups from f_devgroups[] */
+ static struct xtables_lmap *devgroups;
+ 
+-static void devgroup_init(struct xt_entry_match *match)
+-{
+-	const char file[] = "/etc/iproute2/group";
+-	devgroups = xtables_lmap_init(file);
+-	if (devgroups == NULL && errno != ENOENT)
+-		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
+-}
+-
+ static void devgroup_parse_groupspec(const char *arg, unsigned int *group,
+ 				     unsigned int *mask)
+ {
+@@ -157,7 +150,6 @@ static struct xtables_match devgroup_mt_reg = {
+ 	.family		= NFPROTO_UNSPEC,
+ 	.size		= XT_ALIGN(sizeof(struct xt_devgroup_info)),
+ 	.userspacesize	= XT_ALIGN(sizeof(struct xt_devgroup_info)),
+-	.init		= devgroup_init,
+ 	.help		= devgroup_help,
+ 	.print		= devgroup_print,
+ 	.save		= devgroup_save,
+@@ -168,5 +160,10 @@ static struct xtables_match devgroup_mt_reg = {
+ 
+ void _init(void)
+ {
++	devgroups = xtables_lmap_init(f_devgroups);
++	if (devgroups == NULL && errno != ENOENT)
++		fprintf(stderr, "Warning: %s: %s\n", f_devgroups,
++			strerror(errno));
++
+ 	xtables_register_match(&devgroup_mt_reg);
+ }
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-REJECT-Check-for-array-overrun.patch b/SOURCES/extensions-REJECT-Check-for-array-overrun.patch
new file mode 100644
index 0000000..58bf9da
--- /dev/null
+++ b/SOURCES/extensions-REJECT-Check-for-array-overrun.patch
@@ -0,0 +1,72 @@
+From 20f5f3c0c3b4cebc60af3d2def0ac983f54bfb06 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:52:01 +0100
+Subject: [PATCH] extensions: REJECT: Check for array overrun
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: RHEL-only
+
+This might happen in theory if enum ip6t_reject_with was extended in
+kernel and some other tool added a rule making use of the new value.
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libip6t_REJECT.c | 8 ++++++++
+ extensions/libipt_REJECT.c  | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/extensions/libip6t_REJECT.c b/extensions/libip6t_REJECT.c
+index 8085321a6d654..86f2d04296294 100644
+--- a/extensions/libip6t_REJECT.c
++++ b/extensions/libip6t_REJECT.c
+@@ -104,6 +104,10 @@ static void REJECT_print(const void *ip, const struct xt_entry_target *target,
+ 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ 		if (reject_table[i].with == reject->with)
+ 			break;
++	if (i == ARRAY_SIZE(reject_table))
++		xtables_error(VERSION_PROBLEM,
++			      "unknown reject type %d in ruleset",
++			      reject->with);
+ 	printf(" reject-with %s", reject_table[i].name);
+ }
+ 
+@@ -116,6 +120,10 @@ static void REJECT_save(const void *ip, const struct xt_entry_target *target)
+ 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ 		if (reject_table[i].with == reject->with)
+ 			break;
++	if (i == ARRAY_SIZE(reject_table))
++		xtables_error(VERSION_PROBLEM,
++			      "unknown reject type %d in ruleset",
++			      reject->with);
+ 
+ 	printf(" --reject-with %s", reject_table[i].name);
+ }
+diff --git a/extensions/libipt_REJECT.c b/extensions/libipt_REJECT.c
+index 362c65ed88e96..5573ebd28022c 100644
+--- a/extensions/libipt_REJECT.c
++++ b/extensions/libipt_REJECT.c
+@@ -124,6 +124,10 @@ static void REJECT_print(const void *ip, const struct xt_entry_target *target,
+ 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ 		if (reject_table[i].with == reject->with)
+ 			break;
++	if (i == ARRAY_SIZE(reject_table))
++		xtables_error(VERSION_PROBLEM,
++			      "unknown reject type %d in ruleset",
++			      reject->with);
+ 	printf(" reject-with %s", reject_table[i].name);
+ }
+ 
+@@ -136,6 +140,10 @@ static void REJECT_save(const void *ip, const struct xt_entry_target *target)
+ 	for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ 		if (reject_table[i].with == reject->with)
+ 			break;
++	if (i == ARRAY_SIZE(reject_table))
++		xtables_error(VERSION_PROBLEM,
++			      "unknown reject type %d in ruleset",
++			      reject->with);
+ 
+ 	printf(" --reject-with %s", reject_table[i].name);
+ }
+-- 
+2.21.0
+
diff --git a/SOURCES/extensions-libxt_devgroup-Fix-the-path-of-the-group-.patch b/SOURCES/extensions-libxt_devgroup-Fix-the-path-of-the-group-.patch
new file mode 100644
index 0000000..9a14186
--- /dev/null
+++ b/SOURCES/extensions-libxt_devgroup-Fix-the-path-of-the-group-.patch
@@ -0,0 +1,48 @@
+From 2c7f817f6dc2d74d99248403b0ef7e36bcf060c8 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:29:38 +0200
+Subject: [PATCH] extensions: libxt_devgroup: Fix the path of the group
+ mappings file
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1657075
+Upstream Status: iptables commit 93ad9ea1b86bd
+
+commit 93ad9ea1b86bdaacffd8e33654abcea3d4e148b2
+Author: Ana Rey <anarey@gmail.com>
+Date:   Thu Sep 18 13:06:42 2014 +0200
+
+    extensions: libxt_devgroup: Fix the path of the group mappings file
+
+    Use "/etc/iproute2/group" as the default path to the mapping file
+    instead of "/etc/iproute2/group_map".
+
+    Signed-off-by: Ana Rey <anarey@gmail.com>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_devgroup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c
+index 4a69c8229ce4a..fb1fcb51c1bb2 100644
+--- a/extensions/libxt_devgroup.c
++++ b/extensions/libxt_devgroup.c
+@@ -31,12 +31,12 @@ static const struct xt_option_entry devgroup_opts[] = {
+ 	XTOPT_TABLEEND,
+ };
+ 
+-/* array of devgroups from /etc/iproute2/group_map */
++/* array of devgroups from /etc/iproute2/group */
+ static struct xtables_lmap *devgroups;
+ 
+ static void devgroup_init(struct xt_entry_match *match)
+ {
+-	const char file[] = "/etc/iproute2/group_map";
++	const char file[] = "/etc/iproute2/group";
+ 	devgroups = xtables_lmap_init(file);
+ 	if (devgroups == NULL && errno != ENOENT)
+ 		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
+-- 
+2.21.0
+
diff --git a/SOURCES/ip-6-tables-restore-Fix-for-uninitialized-array-curt.patch b/SOURCES/ip-6-tables-restore-Fix-for-uninitialized-array-curt.patch
new file mode 100644
index 0000000..4401ada
--- /dev/null
+++ b/SOURCES/ip-6-tables-restore-Fix-for-uninitialized-array-curt.patch
@@ -0,0 +1,57 @@
+From 721bb877b759a0c92e6b019447fd3ee33d123cc0 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] ip{, 6}tables-restore: Fix for uninitialized array 'curtable'
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 4e499d53d558b
+
+commit 4e499d53d558bed55c8fe74390250dbfd6da3efc
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:46 2018 +0200
+
+    ip{, 6}tables-restore: Fix for uninitialized array 'curtable'
+
+    When reading sufficiently malformed input, parser might hit end of
+    loop without having written the current table name into curtable and
+    therefore calling strcmp() with uninitialized buffer. Avoid this by
+    setting curtable to zero upon declaration.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/ip6tables-restore.c | 2 +-
+ iptables/iptables-restore.c  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
+index e2a82c57bd426..d610360a1c1ff 100644
+--- a/iptables/ip6tables-restore.c
++++ b/iptables/ip6tables-restore.c
+@@ -192,7 +192,7 @@ int ip6tables_restore_main(int argc, char *argv[])
+ 	struct xtc_handle *handle = NULL;
+ 	char buffer[10240];
+ 	int c, lock;
+-	char curtable[XT_TABLE_MAXNAMELEN + 1];
++	char curtable[XT_TABLE_MAXNAMELEN + 1] = {};
+ 	FILE *in;
+ 	int in_table = 0, testing = 0;
+ 	const char *tablename = NULL;
+diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
+index af0c79408631d..db77fb77b3c98 100644
+--- a/iptables/iptables-restore.c
++++ b/iptables/iptables-restore.c
+@@ -191,7 +191,7 @@ iptables_restore_main(int argc, char *argv[])
+ 	struct xtc_handle *handle = NULL;
+ 	char buffer[10240];
+ 	int c, lock;
+-	char curtable[XT_TABLE_MAXNAMELEN + 1];
++	char curtable[XT_TABLE_MAXNAMELEN + 1] = {};
+ 	FILE *in;
+ 	int in_table = 0, testing = 0;
+ 	const char *tablename = NULL;
+-- 
+2.21.0
+
diff --git a/SOURCES/iptables-config b/SOURCES/iptables-config
index 0237281..3d7e176 100644
--- a/SOURCES/iptables-config
+++ b/SOURCES/iptables-config
@@ -5,13 +5,6 @@
 # stored in /etc/modprobe.conf.
 IPTABLES_MODULES=""
 
-# Unload modules on restart and stop
-#   Value: yes|no,  default: yes
-# This option has to be 'yes' to get to a sane state for a firewall
-# restart or stop. Only set to 'no' if there are problems unloading netfilter
-# modules.
-IPTABLES_MODULES_UNLOAD="yes"
-
 # Save current firewall rules on stop.
 #   Value: yes|no,  default: no
 # Saves all firewall rules to /etc/sysconfig/iptables if firewall gets stopped
diff --git a/SOURCES/iptables-xml-fix-segfault-if-missing-space-after-A.patch b/SOURCES/iptables-xml-fix-segfault-if-missing-space-after-A.patch
new file mode 100644
index 0000000..033870c
--- /dev/null
+++ b/SOURCES/iptables-xml-fix-segfault-if-missing-space-after-A.patch
@@ -0,0 +1,50 @@
+From c360c1d2af887c8e614ec152fb64717e56fb472d Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Tue, 9 Apr 2019 15:22:44 +0200
+Subject: [PATCH] iptables-xml: fix segfault if missing space after -A
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit f53b78e423d82
+
+commit f53b78e423d82b0c71c076480f52edeb5eaec5f8
+Author: Phil Oester <kernel@linuxace.com>
+Date:   Thu Jan 23 22:06:58 2014 -0800
+
+    iptables-xml: fix segfault if missing space after -A
+
+    As pointed out by Bernhard Reutner-Fischer, a malformed line fed to
+    iptables-xml such as the below with a missing space after the -A:
+
+            -APOSTROUTING -d 1.1.1.1/32 -p tcp -j MASQUERADE
+
+    causes a segfault.  Patch attached.
+
+    This closes netfilter bugzilla #886.
+
+    Signed-off-by: Phil Oester <kernel@linuxace.com>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/iptables-xml.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
+index 49f8ea2826181..769f76550b764 100644
+--- a/iptables/iptables-xml.c
++++ b/iptables/iptables-xml.c
+@@ -777,6 +777,11 @@ iptables_xml_main(int argc, char *argv[])
+ 			for (a = 0; a < newargc; a++)
+ 				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+ 
++			if (!chain) {
++				fprintf(stderr, "%s: line %u failed - no chain found\n",
++					prog_name, line);
++				exit(1);
++			}
+ 			needChain(chain);// Should we explicitly look for -A
+ 			do_rule(pcnt, bcnt, newargc, newargv, newargvattr);
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/iptables.init b/SOURCES/iptables.init
index 73656d3..c0f15f1 100755
--- a/SOURCES/iptables.init
+++ b/SOURCES/iptables.init
@@ -43,14 +43,8 @@ if [ ! -x /sbin/$IPTABLES ]; then
     exit 5
 fi
 
-# Old or new modutils
-/sbin/modprobe --version 2>&1 | grep -q 'kmod version' \
-    && NEW_MODUTILS=1 \
-    || NEW_MODUTILS=0
-
 # Default firewall configuration:
 IPTABLES_MODULES=""
-IPTABLES_MODULES_UNLOAD="yes"
 IPTABLES_SAVE_ON_STOP="no"
 IPTABLES_SAVE_ON_RESTART="no"
 IPTABLES_SAVE_COUNTER="no"
@@ -64,10 +58,6 @@ IPTABLES_RESTORE_WAIT_INTERVAL=1000000
 # Load firewall configuration.
 [ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG"
 
-# Netfilter modules
-NF_MODULES=($(lsmod | awk "/^${IPV}table_/ {print \$1}") ${IPV}_tables)
-NF_MODULES_COMMON=(x_tables nf_nat nf_conntrack) # Used by netfilter v4 and v6
-
 # Get active tables
 NF_TABLES=$(cat "$PROC_IPTABLES_NAMES" 2>/dev/null)
 
@@ -83,38 +73,6 @@ if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then
 	IPTABLES_RESTORE_CMD+=" $OPT"
 fi
 
-rmmod_r() {
-    # Unload module with all referring modules.
-    # At first all referring modules will be unloaded, then the module itself.
-    local mod=$1
-    local ret=0
-    local ref=
-
-    # Get referring modules.
-    # New modutils have another output format.
-    [ $NEW_MODUTILS = 1 ] \
-	&& ref=$(lsmod | awk "/^${mod}/ { print \$4; }" | tr ',' ' ') \
-	|| ref=$(lsmod | grep ^${mod} | cut -d "[" -s -f 2 | cut -d "]" -s -f 1)
-
-    # recursive call for all referring modules
-    for i in $ref; do
-	rmmod_r $i
-	let ret+=$?;
-    done
-
-    # Unload module.
-    # The extra test is for 2.6: The module might have autocleaned,
-    # after all referring modules are unloaded.
-    if grep -q "^${mod}" /proc/modules ; then
-	modprobe -r $mod > /dev/null 2>&1
-	res=$?
-	[ $res -eq 0 ] || echo -n " $mod"
-	let ret+=$res;
-    fi
-
-    return $ret
-}
-
 flush_n_delete() {
     local ret=0
 
@@ -290,23 +248,6 @@ stop() {
     flush_n_delete
     let ret+=$?
     
-    if [ "x$IPTABLES_MODULES_UNLOAD" = "xyes" ]; then
-	echo -n $"${IPTABLES}: Unloading modules: "
-	ret2=0
-	for mod in ${NF_MODULES[*]}; do
-	    rmmod_r $mod
-	    let ret2+=$?;
-	done
-	# try to unload remaining netfilter modules used by ipv4 and ipv6 
-	# netfilter
-	for mod in ${NF_MODULES_COMMON[*]}; do
-	    rmmod_r $mod >/dev/null
-	done
-	[ $ret2 -eq 0 ] && success || failure
-	echo
-        let ret+=$ret2
-    fi
-    
     rm -f $VAR_SUBSYS_IPTABLES
     return $ret
 }
@@ -357,7 +298,7 @@ save() {
 }
 
 status() {
-    if [ ! -f "$VAR_SUBSYS_IPTABLES" -a -z "$NF_TABLES" ]; then
+    if [ ! -f "$VAR_SUBSYS_IPTABLES" ] && [ -z "$NF_TABLES" ]; then
 	echo $"${IPTABLES}: Firewall is not running."
 	return 3
     fi
@@ -378,7 +319,7 @@ status() {
 
     NUM=
     [ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n"
-    VERBOSE= 
+    VERBOSE=
     [ "x$IPTABLES_STATUS_VERBOSE" = "xyes" ] && VERBOSE="--verbose"
     COUNT=
     [ "x$IPTABLES_STATUS_LINENUMBERS" = "xyes" ] && COUNT="--line-numbers"
diff --git a/SOURCES/libiptc-Avoid-side-effect-in-memset-calls.patch b/SOURCES/libiptc-Avoid-side-effect-in-memset-calls.patch
new file mode 100644
index 0000000..f6ab7df
--- /dev/null
+++ b/SOURCES/libiptc-Avoid-side-effect-in-memset-calls.patch
@@ -0,0 +1,59 @@
+From 72859f25cb799ba4ac0b532c59bd01be70950f00 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libiptc: Avoid side-effect in memset() calls
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit e6f986762667e
+
+commit e6f986762667ee2b2d61e7978d460f28916158a3
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 10 23:35:14 2018 +0200
+
+    libiptc: Avoid side-effect in memset() calls
+
+    These calls to memset() are passed a length argument which exceeds
+    t->target.u.user.name's length by one byte and hence overwrite
+    t->target.u.user.revision as well (relying upon no padding to happen
+    between both).
+
+    Avoid this obscure behaviour by passing the correct field size and
+    explicitly overwriting 'revision' field.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libiptc/libiptc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
+index d2427c16a5254..4c0fbd5d7e68c 100644
+--- a/libiptc/libiptc.c
++++ b/libiptc/libiptc.c
+@@ -1115,8 +1115,9 @@ static inline int iptcc_compile_rule (struct xtc_handle *h, STRUCT_REPLACE *repl
+ 		STRUCT_STANDARD_TARGET *t;
+ 		t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
+ 		/* memset for memcmp convenience on delete/replace */
+-		memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
++		memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
+ 		strcpy(t->target.u.user.name, STANDARD_TARGET);
++		t->target.u.user.revision = 0;
+ 		/* Jumps can only happen to builtin chains, so we
+ 		 * can safely assume that they always have a header */
+ 		t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE;
+@@ -1676,8 +1677,9 @@ iptcc_standard_map(struct rule_head *r, int verdict)
+ 		return 0;
+ 	}
+ 	/* memset for memcmp convenience on delete/replace */
+-	memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
++	memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
+ 	strcpy(t->target.u.user.name, STANDARD_TARGET);
++	t->target.u.user.revision = 0;
+ 	t->verdict = verdict;
+ 
+ 	r->type = IPTCC_R_STANDARD;
+-- 
+2.21.0
+
diff --git a/SOURCES/libiptc-NULL-terminate-errorname.patch b/SOURCES/libiptc-NULL-terminate-errorname.patch
new file mode 100644
index 0000000..c17bebc
--- /dev/null
+++ b/SOURCES/libiptc-NULL-terminate-errorname.patch
@@ -0,0 +1,44 @@
+From 9dfd443c3828a3e9a3cf5cf2afb9f0324bacb19a Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libiptc: NULL-terminate errorname
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit a76ba54e28337
+
+commit a76ba54e2833761c46fd57cbe2486cbc38686717
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 24 19:25:22 2018 +0200
+
+    libiptc: NULL-terminate errorname
+
+    In struct chain_head, field 'name' is of size TABLE_MAXNAMELEN, hence
+    copying its content into 'error_name' field of struct xt_error_target
+    which is two bytes shorter may overflow. Make sure this doesn't happen
+    by using strncpy() and set the last byte to zero.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libiptc/libiptc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
+index f6a9862ea9f4d..d2427c16a5254 100644
+--- a/libiptc/libiptc.c
++++ b/libiptc/libiptc.c
+@@ -1149,7 +1149,8 @@ static int iptcc_compile_chain(struct xtc_handle *h, STRUCT_REPLACE *repl, struc
+ 		strcpy(head->name.target.u.user.name, ERROR_TARGET);
+ 		head->name.target.u.target_size =
+ 				ALIGN(sizeof(struct xt_error_target));
+-		strcpy(head->name.errorname, c->name);
++		strncpy(head->name.errorname, c->name, XT_FUNCTION_MAXNAMELEN);
++		head->name.errorname[XT_FUNCTION_MAXNAMELEN - 1] = '\0';
+ 	} else {
+ 		repl->hook_entry[c->hooknum-1] = c->head_offset;
+ 		repl->underflow[c->hooknum-1] = c->foot_offset;
+-- 
+2.21.0
+
diff --git a/SOURCES/libiptc-Simplify-alloc_handle-function-signature.patch b/SOURCES/libiptc-Simplify-alloc_handle-function-signature.patch
new file mode 100644
index 0000000..dd95978
--- /dev/null
+++ b/SOURCES/libiptc-Simplify-alloc_handle-function-signature.patch
@@ -0,0 +1,74 @@
+From e64b48b46cec83203ff8de80a1c56be2c40b2c7d Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libiptc: Simplify alloc_handle() function signature
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 22ef371abeeec
+
+commit 22ef371abeeec789bb6a701352dcb961556595c2
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:53 2018 +0200
+
+    libiptc: Simplify alloc_handle() function signature
+
+    This change originated from covscan complaining about the strcpy() call
+    with an unknown size source buffer. But in fact, the size is known (and
+    equal to the destination size), so pass a pointer to STRUCT_GETINFO to
+    alloc_handle() instead of it's fields separately. Hopefully this will
+    silence covscan.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libiptc/libiptc.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
+index 1f61fde53f1db..f6a9862ea9f4d 100644
+--- a/libiptc/libiptc.c
++++ b/libiptc/libiptc.c
+@@ -1269,7 +1269,7 @@ static int iptcc_compile_table(struct xtc_handle *h, STRUCT_REPLACE *repl)
+ 
+ /* Allocate handle of given size */
+ static struct xtc_handle *
+-alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
++alloc_handle(STRUCT_GETINFO *infop)
+ {
+ 	struct xtc_handle *h;
+ 
+@@ -1280,14 +1280,14 @@ alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
+ 	}
+ 	memset(h, 0, sizeof(*h));
+ 	INIT_LIST_HEAD(&h->chains);
+-	strcpy(h->info.name, tablename);
++	strcpy(h->info.name, infop->name);
+ 
+-	h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + size);
++	h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + infop->size);
+ 	if (!h->entries)
+ 		goto out_free_handle;
+ 
+-	strcpy(h->entries->name, tablename);
+-	h->entries->size = size;
++	strcpy(h->entries->name, infop->name);
++	h->entries->size = infop->size;
+ 
+ 	return h;
+ 
+@@ -1336,8 +1336,8 @@ retry:
+ 	DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
+ 		info.valid_hooks, info.num_entries, info.size);
+ 
+-	if ((h = alloc_handle(info.name, info.size, info.num_entries))
+-	    == NULL) {
++	h = alloc_handle(&info);
++	if (h == NULL) {
+ 		close(sockfd);
+ 		return NULL;
+ 	}
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_LED-Avoid-string-overrun-while-parsing-led-tri.patch b/SOURCES/libxt_LED-Avoid-string-overrun-while-parsing-led-tri.patch
new file mode 100644
index 0000000..654cbba
--- /dev/null
+++ b/SOURCES/libxt_LED-Avoid-string-overrun-while-parsing-led-tri.patch
@@ -0,0 +1,42 @@
+From a7bb46f478443597a7e97e81adb13d9619f4b1a7 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxt_LED: Avoid string overrun while parsing led-trigger-id
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit d0c1f1b4ad4e3
+
+commit d0c1f1b4ad4e3b91220a03514031ee879db832d0
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:48 2018 +0200
+
+    libxt_LED: Avoid string overrun while parsing led-trigger-id
+
+    Instead of using strcat() and assuming the name will fit, print into the
+    buffer using snprintf() which truncates the string as needed.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_LED.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/extensions/libxt_LED.c b/extensions/libxt_LED.c
+index 8622c379e68bc..6ada795056431 100644
+--- a/extensions/libxt_LED.c
++++ b/extensions/libxt_LED.c
+@@ -53,8 +53,7 @@ static void LED_parse(struct xt_option_call *cb)
+ 	xtables_option_parse(cb);
+ 	switch (cb->entry->id) {
+ 	case O_LED_TRIGGER_ID:
+-		strcpy(led->id, "netfilter-");
+-		strcat(led->id, cb->arg);
++		snprintf(led->id, sizeof(led->id), "netfilter-%s", cb->arg);
+ 		break;
+ 	case O_LED_DELAY:
+ 		if (strncasecmp(cb->arg, "inf", 3) == 0)
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_conntrack-Avoid-potential-buffer-overrun.patch b/SOURCES/libxt_conntrack-Avoid-potential-buffer-overrun.patch
new file mode 100644
index 0000000..ed84344
--- /dev/null
+++ b/SOURCES/libxt_conntrack-Avoid-potential-buffer-overrun.patch
@@ -0,0 +1,62 @@
+From de7ba61cf107f43223eeb640267d24e187047c29 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxt_conntrack: Avoid potential buffer overrun
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 8e798e050367d
+
+commit 8e798e050367dfe43bb958f11dd3170b03bda49e
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:50 2018 +0200
+
+    libxt_conntrack: Avoid potential buffer overrun
+
+    In print_addr(), a resolved hostname is written into a buffer without
+    size check. Since BUFSIZ is typically 8192 bytes, this shouldn't be an
+    issue, though covscan complained about it. Fix the code by using
+    conntrack_dump_addr() as an example.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_conntrack.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c
+index 3e7075760d40f..804aa23638ca1 100644
+--- a/extensions/libxt_conntrack.c
++++ b/extensions/libxt_conntrack.c
+@@ -673,20 +673,20 @@ static void
+ print_addr(const struct in_addr *addr, const struct in_addr *mask,
+            int inv, int numeric)
+ {
+-	char buf[BUFSIZ];
+-
+ 	if (inv)
+ 		printf(" !");
+ 
+ 	if (mask->s_addr == 0L && !numeric)
+-		printf(" %s", "anywhere");
++		printf(" anywhere");
+ 	else {
+ 		if (numeric)
+-			strcpy(buf, xtables_ipaddr_to_numeric(addr));
++			printf(" %s%s",
++			       xtables_ipaddr_to_numeric(addr),
++			       xtables_ipmask_to_numeric(mask));
+ 		else
+-			strcpy(buf, xtables_ipaddr_to_anyname(addr));
+-		strcat(buf, xtables_ipmask_to_numeric(mask));
+-		printf(" %s", buf);
++			printf(" %s%s",
++			       xtables_ipaddr_to_anyname(addr),
++			       xtables_ipmask_to_numeric(mask));
+ 	}
+ }
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_conntrack-Version-0-does-not-support-XT_CONNTR.patch b/SOURCES/libxt_conntrack-Version-0-does-not-support-XT_CONNTR.patch
new file mode 100644
index 0000000..58678d8
--- /dev/null
+++ b/SOURCES/libxt_conntrack-Version-0-does-not-support-XT_CONNTR.patch
@@ -0,0 +1,50 @@
+From c923062439297cbf5b08429123ba214b4efc8798 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:34 +0100
+Subject: [PATCH] libxt_conntrack: Version 0 does not support
+ XT_CONNTRACK_DIRECTION
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 74eb2395c8384
+
+commit 74eb2395c838460384286c2b95f711ae275a46cb
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:49 2018 +0200
+
+    libxt_conntrack: Version 0 does not support XT_CONNTRACK_DIRECTION
+
+    Since sinfo->flags is only 8 bytes large, checking for
+    XT_CONNTRACK_DIRECTION bit (which has value 1 << 12) will always return
+    false, so drop this dead code.
+
+    Fixes: c7fc1dae1e8f8 ("libxt_conntrack: dump ctdir")
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_conntrack.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c
+index 128bbd20a34c2..3e7075760d40f 100644
+--- a/extensions/libxt_conntrack.c
++++ b/extensions/libxt_conntrack.c
+@@ -774,14 +774,6 @@ matchinfo_print(const void *ip, const struct xt_entry_match *match, int numeric,
+         	else
+ 			printf("%lu:%lu", sinfo->expires_min, sinfo->expires_max);
+ 	}
+-
+-	if (sinfo->flags & XT_CONNTRACK_DIRECTION) {
+-		if (sinfo->invflags & XT_CONNTRACK_DIRECTION)
+-			printf(" %sctdir REPLY", optpfx);
+-		else
+-			printf(" %sctdir ORIGINAL", optpfx);
+-	}
+-
+ }
+ 
+ static void
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_ipvs-Avoid-potential-buffer-overrun.patch b/SOURCES/libxt_ipvs-Avoid-potential-buffer-overrun.patch
new file mode 100644
index 0000000..eef1f3f
--- /dev/null
+++ b/SOURCES/libxt_ipvs-Avoid-potential-buffer-overrun.patch
@@ -0,0 +1,77 @@
+From 0bf795555728e54db2593a73f90d7820cf3ef4c6 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:34 +0100
+Subject: [PATCH] libxt_ipvs: Avoid potential buffer overrun
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 749d3c2ecd6a9
+
+commit 749d3c2ecd6a9dc21f5a442c44495cb705621dff
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:51 2018 +0200
+
+    libxt_ipvs: Avoid potential buffer overrun
+
+    Just like with libxt_conntrack, get rid of the temporary buffer. The
+    comment even states that it was copied from there, so just make them
+    identical again.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_ipvs.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/extensions/libxt_ipvs.c b/extensions/libxt_ipvs.c
+index 46727660a027a..a6c57a030d2c6 100644
+--- a/extensions/libxt_ipvs.c
++++ b/extensions/libxt_ipvs.c
+@@ -126,19 +126,19 @@ static void ipvs_mt_dump_addr(const union nf_inet_addr *addr,
+ 			      const union nf_inet_addr *mask,
+ 			      unsigned int family, bool numeric)
+ {
+-	char buf[BUFSIZ];
+-
+ 	if (family == NFPROTO_IPV4) {
+ 		if (!numeric && addr->ip == 0) {
+ 			printf(" anywhere");
+ 			return;
+ 		}
+ 		if (numeric)
+-			strcpy(buf, xtables_ipaddr_to_numeric(&addr->in));
++			printf(" %s%s",
++			       xtables_ipaddr_to_numeric(&addr->in),
++			       xtables_ipmask_to_numeric(&mask->in));
+ 		else
+-			strcpy(buf, xtables_ipaddr_to_anyname(&addr->in));
+-		strcat(buf, xtables_ipmask_to_numeric(&mask->in));
+-		printf(" %s", buf);
++			printf(" %s%s",
++			       xtables_ipaddr_to_anyname(&addr->in),
++			       xtables_ipmask_to_numeric(&mask->in));
+ 	} else if (family == NFPROTO_IPV6) {
+ 		if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 &&
+ 		    addr->ip6[2] == 0 && addr->ip6[3] == 0) {
+@@ -146,11 +146,13 @@ static void ipvs_mt_dump_addr(const union nf_inet_addr *addr,
+ 			return;
+ 		}
+ 		if (numeric)
+-			strcpy(buf, xtables_ip6addr_to_numeric(&addr->in6));
++			printf(" %s%s",
++			       xtables_ip6addr_to_numeric(&addr->in6),
++			       xtables_ip6mask_to_numeric(&mask->in6));
+ 		else
+-			strcpy(buf, xtables_ip6addr_to_anyname(&addr->in6));
+-		strcat(buf, xtables_ip6mask_to_numeric(&mask->in6));
+-		printf(" %s", buf);
++			printf(" %s%s",
++			       xtables_ip6addr_to_anyname(&addr->in6),
++			       xtables_ip6mask_to_numeric(&mask->in6));
+ 	}
+ }
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_recent-Remove-ineffective-checks-for-info-name.patch b/SOURCES/libxt_recent-Remove-ineffective-checks-for-info-name.patch
new file mode 100644
index 0000000..61107bd
--- /dev/null
+++ b/SOURCES/libxt_recent-Remove-ineffective-checks-for-info-name.patch
@@ -0,0 +1,54 @@
+From 61fd4ee73f2a23eeb2b10b24d19ac13deaf0c177 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxt_recent: Remove ineffective checks for info->name
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit d0e3d95fa3442
+
+commit d0e3d95fa3442c6ff32f7fed3e0d2eeb2248ef9f
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Fri Oct 20 13:24:36 2017 +0200
+
+    libxt_recent: Remove ineffective checks for info->name
+
+    In struct xt_recent_mtinfo{,_v1}, field 'name' is an array, not a
+    pointer. So there is no point in comparing it against NULL. Changing the
+    check to make sure it's content is not an empty string is pointless
+    either, since a non-empty default string is used and the argument parser
+    will refuse empty strings as --name argument. So simply get rid of the
+    checks altogether.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_recent.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/extensions/libxt_recent.c b/extensions/libxt_recent.c
+index e1801f1c18952..055ae35080346 100644
+--- a/extensions/libxt_recent.c
++++ b/extensions/libxt_recent.c
+@@ -199,7 +199,7 @@ static void recent_print(const void *ip, const struct xt_entry_match *match,
+ 	if(info->hit_count) printf(" hit_count: %d", info->hit_count);
+ 	if (info->check_set & XT_RECENT_TTL)
+ 		printf(" TTL-Match");
+-	if(info->name) printf(" name: %s", info->name);
++	printf(" name: %s", info->name);
+ 	if (info->side == XT_RECENT_SOURCE)
+ 		printf(" side: source");
+ 	if (info->side == XT_RECENT_DEST)
+@@ -239,7 +239,7 @@ static void recent_save(const void *ip, const struct xt_entry_match *match,
+ 	if(info->hit_count) printf(" --hitcount %d", info->hit_count);
+ 	if (info->check_set & XT_RECENT_TTL)
+ 		printf(" --rttl");
+-	if(info->name) printf(" --name %s",info->name);
++	printf(" --name %s",info->name);
+ 
+ 	switch(family) {
+ 	case NFPROTO_IPV4:
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_sctp-fix-array-out-of-range-in-print_chunk.patch b/SOURCES/libxt_sctp-fix-array-out-of-range-in-print_chunk.patch
new file mode 100644
index 0000000..040aa79
--- /dev/null
+++ b/SOURCES/libxt_sctp-fix-array-out-of-range-in-print_chunk.patch
@@ -0,0 +1,51 @@
+From db1fcba4cade70fd86e615246bb03acd94cc4cd9 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxt_sctp: fix array out of range in print_chunk
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 71de414c21f7f
+Conflicts: Dropped changes to non-existing libxt_sctp.t.
+
+commit 71de414c21f7f31270e5d62e782e52257e5c3d06
+Author: huaibin Wang <huaibin.wang@6wind.com>
+Date:   Mon Nov 13 14:27:54 2017 +0100
+
+    libxt_sctp: fix array out of range in print_chunk
+
+    For chunk type ASCONF, ASCONF_ACK and FORWARD_TSN, sctp_chunk_names[].chunk_type
+    is not equal to the corresponding index in sctp_chunk_names[]. Using this field
+    leads to a segmentation fault (index out of range).
+
+    Example
+    $ iptables -A INPUT -p sctp --chunk-type all ASCONF,ASCONF_ACK,FORWARD_TSN -j ACCEPT
+    $ iptables -L
+    Chain INPUT (policy ACCEPT)
+    target     prot opt source               destination
+    Segmentation fault
+
+    Signed-off-by: huaibin Wang <huaibin.wang@6wind.com>
+    Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_sctp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c
+index 56a4cdf229390..cfd4c12330479 100644
+--- a/extensions/libxt_sctp.c
++++ b/extensions/libxt_sctp.c
+@@ -370,7 +370,7 @@ print_chunk(uint32_t chunknum, int numeric)
+ 
+ 		for (i = 0; i < ARRAY_SIZE(sctp_chunk_names); ++i)
+ 			if (sctp_chunk_names[i].chunk_type == chunknum)
+-				printf("%s", sctp_chunk_names[chunknum].name);
++				printf("%s", sctp_chunk_names[i].name);
+ 	}
+ }
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_string-Avoid-potential-array-out-of-bounds-acc.patch b/SOURCES/libxt_string-Avoid-potential-array-out-of-bounds-acc.patch
new file mode 100644
index 0000000..acda814
--- /dev/null
+++ b/SOURCES/libxt_string-Avoid-potential-array-out-of-bounds-acc.patch
@@ -0,0 +1,46 @@
+From d9b22d809995f16b2bc988c8f72d70a5cd3e86d1 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxt_string: Avoid potential array out of bounds access
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 56d7ab42f3782
+
+commit 56d7ab42f37829ab8d42f34b77fd630ce08f5a7c
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 10 23:35:16 2018 +0200
+
+    libxt_string: Avoid potential array out of bounds access
+
+    The pattern index variable 'sindex' is bounds checked before
+    incrementing it, which means in the next loop iteration it might already
+    match the bounds check condition but is used anyway.
+
+    Fix this by incrementing the index before performing the bounds check.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_string.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c
+index fb15980e4a73f..d298c6a7081e7 100644
+--- a/extensions/libxt_string.c
++++ b/extensions/libxt_string.c
+@@ -159,9 +159,8 @@ parse_hex_string(const char *s, struct xt_string_info *info)
+ 			info->pattern[sindex] = s[i];
+ 			i++;
+ 		}
+-		if (sindex > XT_STRING_MAX_PATTERN_SIZE)
++		if (++sindex > XT_STRING_MAX_PATTERN_SIZE)
+ 			xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s);
+-		sindex++;
+ 	}
+ 	info->patlen = sindex;
+ }
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_string-Fix-array-out-of-bounds-check.patch b/SOURCES/libxt_string-Fix-array-out-of-bounds-check.patch
new file mode 100644
index 0000000..f4c9047
--- /dev/null
+++ b/SOURCES/libxt_string-Fix-array-out-of-bounds-check.patch
@@ -0,0 +1,62 @@
+From 5790cacab5a3fd7bde26056fa0f8b4650bd21bb7 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxt_string: Fix array out of bounds check
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 6fc7762f6f785
+
+commit 6fc7762f6f78526e3cb0c189ac2778a6be4c00b5
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 17 13:38:33 2018 +0200
+
+    libxt_string: Fix array out of bounds check
+
+    Commit 56d7ab42f3782 ("libxt_string: Avoid potential array out of bounds
+    access") tried to fix parse_hex_string() for overlong strings but the
+    change still allowed for 'sindex' to become XT_STRING_MAX_PATTERN_SIZE
+    which leads to access of first byte after info->pattern. This is not
+    really a problem because it merely overwrites info->patlen before
+    calling xtables_error() later, but covscan still detects it so it's
+    still worth fixing.
+
+    The crucial bit here is that 'sindex' has to be incremented at end of
+    the last iteration since its value is used for info->patlen. Hence just
+    move the overflow check to the beginning of the loop.
+
+    Fixes: 56d7ab42f3782 ("libxt_string: Avoid potential array out of bounds access")
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_string.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c
+index d298c6a7081e7..7c6366cbbf1b3 100644
+--- a/extensions/libxt_string.c
++++ b/extensions/libxt_string.c
+@@ -103,6 +103,9 @@ parse_hex_string(const char *s, struct xt_string_info *info)
+ 	}
+ 
+ 	while (i < slen) {
++		if (sindex >= XT_STRING_MAX_PATTERN_SIZE)
++			xtables_error(PARAMETER_PROBLEM,
++				      "STRING too long \"%s\"", s);
+ 		if (s[i] == '\\' && !hex_f) {
+ 			literal_f = 1;
+ 		} else if (s[i] == '\\') {
+@@ -159,8 +162,7 @@ parse_hex_string(const char *s, struct xt_string_info *info)
+ 			info->pattern[sindex] = s[i];
+ 			i++;
+ 		}
+-		if (++sindex > XT_STRING_MAX_PATTERN_SIZE)
+-			xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s);
++		sindex++;
+ 	}
+ 	info->patlen = sindex;
+ }
+-- 
+2.21.0
+
diff --git a/SOURCES/libxt_time-Drop-initialization-of-variable-year.patch b/SOURCES/libxt_time-Drop-initialization-of-variable-year.patch
new file mode 100644
index 0000000..0aa5037
--- /dev/null
+++ b/SOURCES/libxt_time-Drop-initialization-of-variable-year.patch
@@ -0,0 +1,59 @@
+From c6d6426921160fb554871fbe201722963f8a917c Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxt_time: Drop initialization of variable 'year'
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 6b7145fa2112e
+
+commit 6b7145fa2112e257073cc44346e9891fa23ce9c2
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:52 2018 +0200
+
+    libxt_time: Drop initialization of variable 'year'
+
+    The variable is not read before being assigned the return value of
+    strtoul(), thefore the initialization is useless. And since after this
+    change parameter 'end' becomes unused, drop it as well.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libxt_time.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c
+index 9c5bda88c1c78..5a8cc5de13031 100644
+--- a/extensions/libxt_time.c
++++ b/extensions/libxt_time.c
+@@ -88,10 +88,10 @@ static void time_init(struct xt_entry_match *m)
+ 	info->date_stop  = INT_MAX;
+ }
+ 
+-static time_t time_parse_date(const char *s, bool end)
++static time_t time_parse_date(const char *s)
+ {
+ 	unsigned int month = 1, day = 1, hour = 0, minute = 0, second = 0;
+-	unsigned int year  = end ? 2038 : 1970;
++	unsigned int year;
+ 	const char *os = s;
+ 	struct tm tm;
+ 	time_t ret;
+@@ -265,10 +265,10 @@ static void time_parse(struct xt_option_call *cb)
+ 	xtables_option_parse(cb);
+ 	switch (cb->entry->id) {
+ 	case O_DATE_START:
+-		info->date_start = time_parse_date(cb->arg, false);
++		info->date_start = time_parse_date(cb->arg);
+ 		break;
+ 	case O_DATE_STOP:
+-		info->date_stop = time_parse_date(cb->arg, true);
++		info->date_stop = time_parse_date(cb->arg);
+ 		break;
+ 	case O_TIME_START:
+ 		info->daytime_start = time_parse_minutes(cb->arg);
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-Avoid-calling-memcpy-with-NULL-source.patch b/SOURCES/libxtables-Avoid-calling-memcpy-with-NULL-source.patch
new file mode 100644
index 0000000..2d4abba
--- /dev/null
+++ b/SOURCES/libxtables-Avoid-calling-memcpy-with-NULL-source.patch
@@ -0,0 +1,91 @@
+From 3f4e13d60ddbb61bc3256221a98f5c5a954f6f5c Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxtables: Avoid calling memcpy() with NULL source
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit ab639f236ff85
+
+commit ab639f236ff85d2f447cc6601c7ff42cefdaf853
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:54 2018 +0200
+
+    libxtables: Avoid calling memcpy() with NULL source
+
+    Both affected functions check if 'oldopts' is NULL once but later seem
+    to ignore that possibility. To catch up on that, increment the pointer
+    only if it isn't NULL, also don't copy its content into the merged
+    options buffer in that case.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtables.c   | 12 ++++++++----
+ libxtables/xtoptions.c | 12 ++++++++----
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index 4a014e48a9f45..cf9a59d5ec095 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -119,8 +119,10 @@ struct option *xtables_merge_options(struct option *orig_opts,
+ 	 * Since @oldopts also has @orig_opts already (and does so at the
+ 	 * start), skip these entries.
+ 	 */
+-	oldopts += num_oold;
+-	num_old -= num_oold;
++	if (oldopts != NULL) {
++		oldopts += num_oold;
++		num_old -= num_oold;
++	}
+ 
+ 	merge = malloc(sizeof(*mp) * (num_oold + num_old + num_new + 1));
+ 	if (merge == NULL)
+@@ -139,8 +141,10 @@ struct option *xtables_merge_options(struct option *orig_opts,
+ 		mp->val += *option_offset;
+ 
+ 	/* Third, the old options */
+-	memcpy(mp, oldopts, sizeof(*mp) * num_old);
+-	mp += num_old;
++	if (oldopts != NULL) {
++		memcpy(mp, oldopts, sizeof(*mp) * num_old);
++		mp += num_old;
++	}
+ 	xtables_free_opts(0);
+ 
+ 	/* Clear trailing entry */
+diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
+index 1ad4cb57f5836..1d3fda73dedf7 100644
+--- a/libxtables/xtoptions.c
++++ b/libxtables/xtoptions.c
+@@ -91,8 +91,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
+ 	 * Since @oldopts also has @orig_opts already (and does so at the
+ 	 * start), skip these entries.
+ 	 */
+-	oldopts += num_orig;
+-	num_old -= num_orig;
++	if (oldopts != NULL) {
++		oldopts += num_orig;
++		num_old -= num_orig;
++	}
+ 
+ 	merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1));
+ 	if (merge == NULL)
+@@ -114,8 +116,10 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
+ 	}
+ 
+ 	/* Third, the old options */
+-	memcpy(mp, oldopts, sizeof(*mp) * num_old);
+-	mp += num_old;
++	if (oldopts != NULL) {
++		memcpy(mp, oldopts, sizeof(*mp) * num_old);
++		mp += num_old;
++	}
+ 	xtables_free_opts(0);
+ 
+ 	/* Clear trailing entry */
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-Check-extension-real_name-length.patch b/SOURCES/libxtables-Check-extension-real_name-length.patch
new file mode 100644
index 0000000..d4e1d6d
--- /dev/null
+++ b/SOURCES/libxtables-Check-extension-real_name-length.patch
@@ -0,0 +1,57 @@
+From e4dd398938aed75397463aed36fc03f9d754bf29 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxtables: Check extension real_name length
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit a3716cc1a501e
+
+commit a3716cc1a501e40e26a96d78b2e1285bb081f366
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 24 19:25:21 2018 +0200
+
+    libxtables: Check extension real_name length
+
+    Just like with 'name', if given check 'real_name' to not exceed max length.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtables.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index 575f7ee0a0d78..4a014e48a9f45 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -839,6 +839,12 @@ void xtables_register_match(struct xtables_match *me)
+ 		exit(1);
+ 	}
+ 
++	if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
++		fprintf(stderr, "%s: match `%s' has invalid real name\n",
++			xt_params->program_name, me->real_name);
++		exit(1);
++	}
++
+ 	if (me->family >= NPROTO) {
+ 		fprintf(stderr,
+ 			"%s: BUG: match %s has invalid protocol family\n",
+@@ -997,6 +1003,12 @@ void xtables_register_target(struct xtables_target *me)
+ 		exit(1);
+ 	}
+ 
++	if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
++		fprintf(stderr, "%s: target `%s' has invalid real name\n",
++			xt_params->program_name, me->real_name);
++		exit(1);
++	}
++
+ 	if (me->family >= NPROTO) {
+ 		fprintf(stderr,
+ 			"%s: BUG: target %s has invalid protocol family\n",
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-Don-t-read-garbage-in-xtables_strtoui.patch b/SOURCES/libxtables-Don-t-read-garbage-in-xtables_strtoui.patch
new file mode 100644
index 0000000..d1dae23
--- /dev/null
+++ b/SOURCES/libxtables-Don-t-read-garbage-in-xtables_strtoui.patch
@@ -0,0 +1,42 @@
+From 6052b28839968d5077c182e6defa260e68147547 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxtables: Don't read garbage in xtables_strtoui()
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 61ebf3f72ac62
+
+commit 61ebf3f72ac62d887414c50fc83e277386f54e8f
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:55 2018 +0200
+
+    libxtables: Don't read garbage in xtables_strtoui()
+
+    If xtables_strtoul() fails, it returns false and data pointed to by
+    parameter 'value' is undefined. Hence avoid copying that data in
+    xtables_strtoui() if the call failed.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index fb60c01b48c05..575f7ee0a0d78 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -473,7 +473,7 @@ bool xtables_strtoui(const char *s, char **end, unsigned int *value,
+ 	bool ret;
+ 
+ 	ret = xtables_strtoul(s, end, &v, min, max);
+-	if (value != NULL)
++	if (ret && value != NULL)
+ 		*value = v;
+ 	return ret;
+ }
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-Fix-potential-array-overrun-in-xtables_op.patch b/SOURCES/libxtables-Fix-potential-array-overrun-in-xtables_op.patch
new file mode 100644
index 0000000..51e3bf0
--- /dev/null
+++ b/SOURCES/libxtables-Fix-potential-array-overrun-in-xtables_op.patch
@@ -0,0 +1,42 @@
+From f958c3a78f14140e7ee983c3698918fe35f1a7af Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] libxtables: Fix potential array overrun in
+ xtables_option_parse()
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 4144571f87c09
+
+commit 4144571f87c094471419ef59e8bb89ef33cd1365
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Mon Sep 10 23:35:13 2018 +0200
+
+    libxtables: Fix potential array overrun in xtables_option_parse()
+
+    If entry->type is to be used as array index, it needs to be at max one
+    less than that array's size.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtoptions.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
+index 78e9abd6a3f47..0c63c2d372dea 100644
+--- a/libxtables/xtoptions.c
++++ b/libxtables/xtoptions.c
+@@ -864,7 +864,7 @@ void xtables_option_parse(struct xt_option_call *cb)
+ 	 * a *RC option type.
+ 	 */
+ 	cb->nvals = 1;
+-	if (entry->type <= ARRAY_SIZE(xtopt_subparse) &&
++	if (entry->type < ARRAY_SIZE(xtopt_subparse) &&
+ 	    xtopt_subparse[entry->type] != NULL)
+ 		xtopt_subparse[entry->type](cb);
+ 	/* Exclusion with other flags tested later in finalize. */
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-Use-posix_spawn-instead-of-vfork.patch b/SOURCES/libxtables-Use-posix_spawn-instead-of-vfork.patch
new file mode 100644
index 0000000..b301387
--- /dev/null
+++ b/SOURCES/libxtables-Use-posix_spawn-instead-of-vfork.patch
@@ -0,0 +1,71 @@
+From fbcd6c97015324480f843c08da338c9d580b2b31 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxtables: Use posix_spawn() instead of vfork()
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit d95c1e8b65c4e
+
+commit d95c1e8b65c4ec66b8fcd2f7ede257853a888750
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:17:05 2018 +0200
+
+    libxtables: Use posix_spawn() instead of vfork()
+
+    According to covscan, vfork() may lead to a deadlock in the parent
+    process. It suggests to use posix_spawn() instead. Since the latter
+    combines vfork() and exec() calls, use it for xtables_insmod().
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtables.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index bca9863acc566..7210d3706bf26 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -21,6 +21,7 @@
+ #include <fcntl.h>
+ #include <inttypes.h>
+ #include <netdb.h>
++#include <spawn.h>
+ #include <stdarg.h>
+ #include <stdbool.h>
+ #include <stdio.h>
+@@ -343,6 +344,7 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
+ 	char *buf = NULL;
+ 	char *argv[4];
+ 	int status;
++	pid_t pid;
+ 
+ 	/* If they don't explicitly set it, read out of kernel */
+ 	if (!modprobe) {
+@@ -363,18 +365,11 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
+ 	 */
+ 	fflush(stdout);
+ 
+-	switch (vfork()) {
+-	case 0:
+-		execv(argv[0], argv);
+-
+-		/* not usually reached */
+-		_exit(1);
+-	case -1:
++	if (posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL)) {
+ 		free(buf);
+ 		return -1;
+-
+-	default: /* parent */
+-		wait(&status);
++	} else {
++		waitpid(pid, &status, 0);
+ 	}
+ 
+ 	free(buf);
+-- 
+2.21.0
+
diff --git a/SOURCES/libxtables-move-some-code-to-avoid-cautions-in-vfork.patch b/SOURCES/libxtables-move-some-code-to-avoid-cautions-in-vfork.patch
new file mode 100644
index 0000000..bc11de0
--- /dev/null
+++ b/SOURCES/libxtables-move-some-code-to-avoid-cautions-in-vfork.patch
@@ -0,0 +1,102 @@
+From 0d89bdef1e7f698787967bffed5c413ef0dee761 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] libxtables: move some code to avoid cautions in vfork man
+ page
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 78683093cf4f0
+
+commit 78683093cf4f059531e5f929a4884ffaecb8411c
+Author: Dan Wilder <dan.wilder@watchguard.com>
+Date:   Sat Oct 25 00:51:59 2014 +0200
+
+    libxtables: move some code to avoid cautions in vfork man page
+
+    Running iptables-restore on an embedded platform containing no modprobe program, the following lines in xtables.c lead to corrupted stack frame:
+
+     357     switch (vfork()) {
+     358     case 0:
+     359         argv[0] = (char *)modprobe;
+     360         argv[1] = (char *)modname;
+     361         if (quiet) {
+     362             argv[2] = "-q";
+     363             argv[3] = NULL;
+     364         } else {
+     365             argv[2] = NULL;
+     366             argv[3] = NULL;
+     367         }
+     368         execv(argv[0], argv);
+     369
+     370         /* not usually reached */
+     371         exit(1);
+
+    modprobe pointed to a non-existant program /sbin/modprobe, so execv()
+    always failed.  Not a problem in itself on our platform, as the kernel
+    modules are pre-loaded before iptables-restore is run, but it took a
+    bit of headscratching to track this down, as a stack frame was
+    corrupted, leading to failures quite a while after the function
+    containing this code had returned!
+
+    Relevant caution in man 2 vfork:
+
+        "The vfork() function has the same effect as fork(2), except that
+        the behavior is undefined if the process created by vfork() either
+        modifies any data ... or calls any other function before
+        successfully calling _exit(2) or one of the exec(3) family of
+        functions."
+
+    Apparently this has not been a problem for us in earlier versions of
+    glibc, maybe because vfork was more like fork, maybe because the
+    stack corruption was innocuous.  Ours is a corner case anyway, as
+    it might not have been a problem had modprobe existed or had
+    modprobe been a symlink to /bin/true.  But it seems odd to disregard
+    man page cautions, and our problem goes away if they are heeded.
+
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libxtables/xtables.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index cf9a59d5ec095..bca9863acc566 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -352,6 +352,11 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
+ 		modprobe = buf;
+ 	}
+ 
++	argv[0] = (char *)modprobe;
++	argv[1] = (char *)modname;
++	argv[2] = quiet ? "-q" : NULL;
++	argv[3] = NULL;
++
+ 	/*
+ 	 * Need to flush the buffer, or the child may output it again
+ 	 * when switching the program thru execv.
+@@ -360,19 +365,10 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet)
+ 
+ 	switch (vfork()) {
+ 	case 0:
+-		argv[0] = (char *)modprobe;
+-		argv[1] = (char *)modname;
+-		if (quiet) {
+-			argv[2] = "-q";
+-			argv[3] = NULL;
+-		} else {
+-			argv[2] = NULL;
+-			argv[3] = NULL;
+-		}
+ 		execv(argv[0], argv);
+ 
+ 		/* not usually reached */
+-		exit(1);
++		_exit(1);
+ 	case -1:
+ 		free(buf);
+ 		return -1;
+-- 
+2.21.0
+
diff --git a/SOURCES/list-fix-prefetch-dummy.patch b/SOURCES/list-fix-prefetch-dummy.patch
new file mode 100644
index 0000000..9ca7544
--- /dev/null
+++ b/SOURCES/list-fix-prefetch-dummy.patch
@@ -0,0 +1,46 @@
+From 9db248f030af87e336b5880fc39e37a5beb7f291 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:52:42 +0100
+Subject: [PATCH] list: fix prefetch dummy
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 86a65af62b6b9
+
+commit 86a65af62b6b986aa2ae3cbf3c655ea8225b027a
+Author: Arturo Borrero <arturo.borrero.glez@gmail.com>
+Date:   Mon Apr 6 20:05:41 2015 +0200
+
+    list: fix prefetch dummy
+
+    linux_list.h:381:59: warning: right-hand operand of comma expression has no effect [-Wunused-value]
+      for (pos = list_entry((head)->next, typeof(*pos), member), \
+                                                               ^
+    libiptc.c:552:2: note: in expansion of macro 'list_for_each_entry'
+      list_for_each_entry(c, &h->chains, list) {
+      ^
+
+    [ Patch copied from one similar of Patrick McHardy on libnftnl ]
+
+    Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ libiptc/linux_list.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libiptc/linux_list.h b/libiptc/linux_list.h
+index abdcf88dadd64..559e33c9ebde0 100644
+--- a/libiptc/linux_list.h
++++ b/libiptc/linux_list.h
+@@ -27,7 +27,7 @@
+ 	1; \
+ })
+ 
+-#define prefetch(x)		1
++#define prefetch(x)		((void)0)
+ 
+ /* empty define to make this work in userspace -HW */
+ #define smp_wmb()
+-- 
+2.21.0
+
diff --git a/SOURCES/man-iptables-save-Add-note-about-module-autoloading.patch b/SOURCES/man-iptables-save-Add-note-about-module-autoloading.patch
new file mode 100644
index 0000000..49c467e
--- /dev/null
+++ b/SOURCES/man-iptables-save-Add-note-about-module-autoloading.patch
@@ -0,0 +1,47 @@
+From d9db0c35351a960a141e9ddc30cf6f09c9c27c8b Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Thu, 18 Apr 2019 13:29:43 +0200
+Subject: [PATCH] man: iptables-save: Add note about module autoloading
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1691380
+Upstream Status: iptables commit 3390007a11cbc
+
+commit 3390007a11cbc45de1522f99ae751a3c5d55dd6f
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Tue Mar 26 19:03:43 2019 +0100
+
+    man: iptables-save: Add note about module autoloading
+
+    Using '-t' parameter in iptables-save might lead to kernel module
+    loading, just like with iptables itself. Copy the hint from iptables.8
+    to inform users.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/iptables-save.8.in | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/iptables/iptables-save.8.in b/iptables/iptables-save.8.in
+index 4091c0a595575..c3f1bd2152c58 100644
+--- a/iptables/iptables-save.8.in
++++ b/iptables/iptables-save.8.in
+@@ -44,8 +44,11 @@ inspect /proc/sys/kernel/modprobe to determine the executable's path.
+ include the current values of all packet and byte counters in the output
+ .TP
+ \fB\-t\fR, \fB\-\-table\fR \fItablename\fP
+-restrict output to only one table. If not specified, output includes all
+-available tables.
++restrict output to only one table. If the kernel is configured with automatic
++module loading, an attempt will be made to load the appropriate module for
++that table if it is not already there.
++.br
++If not specified, output includes all available tables.
+ .SH BUGS
+ None known as of iptables-1.2.1 release
+ .SH AUTHORS
+-- 
+2.21.0
+
diff --git a/SOURCES/nfnl_osf-Drop-pointless-check-in-xt_osf_strchr.patch b/SOURCES/nfnl_osf-Drop-pointless-check-in-xt_osf_strchr.patch
new file mode 100644
index 0000000..6422370
--- /dev/null
+++ b/SOURCES/nfnl_osf-Drop-pointless-check-in-xt_osf_strchr.patch
@@ -0,0 +1,43 @@
+From 4103f34690e1380c0ad4831b80ad913ea980eab4 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:51:28 +0100
+Subject: [PATCH] nfnl_osf: Drop pointless check in xt_osf_strchr()
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 8c786a351a441
+
+commit 8c786a351a441ff23ad5d9d1da8cec492f88f542
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:42 2018 +0200
+
+    nfnl_osf: Drop pointless check in xt_osf_strchr()
+
+    Although it remains unclear what the original intention behind the
+    affected code was, but 'tmp + 1' always evaluates true since 'tmp' is a
+    pointer value.
+
+    Cc: Evgeniy Polyakov <johnpol@2ka.mxt.ru>
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ utils/nfnl_osf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c
+index 0f8b35b805016..9a9fbe1268155 100644
+--- a/utils/nfnl_osf.c
++++ b/utils/nfnl_osf.c
+@@ -141,7 +141,7 @@ static char *xt_osf_strchr(char *ptr, char c)
+ 	if (tmp)
+ 		*tmp = '\0';
+ 
+-	while (tmp && tmp + 1 && isspace(*(tmp + 1)))
++	while (tmp && isspace(*(tmp + 1)))
+ 		tmp++;
+ 
+ 	return tmp;
+-- 
+2.21.0
+
diff --git a/SOURCES/nfnl_osf-Replace-deprecated-nfnl_talk-by-nfnl_query.patch b/SOURCES/nfnl_osf-Replace-deprecated-nfnl_talk-by-nfnl_query.patch
new file mode 100644
index 0000000..eeee0cc
--- /dev/null
+++ b/SOURCES/nfnl_osf-Replace-deprecated-nfnl_talk-by-nfnl_query.patch
@@ -0,0 +1,40 @@
+From 4ee53b682e3ebb9a809007ec907f65ccfe4a1342 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Fri, 15 Mar 2019 17:50:10 +0100
+Subject: [PATCH] nfnl_osf: Replace deprecated nfnl_talk() by nfnl_query()
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1525980
+Upstream Status: iptables commit 52aa15098ebd6
+
+commit 52aa15098ebd62eaca9eb3c57c240df2455d8e9b
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Wed Sep 19 15:16:56 2018 +0200
+
+    nfnl_osf: Replace deprecated nfnl_talk() by nfnl_query()
+
+    This eliminates the deprecation warning when compiling the sources.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ utils/nfnl_osf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c
+index 972128f47ba04..c67485ee698b1 100644
+--- a/utils/nfnl_osf.c
++++ b/utils/nfnl_osf.c
+@@ -384,7 +384,7 @@ static int osf_load_line(char *buffer, int len, int del)
+ 
+ 	nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger));
+ 
+-	return nfnl_talk(nfnlh, nmh, 0, 0, NULL, NULL, NULL);
++	return nfnl_query(nfnlh, nmh);
+ }
+ 
+ static int osf_load_entries(char *path, int del)
+-- 
+2.21.0
+
diff --git a/SOURCES/xshared-Consolidate-argv-construction-routines.patch b/SOURCES/xshared-Consolidate-argv-construction-routines.patch
new file mode 100644
index 0000000..7e1a5fa
--- /dev/null
+++ b/SOURCES/xshared-Consolidate-argv-construction-routines.patch
@@ -0,0 +1,568 @@
+From fc87d26b0343a5fbe661acc967f7a7c316531ca5 Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:16:49 +0200
+Subject: [PATCH] xshared: Consolidate argv construction routines
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1668475
+Upstream Status: iptables commit a2ed880a19d08
+Conflicts:
+* Context change due to missing commit 2963a8df2175b
+  ("iptables: Remove explicit static variables initalization.").
+* Context change due to missing commit 1cc09188079a6
+  ("xshared: Consolidate parse_counters()").
+* Context change due to previously backported commit 8da04ffdca193
+  ("Share print_ipv{4,6}_addr() from xtables").
+* Dropped changes to non-existing file iptables/xtables-restore.c.
+
+commit a2ed880a19d0861342b3515721804b18d698bf44
+Author: Phil Sutter <phil@nwl.cc>
+Date:   Thu Aug 2 17:05:17 2018 +0200
+
+    xshared: Consolidate argv construction routines
+
+    Implementations were equal in {ip,ip6,x}tables-restore.c. The one in
+    iptables-xml.c differed slightly. For now, collect all features
+    together. Maybe it would make sense to migrate iptables-xml.c to using
+    add_param_to_argv() at some point and therefore extend the latter to
+    store whether a given parameter was quoted or not.
+
+    While being at it, a few improvements were done:
+
+    * free_argv() now also resets 'newargc' variable, so users don't have to
+      do that anymore.
+    * Indenting level in add_param_to_argv() was reduced a bit.
+    * That long error message is put into a single line to aid in grepping
+      for it.
+    * Explicit call to exit() after xtables_error() is removed since the
+      latter does not return anyway.
+
+    Signed-off-by: Phil Sutter <phil@nwl.cc>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ iptables/ip6tables-restore.c | 107 ++----------------------------
+ iptables/iptables-restore.c  | 107 ++----------------------------
+ iptables/iptables-xml.c      |  63 ------------------
+ iptables/xshared.c           | 123 +++++++++++++++++++++++++++++++++++
+ iptables/xshared.h           |  13 ++++
+ 5 files changed, 150 insertions(+), 263 deletions(-)
+
+diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
+index 611430d930eda..1f8cb43286f03 100644
+--- a/iptables/ip6tables-restore.c
++++ b/iptables/ip6tables-restore.c
+@@ -91,96 +91,6 @@ static int parse_counters(char *string, struct xt_counters *ctr)
+ 	return ret == 2;
+ }
+ 
+-/* global new argv and argc */
+-static char *newargv[255];
+-static int newargc;
+-
+-/* function adding one argument to newargv, updating newargc
+- * returns true if argument added, false otherwise */
+-static int add_argv(char *what) {
+-	DEBUGP("add_argv: %s\n", what);
+-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+-		newargv[newargc] = strdup(what);
+-		newargv[++newargc] = NULL;
+-		return 1;
+-	} else {
+-		xtables_error(PARAMETER_PROBLEM,
+-			"Parser cannot handle more arguments\n");
+-		return 0;
+-	}
+-}
+-
+-static void free_argv(void) {
+-	int i;
+-
+-	for (i = 0; i < newargc; i++)
+-		free(newargv[i]);
+-}
+-
+-static void add_param_to_argv(char *parsestart)
+-{
+-	int quote_open = 0, escaped = 0, param_len = 0;
+-	char param_buffer[1024], *curchar;
+-
+-	/* After fighting with strtok enough, here's now
+-	 * a 'real' parser. According to Rusty I'm now no
+-	 * longer a real hacker, but I can live with that */
+-
+-	for (curchar = parsestart; *curchar; curchar++) {
+-		if (quote_open) {
+-			if (escaped) {
+-				param_buffer[param_len++] = *curchar;
+-				escaped = 0;
+-				continue;
+-			} else if (*curchar == '\\') {
+-				escaped = 1;
+-				continue;
+-			} else if (*curchar == '"') {
+-				quote_open = 0;
+-				*curchar = ' ';
+-			} else {
+-				param_buffer[param_len++] = *curchar;
+-				continue;
+-			}
+-		} else {
+-			if (*curchar == '"') {
+-				quote_open = 1;
+-				continue;
+-			}
+-		}
+-
+-		if (*curchar == ' '
+-		    || *curchar == '\t'
+-		    || * curchar == '\n') {
+-			if (!param_len) {
+-				/* two spaces? */
+-				continue;
+-			}
+-
+-			param_buffer[param_len] = '\0';
+-
+-			/* check if table name specified */
+-			if (!strncmp(param_buffer, "-t", 2)
+-                            || !strncmp(param_buffer, "--table", 8)) {
+-				xtables_error(PARAMETER_PROBLEM,
+-				"The -t option (seen in line %u) cannot be "
+-				"used in ip6tables-restore.\n", line);
+-				exit(1);
+-			}
+-
+-			add_argv(param_buffer);
+-			param_len = 0;
+-		} else {
+-			/* regular character, copy to buffer */
+-			param_buffer[param_len++] = *curchar;
+-
+-			if (param_len >= sizeof(param_buffer))
+-				xtables_error(PARAMETER_PROBLEM,
+-				   "Parameter too long!");
+-		}
+-	}
+-}
+-
+ int ip6tables_restore_main(int argc, char *argv[])
+ {
+ 	struct xtc_handle *handle = NULL;
+@@ -425,9 +335,6 @@ int ip6tables_restore_main(int argc, char *argv[])
+ 			char *bcnt = NULL;
+ 			char *parsestart;
+ 
+-			/* reset the newargv */
+-			newargc = 0;
+-
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+ 				char *ptr = strchr(buffer, ']');
+@@ -456,17 +363,17 @@ int ip6tables_restore_main(int argc, char *argv[])
+ 				parsestart = buffer;
+ 			}
+ 
+-			add_argv(argv[0]);
+-			add_argv("-t");
+-			add_argv(curtable);
++			add_argv(argv[0], 0);
++			add_argv("-t", 0);
++			add_argv(curtable, 0);
+ 
+ 			if (counters && pcnt && bcnt) {
+-				add_argv("--set-counters");
+-				add_argv((char *) pcnt);
+-				add_argv((char *) bcnt);
++				add_argv("--set-counters", 0);
++				add_argv((char *) pcnt, 0);
++				add_argv((char *) bcnt, 0);
+ 			}
+ 
+-			add_param_to_argv(parsestart);
++			add_param_to_argv(parsestart, line);
+ 
+ 			DEBUGP("calling do_command6(%u, argv, &%s, handle):\n",
+ 				newargc, curtable);
+diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
+index b0da96d45d297..615e38a6625e0 100644
+--- a/iptables/iptables-restore.c
++++ b/iptables/iptables-restore.c
+@@ -89,96 +89,6 @@ static int parse_counters(char *string, struct xt_counters *ctr)
+ 	return ret == 2;
+ }
+ 
+-/* global new argv and argc */
+-static char *newargv[255];
+-static int newargc;
+-
+-/* function adding one argument to newargv, updating newargc 
+- * returns true if argument added, false otherwise */
+-static int add_argv(char *what) {
+-	DEBUGP("add_argv: %s\n", what);
+-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+-		newargv[newargc] = strdup(what);
+-		newargv[++newargc] = NULL;
+-		return 1;
+-	} else {
+-		xtables_error(PARAMETER_PROBLEM,
+-			"Parser cannot handle more arguments\n");
+-		return 0;
+-	}
+-}
+-
+-static void free_argv(void) {
+-	int i;
+-
+-	for (i = 0; i < newargc; i++)
+-		free(newargv[i]);
+-}
+-
+-static void add_param_to_argv(char *parsestart)
+-{
+-	int quote_open = 0, escaped = 0, param_len = 0;
+-	char param_buffer[1024], *curchar;
+-
+-	/* After fighting with strtok enough, here's now
+-	 * a 'real' parser. According to Rusty I'm now no
+-	 * longer a real hacker, but I can live with that */
+-
+-	for (curchar = parsestart; *curchar; curchar++) {
+-		if (quote_open) {
+-			if (escaped) {
+-				param_buffer[param_len++] = *curchar;
+-				escaped = 0;
+-				continue;
+-			} else if (*curchar == '\\') {
+-				escaped = 1;
+-				continue;
+-			} else if (*curchar == '"') {
+-				quote_open = 0;
+-				*curchar = ' ';
+-			} else {
+-				param_buffer[param_len++] = *curchar;
+-				continue;
+-			}
+-		} else {
+-			if (*curchar == '"') {
+-				quote_open = 1;
+-				continue;
+-			}
+-		}
+-
+-		if (*curchar == ' '
+-		    || *curchar == '\t'
+-		    || * curchar == '\n') {
+-			if (!param_len) {
+-				/* two spaces? */
+-				continue;
+-			}
+-
+-			param_buffer[param_len] = '\0';
+-
+-			/* check if table name specified */
+-			if (!strncmp(param_buffer, "-t", 2)
+-			    || !strncmp(param_buffer, "--table", 8)) {
+-				xtables_error(PARAMETER_PROBLEM,
+-				"The -t option (seen in line %u) cannot be "
+-				"used in iptables-restore.\n", line);
+-				exit(1);
+-			}
+-
+-			add_argv(param_buffer);
+-			param_len = 0;
+-		} else {
+-			/* regular character, copy to buffer */
+-			param_buffer[param_len++] = *curchar;
+-
+-			if (param_len >= sizeof(param_buffer))
+-				xtables_error(PARAMETER_PROBLEM,
+-				   "Parameter too long!");
+-		}
+-	}
+-}
+-
+ int
+ iptables_restore_main(int argc, char *argv[])
+ {
+@@ -424,9 +334,6 @@ iptables_restore_main(int argc, char *argv[])
+ 			char *bcnt = NULL;
+ 			char *parsestart;
+ 
+-			/* reset the newargv */
+-			newargc = 0;
+-
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+ 				char *ptr = strchr(buffer, ']');
+@@ -455,17 +362,17 @@ iptables_restore_main(int argc, char *argv[])
+ 				parsestart = buffer;
+ 			}
+ 
+-			add_argv(argv[0]);
+-			add_argv("-t");
+-			add_argv(curtable);
++			add_argv(argv[0], 0);
++			add_argv("-t", 0);
++			add_argv(curtable, 0);
+ 
+ 			if (counters && pcnt && bcnt) {
+-				add_argv("--set-counters");
+-				add_argv((char *) pcnt);
+-				add_argv((char *) bcnt);
++				add_argv("--set-counters", 0);
++				add_argv((char *) pcnt, 0);
++				add_argv((char *) bcnt, 0);
+ 			}
+ 
+-			add_param_to_argv(parsestart);
++			add_param_to_argv(parsestart, line);
+ 
+ 			DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
+ 				newargc, curtable);
+diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
+index c523a132b2240..49f8ea2826181 100644
+--- a/iptables/iptables-xml.c
++++ b/iptables/iptables-xml.c
+@@ -66,16 +66,6 @@ parse_counters(char *string, struct xt_counters *ctr)
+ 		return (0 == 2);
+ }
+ 
+-/* global new argv and argc */
+-static char *newargv[255];
+-static unsigned int newargc = 0;
+-
+-static char *oldargv[255];
+-static unsigned int oldargc = 0;
+-
+-/* arg meta data, were they quoted, frinstance */
+-static int newargvattr[255];
+-
+ #define XT_CHAIN_MAXNAMELEN XT_TABLE_MAXNAMELEN
+ static char closeActionTag[XT_TABLE_MAXNAMELEN + 1];
+ static char closeRuleTag[XT_TABLE_MAXNAMELEN + 1];
+@@ -93,56 +83,6 @@ struct chain {
+ static struct chain chains[maxChains];
+ static int nextChain = 0;
+ 
+-/* funCtion adding one argument to newargv, updating newargc 
+- * returns true if argument added, false otherwise */
+-static int
+-add_argv(char *what, int quoted)
+-{
+-	DEBUGP("add_argv: %d %s\n", newargc, what);
+-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+-		newargv[newargc] = strdup(what);
+-		newargvattr[newargc] = quoted;
+-		newargc++;
+-		return 1;
+-	} else
+-		return 0;
+-}
+-
+-static void
+-free_argv(void)
+-{
+-	unsigned int i;
+-
+-	for (i = 0; i < newargc; i++) {
+-		free(newargv[i]);
+-		newargv[i] = NULL;
+-	}
+-	newargc = 0;
+-
+-	for (i = 0; i < oldargc; i++) {
+-		free(oldargv[i]);
+-		oldargv[i] = NULL;
+-	}
+-	oldargc = 0;
+-}
+-
+-/* save parsed rule for comparison with next rule 
+-   to perform action agregation on duplicate conditions */
+-static void
+-save_argv(void)
+-{
+-	unsigned int i;
+-
+-	for (i = 0; i < oldargc; i++)
+-		free(oldargv[i]);
+-	oldargc = newargc;
+-	newargc = 0;
+-	for (i = 0; i < oldargc; i++) {
+-		oldargv[i] = newargv[i];
+-		newargv[i] = NULL;
+-	}
+-}
+-
+ /* like puts but with xml encoding */
+ static void
+ xmlEncode(char *text)
+@@ -736,9 +676,6 @@ iptables_xml_main(int argc, char *argv[])
+ 			int quote_open, quoted;
+ 			char param_buffer[1024];
+ 
+-			/* reset the newargv */
+-			newargc = 0;
+-
+ 			if (buffer[0] == '[') {
+ 				/* we have counters in our input */
+ 				char *ptr = strchr(buffer, ']');
+diff --git a/iptables/xshared.c b/iptables/xshared.c
+index 742502154aa55..84dbea562576e 100644
+--- a/iptables/xshared.c
++++ b/iptables/xshared.c
+@@ -406,3 +406,126 @@ void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format)
+ 	       ipv6_addr_to_string(&fw6->ipv6.dst,
+ 				   &fw6->ipv6.dmsk, format));
+ }
++
++/* global new argv and argc */
++char *newargv[255];
++int newargc = 0;
++
++/* saved newargv and newargc from save_argv() */
++char *oldargv[255];
++int oldargc = 0;
++
++/* arg meta data, were they quoted, frinstance */
++int newargvattr[255];
++
++/* function adding one argument to newargv, updating newargc
++ * returns true if argument added, false otherwise */
++int add_argv(const char *what, int quoted)
++{
++	DEBUGP("add_argv: %s\n", what);
++	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
++		newargv[newargc] = strdup(what);
++		newargvattr[newargc] = quoted;
++		newargv[++newargc] = NULL;
++		return 1;
++	} else {
++		xtables_error(PARAMETER_PROBLEM,
++			      "Parser cannot handle more arguments\n");
++	}
++}
++
++void free_argv(void)
++{
++	while (newargc)
++		free(newargv[--newargc]);
++	while (oldargc)
++		free(oldargv[--oldargc]);
++}
++
++/* Save parsed rule for comparison with next rule to perform action aggregation
++ * on duplicate conditions.
++ */
++void save_argv(void)
++{
++	unsigned int i;
++
++	while (oldargc)
++		free(oldargv[--oldargc]);
++
++	oldargc = newargc;
++	newargc = 0;
++	for (i = 0; i < oldargc; i++) {
++		oldargv[i] = newargv[i];
++	}
++}
++
++void add_param_to_argv(char *parsestart, int line)
++{
++	int quote_open = 0, escaped = 0, param_len = 0;
++	char param_buffer[1024], *curchar;
++
++	/* After fighting with strtok enough, here's now
++	 * a 'real' parser. According to Rusty I'm now no
++	 * longer a real hacker, but I can live with that */
++
++	for (curchar = parsestart; *curchar; curchar++) {
++		if (quote_open) {
++			if (escaped) {
++				param_buffer[param_len++] = *curchar;
++				escaped = 0;
++				continue;
++			} else if (*curchar == '\\') {
++				escaped = 1;
++				continue;
++			} else if (*curchar == '"') {
++				quote_open = 0;
++				*curchar = '"';
++			} else {
++				param_buffer[param_len++] = *curchar;
++				continue;
++			}
++		} else {
++			if (*curchar == '"') {
++				quote_open = 1;
++				continue;
++			}
++		}
++
++		switch (*curchar) {
++		case '"':
++			break;
++		case ' ':
++		case '\t':
++		case '\n':
++			if (!param_len) {
++				/* two spaces? */
++				continue;
++			}
++			break;
++		default:
++			/* regular character, copy to buffer */
++			param_buffer[param_len++] = *curchar;
++
++			if (param_len >= sizeof(param_buffer))
++				xtables_error(PARAMETER_PROBLEM,
++					      "Parameter too long!");
++			continue;
++		}
++
++		param_buffer[param_len] = '\0';
++
++		/* check if table name specified */
++		if ((param_buffer[0] == '-' &&
++		     param_buffer[1] != '-' &&
++		     strchr(param_buffer, 't')) ||
++		    (!strncmp(param_buffer, "--t", 3) &&
++		     !strncmp(param_buffer, "--table", strlen(param_buffer)))) {
++			xtables_error(PARAMETER_PROBLEM,
++				      "The -t option (seen in line %u) cannot be used in %s.\n",
++				      line, xt_params->program_name);
++		}
++
++		add_argv(param_buffer, 0);
++		param_len = 0;
++	}
++}
+diff --git a/iptables/xshared.h b/iptables/xshared.h
+index bfdb10b2701e5..4f567db9f410b 100644
+--- a/iptables/xshared.h
++++ b/iptables/xshared.h
+@@ -119,6 +119,19 @@ bool xs_has_arg(int argc, char *argv[]);
+ 
+ extern const struct xtables_afinfo *afinfo;
+ 
++extern char *newargv[];
++extern int newargc;
++
++extern char *oldargv[];
++extern int oldargc;
++
++extern int newargvattr[];
++
++int add_argv(const char *what, int quoted);
++void free_argv(void);
++void save_argv(void);
++void add_param_to_argv(char *parsestart, int line);
++
+ void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
+ void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
+ 
+-- 
+2.21.0
+
diff --git a/SOURCES/xtables-Introduce-and-use-common-function-to-parse-v.patch b/SOURCES/xtables-Introduce-and-use-common-function-to-parse-v.patch
new file mode 100644
index 0000000..8189830
--- /dev/null
+++ b/SOURCES/xtables-Introduce-and-use-common-function-to-parse-v.patch
@@ -0,0 +1,259 @@
+From cc564f1b24a61d8abcd1163323ba68d373ef3d7c Mon Sep 17 00:00:00 2001
+From: Phil Sutter <psutter@redhat.com>
+Date: Wed, 3 Apr 2019 20:30:11 +0200
+Subject: [PATCH] xtables: Introduce and use common function to parse
+ val[/mask] arguments
+
+Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1657075
+Upstream Status: iptables commit 29b1d97764d18
+
+commit 29b1d97764d1849651388d870565b3fa815a0bd8
+Author: Serhey Popovych <serhe.popovych@gmail.com>
+Date:   Thu Mar 1 13:03:11 2018 +0200
+
+    xtables: Introduce and use common function to parse val[/mask] arguments
+
+    There are a couple of places in both core and extensions where arguments
+    in the form of val[/mask] is parsed (see XTTYPE_MARKMASK32).
+
+    In some cases symbolic name might be used which is mapped in code to
+    numeric value.
+
+    Introduce common function to handle both cases where value given is
+    either val[/mask] or symbolic name.
+
+    Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
+    Signed-off-by: Florian Westphal <fw@strlen.de>
+
+Signed-off-by: Phil Sutter <psutter@redhat.com>
+---
+ extensions/libipt_realm.c   | 29 ++++++---------------
+ extensions/libxt_devgroup.c | 35 ++++---------------------
+ include/xtables.h           | 11 ++++++++
+ libxtables/xtables.c        | 52 +++++++++++++++++++++++++++++++++++++
+ libxtables/xtoptions.c      | 22 +---------------
+ 5 files changed, 77 insertions(+), 72 deletions(-)
+
+diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
+index fffb1218db7a6..0bfbaea0add23 100644
+--- a/extensions/libipt_realm.c
++++ b/extensions/libipt_realm.c
+@@ -34,30 +34,17 @@ static struct xtables_lmap *realms;
+ 
+ static void realm_parse(struct xt_option_call *cb)
+ {
+-	struct xt_realm_info *realminfo = cb->data;
+-	int id;
+-	char *end;
++	struct xt_realm_info *ri = cb->data;
++	unsigned int id, mask;
+ 
+ 	xtables_option_parse(cb);
+-	realminfo->id = strtoul(cb->arg, &end, 0);
+-	if (end != cb->arg && (*end == '/' || *end == '\0')) {
+-		if (*end == '/')
+-			realminfo->mask = strtoul(end+1, &end, 0);
+-		else
+-			realminfo->mask = 0xffffffff;
+-		if (*end != '\0' || end == cb->arg)
+-			xtables_error(PARAMETER_PROBLEM,
+-				   "Bad realm value \"%s\"", cb->arg);
+-	} else {
+-		id = xtables_lmap_name2id(realms, cb->arg);
+-		if (id == -1)
+-			xtables_error(PARAMETER_PROBLEM,
+-				   "Realm \"%s\" not found", cb->arg);
+-		realminfo->id = id;
+-		realminfo->mask = 0xffffffff;
+-	}
++	xtables_parse_val_mask(cb, &id, &mask, realms);
++
++	ri->id = id;
++	ri->mask = mask;
++
+ 	if (cb->invert)
+-		realminfo->invert = 1;
++		ri->invert = 1;
+ }
+ 
+ static void
+diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c
+index ebfa2aee80cf2..604828276177b 100644
+--- a/extensions/libxt_devgroup.c
++++ b/extensions/libxt_devgroup.c
+@@ -35,49 +35,24 @@ static const char f_devgroups[] = "/etc/iproute2/group";
+ /* array of devgroups from f_devgroups[] */
+ static struct xtables_lmap *devgroups;
+ 
+-static void devgroup_parse_groupspec(const char *arg, unsigned int *group,
+-				     unsigned int *mask)
+-{
+-	char *end;
+-	bool ok;
+-
+-	ok = xtables_strtoui(arg, &end, group, 0, UINT32_MAX);
+-	if (ok && (*end == '/' || *end == '\0')) {
+-		if (*end == '/')
+-			ok = xtables_strtoui(end + 1, NULL, mask,
+-			                     0, UINT32_MAX);
+-		else
+-			*mask = ~0U;
+-		if (!ok)
+-			xtables_error(PARAMETER_PROBLEM,
+-				      "Bad group value \"%s\"", arg);
+-	} else {
+-		*group = xtables_lmap_name2id(devgroups, arg);
+-		if (*group == -1)
+-			xtables_error(PARAMETER_PROBLEM,
+-				      "Device group \"%s\" not found", arg);
+-		*mask = ~0U;
+-	}
+-}
+-
+ static void devgroup_parse(struct xt_option_call *cb)
+ {
+ 	struct xt_devgroup_info *info = cb->data;
+-	unsigned int id, mask;
++	unsigned int group, mask;
+ 
+ 	xtables_option_parse(cb);
++	xtables_parse_val_mask(cb, &group, &mask, devgroups);
++
+ 	switch (cb->entry->id) {
+ 	case O_SRC_GROUP:
+-		devgroup_parse_groupspec(cb->arg, &id, &mask);
+-		info->src_group = id;
++		info->src_group = group;
+ 		info->src_mask  = mask;
+ 		info->flags |= XT_DEVGROUP_MATCH_SRC;
+ 		if (cb->invert)
+ 			info->flags |= XT_DEVGROUP_INVERT_SRC;
+ 		break;
+ 	case O_DST_GROUP:
+-		devgroup_parse_groupspec(cb->arg, &id, &mask);
+-		info->dst_group = id;
++		info->dst_group = group;
+ 		info->dst_mask  = mask;
+ 		info->flags |= XT_DEVGROUP_MATCH_DST;
+ 		if (cb->invert)
+diff --git a/include/xtables.h b/include/xtables.h
+index 021726708b2ee..47481e693ca25 100644
+--- a/include/xtables.h
++++ b/include/xtables.h
+@@ -501,6 +501,17 @@ extern void xtables_save_string(const char *value);
+ 
+ extern void xtables_print_num(uint64_t number, unsigned int format);
+ 
++extern void xtables_parse_val_mask(struct xt_option_call *cb,
++				   unsigned int *val, unsigned int *mask,
++				   const struct xtables_lmap *lmap);
++
++static inline void xtables_parse_mark_mask(struct xt_option_call *cb,
++					   unsigned int *mark,
++					   unsigned int *mask)
++{
++	xtables_parse_val_mask(cb, mark, mask, NULL);
++}
++
+ #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ #	ifdef _INIT
+ #		undef _init
+diff --git a/libxtables/xtables.c b/libxtables/xtables.c
+index 7210d3706bf26..2981f52bc767f 100644
+--- a/libxtables/xtables.c
++++ b/libxtables/xtables.c
+@@ -1950,6 +1950,58 @@ void xtables_print_num(uint64_t number, unsigned int format)
+ 	printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
+ }
+ 
++void xtables_parse_val_mask(struct xt_option_call *cb,
++			    unsigned int *val, unsigned int *mask,
++			    const struct xtables_lmap *lmap)
++{
++	char *end;
++
++	*mask = ~0U;
++
++	if (!xtables_strtoui(cb->arg, &end, val, 0, UINT32_MAX)) {
++		if (lmap)
++			goto name2val;
++		else
++			goto bad_val;
++	}
++
++	if (*end == '\0')
++		return;
++
++	if (*end != '/') {
++		if (lmap)
++			goto name2val;
++		else
++			goto garbage;
++	}
++
++	if (!xtables_strtoui(end + 1, &end, mask, 0, UINT32_MAX))
++		goto bad_val;
++
++	if (*end == '\0')
++		return;
++
++garbage:
++	xt_params->exit_err(PARAMETER_PROBLEM,
++			"%s: trailing garbage after value "
++			"for option \"--%s\".\n",
++			cb->ext_name, cb->entry->name);
++
++bad_val:
++	xt_params->exit_err(PARAMETER_PROBLEM,
++			"%s: bad integer value for option \"--%s\", "
++			"or out of range.\n",
++			cb->ext_name, cb->entry->name);
++
++name2val:
++	*val = xtables_lmap_name2id(lmap, cb->arg);
++	if ((int)*val == -1)
++		xt_params->exit_err(PARAMETER_PROBLEM,
++			"%s: could not map name %s to an integer value "
++			"for option \"--%s\".\n",
++			cb->ext_name, cb->arg, cb->entry->name);
++}
++
+ int kernel_version;
+ 
+ void get_kernel_version(void)
+diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
+index 1d3fda73dedf7..4bbc03ab0f047 100644
+--- a/libxtables/xtoptions.c
++++ b/libxtables/xtoptions.c
+@@ -432,27 +432,7 @@ static void xtopt_parse_tosmask(struct xt_option_call *cb)
+  */
+ static void xtopt_parse_markmask(struct xt_option_call *cb)
+ {
+-	unsigned int mark = 0, mask = ~0U;
+-	char *end;
+-
+-	if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
+-		xt_params->exit_err(PARAMETER_PROBLEM,
+-			"%s: bad mark value for option \"--%s\", "
+-			"or out of range.\n",
+-			cb->ext_name, cb->entry->name);
+-	if (*end == '/' &&
+-	    !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
+-		xt_params->exit_err(PARAMETER_PROBLEM,
+-			"%s: bad mask value for option \"--%s\", "
+-			"or out of range.\n",
+-			cb->ext_name, cb->entry->name);
+-	if (*end != '\0')
+-		xt_params->exit_err(PARAMETER_PROBLEM,
+-			"%s: trailing garbage after value "
+-			"for option \"--%s\".\n",
+-			cb->ext_name, cb->entry->name);
+-	cb->val.mark = mark;
+-	cb->val.mask = mask;
++	xtables_parse_mark_mask(cb, &cb->val.mark, &cb->val.mask);
+ }
+ 
+ static int xtopt_sysloglvl_compare(const void *a, const void *b)
+-- 
+2.21.0
+
diff --git a/SPECS/iptables.spec b/SPECS/iptables.spec
index 22d331f..1725e69 100644
--- a/SPECS/iptables.spec
+++ b/SPECS/iptables.spec
@@ -7,7 +7,7 @@
 Name: iptables
 Summary: Tools for managing Linux kernel packet filtering capabilities
 Version: 1.4.21
-Release: 28%{?dist}
+Release: 33%{?dist}
 Source: http://www.netfilter.org/projects/iptables/files/%{name}-%{version}.tar.bz2
 Source1: iptables.init
 Source2: iptables-config
@@ -39,6 +39,42 @@ Patch19: ip-6-tables-restore-Don-t-ignore-missing-wait-interv.patch
 Patch20: ip-6-tables-restore-Don-t-accept-wait-interval-witho.patch
 Patch21: utils-nfnl_osf-Fix-synopsis-in-help-text.patch
 Patch22: utils-Add-a-man-page-for-nfnl_osf.patch
+Patch23: Mark-fall-through-cases-in-switch-statements.patch
+Patch24: libiptc-Simplify-alloc_handle-function-signature.patch
+Patch25: libxtables-Fix-potential-array-overrun-in-xtables_op.patch
+Patch26: ip-6-tables-restore-Fix-for-uninitialized-array-curt.patch
+Patch27: nfnl_osf-Replace-deprecated-nfnl_talk-by-nfnl_query.patch
+Patch28: libxt_string-Avoid-potential-array-out-of-bounds-acc.patch
+Patch29: libxt_string-Fix-array-out-of-bounds-check.patch
+Patch30: libxtables-Don-t-read-garbage-in-xtables_strtoui.patch
+Patch31: libxt_time-Drop-initialization-of-variable-year.patch
+Patch32: libxt_sctp-fix-array-out-of-range-in-print_chunk.patch
+Patch33: libxt_ipvs-Avoid-potential-buffer-overrun.patch
+Patch34: libxt_conntrack-Version-0-does-not-support-XT_CONNTR.patch
+Patch35: Fix-a-few-cases-of-pointless-assignments.patch
+Patch36: nfnl_osf-Drop-pointless-check-in-xt_osf_strchr.patch
+Patch37: libxt_conntrack-Avoid-potential-buffer-overrun.patch
+Patch38: libxtables-Check-extension-real_name-length.patch
+Patch39: libiptc-NULL-terminate-errorname.patch
+Patch40: libxtables-Avoid-calling-memcpy-with-NULL-source.patch
+Patch41: libxt_LED-Avoid-string-overrun-while-parsing-led-tri.patch
+Patch42: libxt_recent-Remove-ineffective-checks-for-info-name.patch
+Patch43: libxtables-move-some-code-to-avoid-cautions-in-vfork.patch
+Patch44: libxtables-Use-posix_spawn-instead-of-vfork.patch
+Patch45: libiptc-Avoid-side-effect-in-memset-calls.patch
+Patch46: Share-print_ipv-4-6-_addr-from-xtables.patch
+Patch47: extensions-REJECT-Check-for-array-overrun.patch
+Patch48: list-fix-prefetch-dummy.patch
+Patch49: extensions-Add-macro-_DEFAULT_SOURCE.patch
+Patch50: Consolidate-DEBUGP-macros.patch
+Patch51: xshared-Consolidate-argv-construction-routines.patch
+Patch52: extensions-Fix-ipvs-vproto-parsing.patch
+Patch53: extensions-Fix-ipvs-vproto-option-printing.patch
+Patch54: extensions-libxt_devgroup-Fix-the-path-of-the-group-.patch
+Patch55: extensions-Initialize-linear-mapping-of-symbols-in-_.patch
+Patch56: xtables-Introduce-and-use-common-function-to-parse-v.patch
+Patch57: iptables-xml-fix-segfault-if-missing-space-after-A.patch
+Patch58: man-iptables-save-Add-note-about-module-autoloading.patch
 
 Group: System Environment/Base
 URL: http://www.netfilter.org/
@@ -104,29 +140,7 @@ Currently only provides nfnl_osf with the pf.os database.
 
 
 %prep
-%setup -q
-%patch1 -p1 -b .rhbz_1054871
-%patch2 -p1 -b .libxt_cgroup
-%patch3 -p1 -b .wait_seconds
-%patch4 -p1 -b .flock_wait
-%patch5 -p1 -b .rhbz_1261238
-%patch6 -p1 -b .rhbz_1298879
-%patch7 -p1 -b .wait-interval
-%patch8 -p1 -b .do_not_lock_again_and_again
-%patch9 -p1 -b .use_the_blocking_file_lock_request
-%patch10 -p1 -b .configure_set_lock_file_path
-%patch11 -p1 -b .move_XT_LOCK_NAME_to_config.h
-%patch12 -p1 -b .remove_duplicated_argument_parsing
-%patch13 -p1 -b .restore_support_acquiring_the_lock
-%patch14 -p1 -b .do_not_set_changed_for_check_options
-%patch15 -p1 -b .restore_version
-%patch16 -p1 -b .restore_wait_man
-%patch17 -p1 -b .tcpmss_detect_invalid_ranges
-%patch18 -p1 -b .exit_unknown_option
-%patch19 -p1 -b .require_wait_value
-%patch20 -p1 -b .wait_interval_needs_wait
-%patch21 -p1 -b .nfnl_osf_synopsis
-%patch22 -p1 -b .nfnl_osf_man_page
+%autosetup -p1
 
 %build
 # Since patches above touch configure.ac we must regen configure
@@ -290,6 +304,26 @@ done
 
 
 %changelog
+* Thu Apr 18 2019 Phil Sutter <psutter@redhat.com> - 1.4.21-33
+- man: iptables-save: Add note about module autoloading (RHBZ#1691380)
+
+* Tue Apr 09 2019 Phil Sutter <psutter@redhat.com> - 1.4.21-32
+- iptables-xml: fix segfault if missing space after -A (RHBZ#1525980)
+
+* Wed Apr 03 2019 Phil Sutter <psutter@redhat.com> - 1.4.21-31
+- Fix iptables-restore with empty comment in rule (RHBZ#1668475)
+- Fix parsing and printing of -m ipvs --vproto option (RHBZ#1679726)
+- Fix for wrong location of devgroup definition file (RHBZ#1657075)
+- Fix for non-numeric devgroup name output (RHBZ#1657075)
+- Reject negative realm values (RHBZ#1657075)
+
+* Fri Mar 15 2019 Phil Sutter - 1.4.21-30
+- Drop leftover variable from init script (RHBZ#1520534)
+
+* Fri Mar 15 2019 Phil Sutter - 1.4.21-29
+- Do not attempt to unload any modules when stopping the firewall (RHBZ#1520534)
+- Fix for covscan warnings (RHBZ#1525980)
+
 * Tue Jun 05 2018 Phil Sutter - 1.4.21-28
 - Add nfnl_osf.8 man page (RHBZ#1487331)