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 +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 +--- + 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 + + /* 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 - 1.3.5-19 +- Fix VIP removal on abort (#1784879) + +* Mon Mar 30 2020 Ryan O'Hara - 1.3.5-18 +- Set required version for ipset-libs/ipset-devel (#1818891) + +* Mon Mar 30 2020 Ryan O'Hara - 1.3.5-17 +- Build with latest ipset (#1818891) + * Fri Jun 14 2019 Ryan O'Hara - 1.3.5-16 - Rework previous misc_script/vrrp_script patch (#1667292)