From bd7cc2b8ae178ab6bc9b08b1b24a16ce2e9a7123 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Wed, 20 Sep 2023 13:42:28 +0100 Subject: [PATCH 1/2] vrrp: check prefix length when checking if deleted address is a VIP It is possible, for example, to configure both 10.1.0.3/32 and 10.1.0.3/24 on the same interface. When checking whether an address deleted from an interface is one of our VIPs, we need to also check the prefix length. Signed-off-by: Quentin Armitage --- keepalived/core/keepalived_netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keepalived/core/keepalived_netlink.c b/keepalived/core/keepalived_netlink.c index c843b3087..1bde1e63a 100644 --- a/keepalived/core/keepalived_netlink.c +++ b/keepalived/core/keepalived_netlink.c @@ -201,7 +201,8 @@ address_is_ours(struct ifaddrmsg *ifa, struct in_addr *addr, interface_t *ifp) vip_list; vip_list = vip_list == &vrrp->vip ? &vrrp->evip : NULL) { list_for_each_entry(ip_addr, vip_list, e_list) { - if (addr_is_equal(ifa, addr, ip_addr, ifp)) + if (addr_is_equal(ifa, addr, ip_addr, ifp) && + ifa->ifa_prefixlen == ip_addr->ifa.ifa_prefixlen) return ip_addr->dont_track ? NULL : vrrp; } } From 37d449a4531953f6b950b8e778a15684ffaca675 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Sun, 1 Oct 2023 15:10:50 +0100 Subject: [PATCH 2/2] core: fix config-check log file truncate on /dev/null etc Prior to a config-check, the log file is truncated (to 0 size). If /dev/null (or any other non-regular) file was specified, truncate() gives error EINVAL, which was not being handled in the code. This commit stops keepalived logging an error if the output file specified (or the default /dev/null) is a character device. Signed-off-by: Quentin Armitage --- keepalived/core/main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/keepalived/core/main.c b/keepalived/core/main.c index f9be12310..e64eafdaa 100644 --- a/keepalived/core/main.c +++ b/keepalived/core/main.c @@ -1001,6 +1001,7 @@ start_validate_reload_conf_child(void) int fd; int len; char exe_buf[128]; + struct stat sb; exe_buf[sizeof(exe_buf) - 1] = '\0'; ret = readlink("/proc/self/exe", exe_buf, sizeof(exe_buf)); @@ -1055,8 +1056,13 @@ start_validate_reload_conf_child(void) script.uid = 0; script.gid = 0; - if (truncate(global_data->reload_check_config, 0) && errno != ENOENT) - log_message(LOG_INFO, "truncate of config check log %s failed (%d) - %m", global_data->reload_check_config, errno); + if (truncate(global_data->reload_check_config, 0) && errno != ENOENT) { + /* The file exists, but truncate failed. It might be a character + * device like /dev/null. truncate() returns EINVAL in this case. */ + if (stat(global_data->reload_check_config, &sb) || + !S_ISCHR(sb.st_mode)) + log_message(LOG_INFO, "truncate of config check log %s failed (%d) - %m", global_data->reload_check_config, errno); + } create_reload_file();