Skip to content

Commit

Permalink
vrrp: Add configure option to update /etc/rt_addrprotos
Browse files Browse the repository at this point in the history
If there is no keepalived entry in rt_addrprotos create an entry
which is removed when keepalived terminates. This will allow
ip address show to display the protocol of an address as
"keepalived" rather than 0x12.

Signed-off-by: Quentin Armitage <[email protected]>
  • Loading branch information
pqarmitage committed Oct 28, 2024
1 parent a2328fe commit b51a26a
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 1 deletion.
13 changes: 13 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ AC_ARG_WITH(iproute-usr-dir,
[AS_HELP_STRING([--with-iproute-usr-dir=PATH_TO_CONFIG_FILES], [specify usr directory iproute2 uses for config files])])
AC_ARG_WITH(iproute-etc-dir,
[AS_HELP_STRING([--with-iproute-etc-dir=PATH_TO_CONFIG_FILES], [specify etc directory iproute2 uses for config files])])
AC_ARG_ENABLE(update-rt-addrprotos-file,
[AS_HELP_STRING([--enable-update-rt-addrprotos-file], [update iproute rt_addrprotos file if no entry for keepalived])])
AC_ARG_ENABLE(strict-config-checks,
[AS_HELP_STRING([--enable-strict-config-checks], [build with strict configuration checking])])
AC_ARG_ENABLE(hardening,
Expand Down Expand Up @@ -2793,6 +2795,14 @@ AS_IF([test .${iproute_usr_dir} != . ],
add_config_opt([IPROUTE_USR_DIR=$iproute_usr_dir])
])
AS_IF([test .${enable_update_rt_addrprotos_file} = ."yes"],
[
AC_DEFINE([UPDATE_RT_ADDRPROTOS_FILE], [ 1 ], [update iproute2 rt_addrprotos file])
echo You probably do not want to use this option\; it is better to create an
echo entry in /etc/iproute2/rt_addrprotos, or add keepalived.conf with a relevant
echo entry in /etc/iproute2/rt_addrprotos.d if your version of iproute2 is \>= 6.12.
])
dnl - Check type of rlim_t for printf() - this check needs to be late on
dnl - since _FILE_OFFSET_BITS (set when using netsnmp) alters sizeof(rlim_t)
SAV_CFLAGS="$CFLAGS"
Expand Down Expand Up @@ -3523,6 +3533,9 @@ echo "Strict config checks : ${STRICT_CONFIG}"
echo "Build documentation : ${HAVE_SPHINX_BUILD}"
echo "iproute usr directory : ${iproute_usr_dir}"
echo "iproute etc directory : ${iproute_etc_dir}"
if test .${enable_update_rt_addrprotos_file} = .yes; then
echo "update rt_addrprotos : Yes"
fi
if test ${ENABLE_STACKTRACE} = Yes; then
echo "Stacktrace support : Yes"
fi
Expand Down
4 changes: 4 additions & 0 deletions keepalived/vrrp/vrrp_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ vrrp_terminate_phase2(int exit_status)

clear_rt_names();

#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
remove_created_addrprotos_file();
#endif

if (global_data->vrrp_notify_fifo.fd != -1)
notify_fifo_close(&global_data->notify_fifo, &global_data->vrrp_notify_fifo);

Expand Down
106 changes: 105 additions & 1 deletion lib/rttables.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Copyright (C) 2001-2017 Alexandre Cassen, <[email protected]>
* Copyright (C) 2001-2024 Alexandre Cassen, <[email protected]>
*/

/*
Expand All @@ -36,6 +36,7 @@
6.6 946753a 15/09/23 ensure CONF_USR_DIR honours configure lib path - uses $(LIBDIR)
deb66ac 06/11/23 revert 946753a4
6.7 9626923 15/11/23 change using /usr/lib/iproute2 to /usr/share/iproute2
6.12 b43f84a 14/10/24 add rt_addrprotos.d subdirectories
Debian, Ubuntu, RHEL and openSUSE moved from /etc/iproute2 to /usr/share/iproute2
Mint, Gentoo and Archlinux currently use /etc/iproute2
Expand Down Expand Up @@ -67,6 +68,9 @@
#include <linux/if_addr.h>
#include <dirent.h>
#include <errno.h>
#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
#include <unistd.h>
#endif

#include "list_head.h"
#include "memory.h"
Expand Down Expand Up @@ -179,6 +183,12 @@ static LIST_HEAD_INITIALIZE(rt_scopes);

static char ret_buf[11]; /* uint32_t in decimal */

