diff --git a/SOURCES/bz1784879-fix-vip-removal-on-abort.patch b/SOURCES/bz1784879-fix-vip-removal-on-abort.patch
new file mode 100644
index 0000000..0d8a1a6
--- /dev/null
+++ b/SOURCES/bz1784879-fix-vip-removal-on-abort.patch
@@ -0,0 +1,159 @@
+From 44f2b1782e3d7afe7ede3779e7b9896cbd6c26c7 Mon Sep 17 00:00:00 2001
+From: Quentin Armitage <quentin@armitage.org.uk>
+Date: Fri, 15 Dec 2017 21:14:24 +0000
+Subject: [PATCH] Fix removing left-over addresses if keepalived aborts
+
+Issue #718 reported that if keepalived terminates abnormally when
+it has vrrp instances in master state, it doesn't remove the
+left-over VIPs and eVIPs when it restarts. This is despite
+commit f4c10426c saying that it resolved this problem.
+
+It turns out that commit f4c10426c did resolve the problem for VIPs
+or eVIPs, although it did resolve the issue for iptables and ipset
+configuration.
+
+This commit now really resolves the problem, and residual VIPs and
+eVIPs are removed at startup.
+
+Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
+---
+ keepalived/include/vrrp_ipaddress.h |  2 +-
+ keepalived/vrrp/vrrp.c              | 16 ++++++++--------
+ keepalived/vrrp/vrrp_daemon.c       |  6 +++---
+ keepalived/vrrp/vrrp_ipaddress.c    |  6 +++---
+ 4 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/keepalived/include/vrrp_ipaddress.h b/keepalived/include/vrrp_ipaddress.h
+index 900dfd7f..4d613652 100644
+--- a/keepalived/include/vrrp_ipaddress.h
++++ b/keepalived/include/vrrp_ipaddress.h
+@@ -93,7 +93,7 @@ struct ipt_handle;	// AAGH - TODO
+ /* prototypes */
+ extern char *ipaddresstos(char *, ip_address_t *);
+ extern int netlink_ipaddress(ip_address_t *, int);
+-extern bool netlink_iplist(list, int);
++extern bool netlink_iplist(list, int, bool);
+ extern void handle_iptable_rule_to_iplist(struct ipt_handle *, list, int, bool force);
+ extern void free_ipaddress(void *);
+ extern void dump_ipaddress(void *);
+diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c
+index 3d2bfe41..d58c3690 100644
+--- a/keepalived/vrrp/vrrp.c
++++ b/keepalived/vrrp/vrrp.c
+@@ -74,13 +74,13 @@
+ 
+ /* add/remove Virtual IP addresses */
+ static bool
+-vrrp_handle_ipaddress(vrrp_t * vrrp, int cmd, int type)
++vrrp_handle_ipaddress(vrrp_t * vrrp, int cmd, int type, bool force)
+ {
+ 	if (__test_bit(LOG_DETAIL_BIT, &debug))
+ 		log_message(LOG_INFO, "VRRP_Instance(%s) %s protocol %s", vrrp->iname,
+ 		       (cmd == IPADDRESS_ADD) ? "setting" : "removing",
+ 		       (type == VRRP_VIP_TYPE) ? "VIPs." : "E-VIPs.");
+-	return netlink_iplist((type == VRRP_VIP_TYPE) ? vrrp->vip : vrrp->evip, cmd);
++	return netlink_iplist((type == VRRP_VIP_TYPE) ? vrrp->vip : vrrp->evip, cmd, force);
+ }
+ 
+ #ifdef _HAVE_FIB_ROUTING_
+@@ -1283,9 +1283,9 @@ vrrp_state_become_master(vrrp_t * vrrp)
+ 	/* add the ip addresses */
+ 	vrrp_handle_accept_mode(vrrp, IPADDRESS_ADD, false);
+ 	if (!LIST_ISEMPTY(vrrp->vip))
+-		vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_VIP_TYPE);
++		vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_VIP_TYPE, false);
+ 	if (!LIST_ISEMPTY(vrrp->evip))
+-		vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_EVIP_TYPE);
++		vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_EVIP_TYPE, false);
+ 	vrrp->vipset = 1;
+ 
+ #ifdef _HAVE_FIB_ROUTING_
+@@ -1403,9 +1403,9 @@ vrrp_restore_interface(vrrp_t * vrrp, bool advF, bool force)
+ 	    __test_bit(DONT_RELEASE_VRRP_BIT, &debug) ||
+ 	    __test_bit(RELEASE_VIPS_BIT, &debug)) {
+ 		if (!LIST_ISEMPTY(vrrp->vip))
+-			vrrp_handle_ipaddress(vrrp, IPADDRESS_DEL, VRRP_VIP_TYPE);
++			vrrp_handle_ipaddress(vrrp, IPADDRESS_DEL, VRRP_VIP_TYPE, force);
+ 		if (!LIST_ISEMPTY(vrrp->evip))
+-			vrrp_handle_ipaddress(vrrp, IPADDRESS_DEL, VRRP_EVIP_TYPE);
++			vrrp_handle_ipaddress(vrrp, IPADDRESS_DEL, VRRP_EVIP_TYPE, force);
+ 		vrrp_handle_accept_mode(vrrp, IPADDRESS_DEL, force);
+ 		vrrp->vipset = 0;
+ 	}
+@@ -2740,9 +2740,9 @@ restore_vrrp_state(vrrp_t *old_vrrp, vrrp_t *vrrp)
+ 	if (vrrp->vipset) {
+ 		vrrp_handle_accept_mode(vrrp, IPADDRESS_ADD, false);
+ 		if (!LIST_ISEMPTY(vrrp->vip))
+-			added_ip_addr = vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_VIP_TYPE);
++			added_ip_addr = vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_VIP_TYPE, false);
+ 		if (!LIST_ISEMPTY(vrrp->evip)) {
+-			if (vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_EVIP_TYPE))
++			if (vrrp_handle_ipaddress(vrrp, IPADDRESS_ADD, VRRP_EVIP_TYPE, false))
+ 				added_ip_addr = true;
+ 		}
+ #ifdef _HAVE_FIB_ROUTING_
+diff --git a/keepalived/vrrp/vrrp_daemon.c b/keepalived/vrrp/vrrp_daemon.c
+index 1c2f9e89..32bf4560 100644
+--- a/keepalived/vrrp/vrrp_daemon.c
++++ b/keepalived/vrrp/vrrp_daemon.c
+@@ -103,7 +103,7 @@ stop_vrrp(int status)
+ 	netlink_rulelist(vrrp_data->static_rules, IPRULE_DEL, false);
+ 	netlink_rtlist(vrrp_data->static_routes, IPROUTE_DEL);
+ #endif
+-	netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL);
++	netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL, false);
+ 
+ #ifdef _WITH_SNMP_
+ 	if (global_data->enable_snmp_keepalived || global_data->enable_snmp_rfcv2 || global_data->enable_snmp_rfcv3)
+@@ -245,7 +245,7 @@ start_vrrp(void)
+ 	}
+ 	else {
+ 		/* Clear leftover static entries */
+-		netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL);
++		netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL, false);
+ #ifdef _HAVE_FIB_ROUTING_
+ 		netlink_rtlist(vrrp_data->static_routes, IPROUTE_DEL);
+ 		netlink_error_ignore = ENOENT;
+@@ -286,7 +286,7 @@ start_vrrp(void)
+ #endif
+ 
+ 	/* Set static entries */
+-	netlink_iplist(vrrp_data->static_addresses, IPADDRESS_ADD);
++	netlink_iplist(vrrp_data->static_addresses, IPADDRESS_ADD, false);
+ #ifdef _HAVE_FIB_ROUTING_
+ 	netlink_rtlist(vrrp_data->static_routes, IPROUTE_ADD);
+ 	netlink_rulelist(vrrp_data->static_rules, IPRULE_ADD, false);
+diff --git a/keepalived/vrrp/vrrp_ipaddress.c b/keepalived/vrrp/vrrp_ipaddress.c
+index eb332e72..e8dca912 100644
+--- a/keepalived/vrrp/vrrp_ipaddress.c
++++ b/keepalived/vrrp/vrrp_ipaddress.c
+@@ -143,7 +143,7 @@ netlink_ipaddress(ip_address_t *ipaddress, int cmd)
+ 
+ /* Add/Delete a list of IP addresses */
+ bool
+-netlink_iplist(list ip_list, int cmd)
++netlink_iplist(list ip_list, int cmd, bool force)
+ {
+ 	ip_address_t *ipaddr;
+ 	element e;
+@@ -161,7 +161,7 @@ netlink_iplist(list ip_list, int cmd)
+ 		ipaddr = ELEMENT_DATA(e);
+ 		if ((cmd == IPADDRESS_ADD && !ipaddr->set) ||
+ 		    (cmd == IPADDRESS_DEL &&
+-		     (ipaddr->set || __test_bit(DONT_RELEASE_VRRP_BIT, &debug)))) {
++		     (force || ipaddr->set || __test_bit(DONT_RELEASE_VRRP_BIT, &debug)))) {
+ 			if (netlink_ipaddress(ipaddr, cmd) > 0) {
+ 				ipaddr->set = !(cmd == IPADDRESS_DEL);
+ 				changed_entries = true;
+@@ -581,7 +581,7 @@ clear_diff_address(struct ipt_handle *h, list l, list n)
+ 	/* All addresses removed */
+ 	if (LIST_ISEMPTY(n)) {
+ 		log_message(LOG_INFO, "Removing a complete VIP or e-VIP block");
+-		netlink_iplist(l, IPADDRESS_DEL);
++		netlink_iplist(l, IPADDRESS_DEL, false);
+ 		handle_iptable_rule_to_iplist(h, l, IPADDRESS_DEL, false);
+ 		return;
+ 	}
+-- 
+2.25.1
+
diff --git a/SOURCES/bz1818891-build-with-latest-ipset.patch b/SOURCES/bz1818891-build-with-latest-ipset.patch
new file mode 100644
index 0000000..10b7414
--- /dev/null
+++ b/SOURCES/bz1818891-build-with-latest-ipset.patch
@@ -0,0 +1,95 @@
+diff -Naur a/keepalived/vrrp/vrrp_ipset.c b/keepalived/vrrp/vrrp_ipset.c
+--- a/keepalived/vrrp/vrrp_ipset.c	2020-03-30 11:16:29.420721279 -0500
++++ b/keepalived/vrrp/vrrp_ipset.c	2020-03-30 11:16:57.188181698 -0500
+@@ -52,11 +52,11 @@
+ #include <dlfcn.h>
+ 
+ /* The addresses of the functions we want */
+-struct ipset_session* (*ipset_session_init_addr)(ipset_outfn outfn);
++struct ipset_session* (*ipset_session_init_addr)(ipset_print_outfn outfn, const void *p);
+ int (*ipset_session_fini_addr)(struct ipset_session *session);
+ struct ipset_data* (*ipset_session_data_addr)(const struct ipset_session *session);
+ const char* (*ipset_session_error_addr)(const struct ipset_session *session);
+-int (*ipset_envopt_parse_addr)(struct ipset_session *session, int env, const char *str);
++void (*ipset_envopt_set_addr)(struct ipset_session *session, int env);
+ const struct ipset_type* (*ipset_type_get_addr)(struct ipset_session *session, enum ipset_cmd cmd);
+ int (*ipset_data_set_addr)(struct ipset_data *data, enum ipset_opt opt, const void *value);
+ int (*ipset_cmd_addr)(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno);
+@@ -66,8 +66,7 @@
+ #define ipset_session_init (*ipset_session_init_addr)
+ #define ipset_session_fini (*ipset_session_fini_addr)
+ #define ipset_session_data (*ipset_session_data_addr)
+-#define ipset_session_error (*ipset_session_error_addr)
+-#define ipset_envopt_parse (*ipset_envopt_parse_addr)
++#define ipset_envopt_set (*ipset_envopt_set_addr)
+ #define ipset_type_get (*ipset_type_get_addr)
+ #define ipset_data_set (*ipset_data_set_addr)
+ /* Unfortunately ipset_cmd conflicts with struct ipset_cmd */
+@@ -79,6 +78,21 @@
+ #define ipset_cmd1 ipset_cmd
+ #endif
+ 
++static int
++__attribute__ ((format(printf, 3, 4)))
++ipset_printf(__attribute ((__unused__)) struct ipset_session *session, void *p, const char *fmt, ...)
++{
++	va_list args;
++
++	log_message(LOG_INFO, "libipset message from %s", (const char *)p);
++
++	va_start(args, fmt);
++	vlog_message(LOG_INFO, fmt, args);
++	va_end(args);
++
++	return 0;
++}
++
+ static bool
+ do_ipset_cmd(struct ipset_session* session, enum ipset_cmd cmd, const char *setname,
+ 		const ip_address_t *addr, uint32_t timeout, const char* iface)
+@@ -152,7 +166,7 @@
+ {
+ 	struct ipset_session *session;
+ 
+-	session = ipset_session_init(printf);
++	session = ipset_session_init(ipset_printf, "create_sets");
+ 	if (!session) {
+ 		log_message(LOG_INFO, "Cannot initialize ipset session.");
+ 		return false;
+@@ -161,7 +175,7 @@
+ 	/* If we aren't reloading, don't worry if sets already exists. With the
+ 	 * IPSET_ENV_EXIST option set, any existing entries in the set are removed. */
+ 	if (!reload)
+-		ipset_envopt_parse(session, IPSET_ENV_EXIST, NULL);
++		ipset_envopt_set(session, IPSET_ENV_EXIST);
+ 
+ 	if (block_ipv4) {
+ 		if (!reload || !has_ipset_setname(session, addr4))
+@@ -242,8 +256,7 @@
+ 	if (!(ipset_session_init_addr = dlsym(libipset_handle, "ipset_session_init")) ||
+ 	    !(ipset_session_fini_addr = dlsym(libipset_handle, "ipset_session_fini")) ||
+ 	    !(ipset_session_data_addr = dlsym(libipset_handle,"ipset_session_data")) ||
+-	    !(ipset_session_error_addr = dlsym(libipset_handle,"ipset_session_error")) ||
+-	    !(ipset_envopt_parse_addr = dlsym(libipset_handle,"ipset_envopt_parse")) ||
++	    !(ipset_envopt_set_addr = dlsym(libipset_handle,"ipset_envopt_set")) ||
+ 	    !(ipset_type_get_addr = dlsym(libipset_handle,"ipset_type_get")) ||
+ 	    !(ipset_data_set_addr = dlsym(libipset_handle,"ipset_data_set")) ||
+ 	    !(ipset_cmd_addr = dlsym(libipset_handle,"ipset_cmd")) ||
+@@ -275,7 +288,7 @@
+ 		return true;
+ #endif
+ 
+-	session = ipset_session_init(printf);
++	session = ipset_session_init(ipset_printf, "remove_ipsets");
+ 	if (!session) {
+ 		log_message(LOG_INFO, "Cannot initialize ipset session.");
+ 		return false;
+@@ -301,7 +314,7 @@
+ 
+ struct ipset_session* ipset_session_start(void)
+ {
+-	return ipset_session_init(NULL);
++	return ipset_session_init(ipset_printf, "session_start");
+ }
+ 
+ void ipset_session_end(struct ipset_session* session)
diff --git a/SPECS/keepalived.spec b/SPECS/keepalived.spec
index d997f0a..512b52b 100644
--- a/SPECS/keepalived.spec
+++ b/SPECS/keepalived.spec
@@ -9,7 +9,7 @@
 Name: keepalived
 Summary: Load balancer and high availability service
 Version: 1.3.5
-Release: 16%{?dist}
+Release: 19%{?dist}
 License: GPLv2+
 URL: http://www.keepalived.org/
 Group: System Environment/Daemons
@@ -38,8 +38,10 @@ patch17: bz1678480-resolve-compiler-warning.patch
 patch18: bz1678480-include-check_api-in-ipwrapper.patch
 patch19: bz1715308-make-checker-variables-non-global.patch
 patch20: bz1715308-fix-checkers-comparison-on-reload.patch
+patch21: bz1818891-build-with-latest-ipset.patch
+patch22: bz1784879-fix-vip-removal-on-abort.patch
 
-Requires: ipset-libs
+Requires: ipset-libs >= 7.1
 Requires(post): systemd
 Requires(preun): systemd
 Requires(postun): systemd
@@ -52,7 +54,7 @@ BuildRequires: net-snmp-devel
 BuildRequires: systemd-units
 BuildRequires: openssl-devel
 BuildRequires: libnl3-devel
-BuildRequires: ipset-devel
+BuildRequires: ipset-devel >= 7.1
 BuildRequires: iptables-devel
 BuildRequires: libnfnetlink-devel
 
@@ -89,6 +91,8 @@ Keepalived also implements the Virtual Router Redundancy Protocol
 %patch18 -p1
 %patch19 -p1
 %patch20 -p1
+%patch21 -p1
+%patch22 -p1
 
 %build
 %configure \
@@ -145,6 +149,15 @@ Keepalived also implements the Virtual Router Redundancy Protocol
 %{_mandir}/man8/keepalived.8*
 
 %changelog
+* Fri May 01 2020 Ryan O'Hara <rohara@redhat.com> - 1.3.5-19
+- Fix VIP removal on abort (#1784879)
+
+* Mon Mar 30 2020 Ryan O'Hara <rohara@redhat.com> - 1.3.5-18
+- Set required version for ipset-libs/ipset-devel (#1818891)
+
+* Mon Mar 30 2020 Ryan O'Hara <rohara@redhat.com> - 1.3.5-17
+- Build with latest ipset (#1818891)
+
 * Fri Jun 14 2019 Ryan O'Hara <rohara@redhat.com> - 1.3.5-16
 - Rework previous misc_script/vrrp_script patch (#1667292)