Skip to content

Commit

Permalink
Merge pull request #2436 from pqarmitage/updates
Browse files Browse the repository at this point in the history
Fix ip_vs module loading on RHEL based distros
  • Loading branch information
pqarmitage authored Jul 1, 2024
2 parents b456255 + 1e3d47e commit cf0f3e5
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
7 changes: 7 additions & 0 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ For building the documentation, the following packages need to be installed:
For latex or pdf files, the following are also needed:
texlive-core texlive-bin texlive-latexextra

openSUSE
========
1. zypper install -t pattern devel_C_C++
2. Install packages with same names as Red Hat variants (except libopenssl-devel instead of openssl-devel and libkmod-devel instead of kmod-devel)

Kernel configuration requirements
---------------------------------
The following list is probably incomplete, and will be updated as other
Expand All @@ -150,6 +155,8 @@ NETFILTER_XTABLES - if strict_mode or no_accept.
NF_TABLES and associated components - to use nftables for strict_mode or no_accept
IP_ADVANCED_ROUTER and various associated options if static/dynamic routes specified
FIB_RULES if static or dynamic rules are specified
PROC_EVENTS for track_process


Installing from a git repo
==========================
Expand Down
6 changes: 2 additions & 4 deletions keepalived/check/ipvswrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ ipvs_start(void)
{
log_message(LOG_DEBUG, "%snitializing ipvs", reload ? "Rei" : "I");
/* Initialize IPVS module */
if (ipvs_init()) {
if (!keepalived_modprobe("ip_vs") || ipvs_init()) {
if (ipvs_init(false)) {
if (!keepalived_modprobe("ip_vs") || ipvs_init(true)) {
log_message(LOG_INFO, "IPVS: Can't initialize ipvs: %s",
ipvs_strerror(errno));
no_ipvs = true;
Expand Down Expand Up @@ -879,9 +879,7 @@ ipvs_update_rs_stats(virtual_server_t *vs, uint16_t af, uint32_t fwmark, union n
else {
/* Search for a match in the list of real servers */
rs_match = NULL;
int no = 0;
list_for_each_entry(rs, &vs->rs, e_list) {
no++;
if (vsd_equal(rs, &dests->user.entrytable[i])) {
rs_match = rs;
break;
Expand Down
41 changes: 33 additions & 8 deletions keepalived/check/libipvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,28 +385,53 @@ static int ipvs_getinfo_parse_cb(struct nl_msg *msg, __attribute__((unused)) voi
}
#endif

static int ipvs_getinfo(void)
static int ipvs_getinfo(bool retry)
{
socklen_t len;
struct ip_vs_getinfo ipvs_info;
unsigned retries = retry ? 1 : 0;

/* It appears that if we need to install the ip_vs module
* (via keepalived_modprobe), then the first ipvs_nl_send_message()
* call afterwards fails, but it succeeds thereafter.
*
* On some distros the call genl_ctrl_resolve(sock, IPVS_GENL_NAME) loads
* the ip_vs module, so we don't need to call keepalived_modprobe(), and
* we don't need to retry the ipvs_nl_send_message(). On the other hand,
* if genl_ctrl_resolve() does not load the ip_vs module, then we need to
* make the second call of ipvs_nl_send_message().
*
* It appears that if there is an entry:
* alias net-pf-16-proto-16-family-IPVS ip_vs
* in /lib/modules/{KERNEL_VER}/modules.alias then genl_ctrl_resolve() causes
* the ip_vs module to be loaded, and if there is no such entry, then it does
* not load the ip_vs module. Whether this is cause and effect, or whether they
* are both caused by some other aspect of the configuration I do not know.
*/

ipvs_func = ipvs_getinfo;

#ifdef LIBIPVS_USE_NL
if (try_nl) {
struct nl_msg *msg;
if (!(msg = ipvs_nl_message(IPVS_CMD_GET_INFO, 0)))
return -1;

return ipvs_nl_send_message(msg, ipvs_getinfo_parse_cb, NULL);
do {
if (!(msg = ipvs_nl_message(IPVS_CMD_GET_INFO, 0)))
return -1;

if (!ipvs_nl_send_message(msg, ipvs_getinfo_parse_cb, NULL))
return 0;
} while (retries--);

return -1;
}
#endif

len = sizeof(ipvs_info);
return getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, &ipvs_info, &len);
}

int ipvs_init(void)
int ipvs_init(bool retry)
{
ipvs_func = ipvs_init;

Expand All @@ -417,8 +442,8 @@ int ipvs_init(void)
log_message(LOG_INFO, "Note: IPVS with IPv6 will not be supported");
#endif

if (try_nl && ipvs_nl_send_message(NULL, NULL, NULL) == 0)
return ipvs_getinfo();
if (try_nl)
return ipvs_getinfo(retry);

try_nl = false;
#else
Expand All @@ -429,7 +454,7 @@ int ipvs_init(void)
if (sockfd == -1)
return -1;

if (ipvs_getinfo()) {
if (ipvs_getinfo(false)) {
close(sockfd);
sockfd = -1;
return -1;
Expand Down
2 changes: 1 addition & 1 deletion keepalived/include/libipvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct ip_vs_dest_entry_app ipvs_dest_entry_t;


/* init socket and get ipvs info */
extern int ipvs_init(void);
extern int ipvs_init(bool);

/* Set timeout parameters */
extern int ipvs_set_timeout(const ipvs_timeout_t *to);
Expand Down

0 comments on commit cf0f3e5

Please sign in to comment.