From e597806899cdeb8016f99dfee7138f728a9f8390 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Thu, 6 Aug 2026 13:47:42 +0100 Subject: [PATCH 1/2] IPVS: implement bindto and bind_if for PING_CHECK The configuration allowed specifying bindto and bind_if for PING_CHECK but did not do anything with them. This commit now adds functionality to support the keywords. Signed-off-by: Quentin Armitage --- keepalived/check/check_ping.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/keepalived/check/check_ping.c b/keepalived/check/check_ping.c index ae0d54fae..b323c2e0c 100644 --- a/keepalived/check/check_ping.c +++ b/keepalived/check/check_ping.c @@ -419,9 +419,12 @@ icmp_ping_thread(thread_ref_t thread) static void icmp_connect_thread(thread_ref_t thread) { + socklen_t addrlen; checker_t *checker = THREAD_ARG(thread); ping_check_t *ping_checker = CHECKER_ARG(checker); conn_opts_t *co = checker->co; + const sockaddr_t *bind_addr = &co->bindto; + int fd; int size = SOCK_RECV_BUFF; @@ -453,6 +456,28 @@ icmp_connect_thread(thread_ref_t thread) return; } + /* Bind socket */ + if (co->bind_if[0]) { + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, co->bind_if, (unsigned)strlen(co->bind_if) + 1) < 0) { + log_message(LOG_INFO, "Checker can't bind to device %s: %s", co->bind_if, strerror(errno)); + /* Is this correct. Should we return connect_error? */ + thread_add_timer(thread->master, icmp_connect_thread, checker, + checker->delay_loop); + return; + } + } + + if (PTR_CAST_CONST(struct sockaddr, bind_addr)->sa_family != AF_UNSPEC) { + addrlen = sizeof(*bind_addr); + if (bind(fd, PTR_CAST_CONST(struct sockaddr, bind_addr), addrlen) != 0) { + log_message(LOG_INFO, "bind failed. errno: %d, error: %s", errno, strerror(errno)); + /* Is this correct. Should we return connect_error? */ + thread_add_timer(thread->master, icmp_connect_thread, checker, + checker->delay_loop); + return; + } + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size))) log_message(LOG_INFO, "setsockopt SO_RCVBUF for socket %d failed (%d) - %m", fd, errno); From 5149ad54c516c1f00d06d45bef25ee057df6b45d Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Thu, 6 Aug 2026 13:50:28 +0100 Subject: [PATCH 2/2] IPVS: Implement bind_if checker support for UDP sockets Although the configuration of bind_if was supported for UDP sockets, the code did not implement it. Signed-off-by: Quentin Armitage --- keepalived/core/layer4.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/keepalived/core/layer4.c b/keepalived/core/layer4.c index bb6b68342..e00229630 100644 --- a/keepalived/core/layer4.c +++ b/keepalived/core/layer4.c @@ -104,6 +104,7 @@ socket_bind_connect(int fd, conn_opts_t *co) } #endif + /* Bind socket */ if (co->bind_if[0]) { if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, co->bind_if, (unsigned)strlen(co->bind_if) + 1) < 0) { log_message(LOG_INFO, "Checker can't bind to device %s: %s", co->bind_if, strerror(errno)); @@ -111,7 +112,6 @@ socket_bind_connect(int fd, conn_opts_t *co) } } - /* Bind socket */ if (PTR_CAST_CONST(struct sockaddr, bind_addr)->sa_family != AF_UNSPEC) { addrlen = sizeof(*bind_addr); if (bind(fd, PTR_CAST_CONST(struct sockaddr, bind_addr), addrlen) != 0) { @@ -256,6 +256,13 @@ udp_bind_connect(int fd, conn_opts_t *co, uint8_t *payload, uint16_t payload_len #endif /* Bind socket */ + if (co->bind_if[0]) { + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, co->bind_if, (unsigned)strlen(co->bind_if) + 1) < 0) { + log_message(LOG_INFO, "Checker can't bind to device %s: %s", co->bind_if, strerror(errno)); + return connect_error; + } + } + if (PTR_CAST_CONST(struct sockaddr, bind_addr)->sa_family != AF_UNSPEC) { addrlen = sizeof(*bind_addr); if (bind(fd, PTR_CAST_CONST(struct sockaddr, bind_addr), addrlen) != 0) {