#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
static const char *created_addrprotos_file;
static const char *created_addrprotos_dir;
bool updated_addrprotos_file;
#endif

static void
free_rt_entry(rt_entry_t *rte)
{
Expand Down Expand Up @@ -584,6 +594,78 @@ get_rttables_addrproto(uint32_t id)
return get_entry(id, &rt_scopes, RT_ADDRPROTOS_FILE, rtscope_default, 255);
}

#ifdef UPDATE_RT_ADDRPROTOS_FILE
static void
write_addrproto_config(const char *name, uint32_t val)
{
char buf[256];
FILE *fp;
char *v, *e;
int ver_maj, ver_min, ver_rel;
char *res;
const char *path, *dir = NULL;
bool file_exists = false;
struct stat statbuf;

fp = popen("ip -V", "re");
res = fgets(buf, sizeof(buf), fp);
pclose(fp);

if (!res)
return;

/* Format is:
* ip utility, iproute2-5.10.0
* or
* ip utility, iproute2-6.7.0, libbpf 1.2.3
*/
if (!(v = strchr(buf, '-')))
return;

v++;
if ((e = strchr(v, ',')))
*e = '\0';
sscanf(v, "%d.%d.%d", &ver_maj, &ver_min, &ver_rel);
if (ver_maj >= 7 || (ver_maj == 6 && ver_min >= 12)) {
dir = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d";
path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d/keepalived_private.conf" ;
} else if (ver_maj == 6 && ver_min >= 3) {
path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE;
} else
return;

stat(IPROUTE_ETC_DIR, &statbuf);
if (dir) {
if (!mkdir(dir, statbuf.st_mode & ~S_IFMT)) { // This may fail if the directory already exists
created_addrprotos_dir = dir;
chmod(dir, statbuf.st_mode & ~S_IFMT);
}
} else {
/* Check if rt_addrprotos file exists */
file_exists = !stat(path, &statbuf);
}

if (!(fp = fopen(path, "a")))
return;

if (!file_exists)
chmod(path, statbuf.st_mode & ~S_IFMT & ~(S_IXUSR | S_IXGRP | S_IXOTH));

if (dir || !file_exists) {
fputs("# File created by keepalived - feel free to remove it\n", fp);
fprintf(fp, "%u\t%s\n", val, name);
} else
fprintf(fp, "%u\t%s\t# entry added by keepalived - feel free to remove it\n", val, name);

fclose(fp);

if (!file_exists)
created_addrprotos_file = path;
else
updated_addrprotos_file = true;
}
#endif

bool
create_rttables_addrproto(const char *name, uint8_t *id)
{
Expand Down Expand Up @@ -618,9 +700,31 @@ create_rttables_addrproto(const char *name, uint8_t *id)

list_add_tail(&rte->e_list, &rt_addrprotos);

#ifdef UPDATE_RT_ADDRPROTOS_FILE
/* Save the entry so iproute can use it */
write_addrproto_config(name, *id);
#endif

return true;
}

#ifdef UPDATE_RT_ADDRPROTOS_FILE
void
remove_created_addrprotos_file(void)
{
if (created_addrprotos_file) {
unlink(created_addrprotos_file);

if (created_addrprotos_dir)
rmdir(created_addrprotos_dir);
} else if (updated_addrprotos_file) {
if (system("sed -i -e '/keepalived/d' " IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE)) {
/* Dummy to aviod unused result warning */
}
}
}
#endif

bool
find_rttables_addrproto(const char *name, uint8_t *id)
{
Expand Down
3 changes: 3 additions & 0 deletions lib/rttables.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,8 @@ extern const char *get_rttables_scope(uint32_t);
extern const char *get_rttables_group(uint32_t);
#endif
extern const char *get_rttables_rtntype(uint8_t);
#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
extern void remove_created_addrprotos_file(void);
#endif

#endif

0 comments on commit b51a26a

Please sign in to comment.