Skip to content

Commit b51a26a

Browse files
committed
vrrp: Add configure option to update /etc/rt_addrprotos
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]>
1 parent a2328fe commit b51a26a

File tree

4 files changed

+125
-1
lines changed

4 files changed

+125
-1
lines changed

configure.ac

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ AC_ARG_WITH(iproute-usr-dir,
238238
[AS_HELP_STRING([--with-iproute-usr-dir=PATH_TO_CONFIG_FILES], [specify usr directory iproute2 uses for config files])])
239239
AC_ARG_WITH(iproute-etc-dir,
240240
[AS_HELP_STRING([--with-iproute-etc-dir=PATH_TO_CONFIG_FILES], [specify etc directory iproute2 uses for config files])])
241+
AC_ARG_ENABLE(update-rt-addrprotos-file,
242+
[AS_HELP_STRING([--enable-update-rt-addrprotos-file], [update iproute rt_addrprotos file if no entry for keepalived])])
241243
AC_ARG_ENABLE(strict-config-checks,
242244
[AS_HELP_STRING([--enable-strict-config-checks], [build with strict configuration checking])])
243245
AC_ARG_ENABLE(hardening,
@@ -2793,6 +2795,14 @@ AS_IF([test .${iproute_usr_dir} != . ],
27932795
add_config_opt([IPROUTE_USR_DIR=$iproute_usr_dir])
27942796
])
27952797
2798+
AS_IF([test .${enable_update_rt_addrprotos_file} = ."yes"],
2799+
[
2800+
AC_DEFINE([UPDATE_RT_ADDRPROTOS_FILE], [ 1 ], [update iproute2 rt_addrprotos file])
2801+
echo You probably do not want to use this option\; it is better to create an
2802+
echo entry in /etc/iproute2/rt_addrprotos, or add keepalived.conf with a relevant
2803+
echo entry in /etc/iproute2/rt_addrprotos.d if your version of iproute2 is \>= 6.12.
2804+
])
2805+
27962806
dnl - Check type of rlim_t for printf() - this check needs to be late on
27972807
dnl - since _FILE_OFFSET_BITS (set when using netsnmp) alters sizeof(rlim_t)
27982808
SAV_CFLAGS="$CFLAGS"
@@ -3523,6 +3533,9 @@ echo "Strict config checks : ${STRICT_CONFIG}"
35233533
echo "Build documentation : ${HAVE_SPHINX_BUILD}"
35243534
echo "iproute usr directory : ${iproute_usr_dir}"
35253535
echo "iproute etc directory : ${iproute_etc_dir}"
3536+
if test .${enable_update_rt_addrprotos_file} = .yes; then
3537+
echo "update rt_addrprotos : Yes"
3538+
fi
35263539
if test ${ENABLE_STACKTRACE} = Yes; then
35273540
echo "Stacktrace support : Yes"
35283541
fi

keepalived/vrrp/vrrp_daemon.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ vrrp_terminate_phase2(int exit_status)
318318

319319
clear_rt_names();
320320

321+
#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
322+
remove_created_addrprotos_file();
323+
#endif
324+
321325
if (global_data->vrrp_notify_fifo.fd != -1)
322326
notify_fifo_close(&global_data->notify_fifo, &global_data->vrrp_notify_fifo);
323327

lib/rttables.c

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* as published by the Free Software Foundation; either version
1919
* 2 of the License, or (at your option) any later version.
2020
*
21-
* Copyright (C) 2001-2017 Alexandre Cassen, <[email protected]>
21+
* Copyright (C) 2001-2024 Alexandre Cassen, <[email protected]>
2222
*/
2323

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

7175
#include "list_head.h"
7276
#include "memory.h"
@@ -179,6 +183,12 @@ static LIST_HEAD_INITIALIZE(rt_scopes);
179183

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

186+
#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
187+
static const char *created_addrprotos_file;
188+
static const char *created_addrprotos_dir;
189+
bool updated_addrprotos_file;
190+
#endif
191+
182192
static void
183193
free_rt_entry(rt_entry_t *rte)
184194
{
@@ -584,6 +594,78 @@ get_rttables_addrproto(uint32_t id)
584594
return get_entry(id, &rt_scopes, RT_ADDRPROTOS_FILE, rtscope_default, 255);
585595
}
586596

597+
#ifdef UPDATE_RT_ADDRPROTOS_FILE
598+
static void
599+
write_addrproto_config(const char *name, uint32_t val)
600+
{
601+
char buf[256];
602+
FILE *fp;
603+
char *v, *e;
604+
int ver_maj, ver_min, ver_rel;
605+
char *res;
606+
const char *path, *dir = NULL;
607+
bool file_exists = false;
608+
struct stat statbuf;
609+
610+
fp = popen("ip -V", "re");
611+
res = fgets(buf, sizeof(buf), fp);
612+
pclose(fp);
613+
614+
if (!res)
615+
return;
616+
617+
/* Format is:
618+
* ip utility, iproute2-5.10.0
619+
* or
620+
* ip utility, iproute2-6.7.0, libbpf 1.2.3
621+
*/
622+
if (!(v = strchr(buf, '-')))
623+
return;
624+
625+
v++;
626+
if ((e = strchr(v, ',')))
627+
*e = '\0';
628+
sscanf(v, "%d.%d.%d", &ver_maj, &ver_min, &ver_rel);
629+
if (ver_maj >= 7 || (ver_maj == 6 && ver_min >= 12)) {
630+
dir = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d";
631+
path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d/keepalived_private.conf" ;
632+
} else if (ver_maj == 6 && ver_min >= 3) {
633+
path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE;
634+
} else
635+
return;
636+
637+
stat(IPROUTE_ETC_DIR, &statbuf);
638+
if (dir) {
639+
if (!mkdir(dir, statbuf.st_mode & ~S_IFMT)) { // This may fail if the directory already exists
640+
created_addrprotos_dir = dir;
641+
chmod(dir, statbuf.st_mode & ~S_IFMT);
642+
}
643+
} else {
644+
/* Check if rt_addrprotos file exists */
645+
file_exists = !stat(path, &statbuf);
646+
}
647+
648+
if (!(fp = fopen(path, "a")))
649+
return;
650+
651+
if (!file_exists)
652+
chmod(path, statbuf.st_mode & ~S_IFMT & ~(S_IXUSR | S_IXGRP | S_IXOTH));
653+
654+
if (dir || !file_exists) {
655+
fputs("# File created by keepalived - feel free to remove it\n", fp);
656+
fprintf(fp, "%u\t%s\n", val, name);
657+
} else
658+
fprintf(fp, "%u\t%s\t# entry added by keepalived - feel free to remove it\n", val, name);
659+
660+
fclose(fp);
661+
662+
if (!file_exists)
663+
created_addrprotos_file = path;
664+
else
665+
updated_addrprotos_file = true;
666+
}
667+
#endif
668+
587669
bool
588670
create_rttables_addrproto(const char *name, uint8_t *id)
589671
{
@@ -618,9 +700,31 @@ create_rttables_addrproto(const char *name, uint8_t *id)
618700

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

703+
#ifdef UPDATE_RT_ADDRPROTOS_FILE
704+
/* Save the entry so iproute can use it */
705+
write_addrproto_config(name, *id);
706+
#endif
707+
621708
return true;
622709
}
623710

711+
#ifdef UPDATE_RT_ADDRPROTOS_FILE
712+
void
713+
remove_created_addrprotos_file(void)
714+
{
715+
if (created_addrprotos_file) {
716+
unlink(created_addrprotos_file);
717+
718+
if (created_addrprotos_dir)
719+
rmdir(created_addrprotos_dir);
720+
} else if (updated_addrprotos_file) {
721+
if (system("sed -i -e '/keepalived/d' " IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE)) {
722+
/* Dummy to aviod unused result warning */
723+
}
724+
}
725+
}
726+
#endif
727+
624728
bool
625729
find_rttables_addrproto(const char *name, uint8_t *id)
626730
{

lib/rttables.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,8 @@ extern const char *get_rttables_scope(uint32_t);
4747
extern const char *get_rttables_group(uint32_t);
4848
#endif
4949
extern const char *get_rttables_rtntype(uint8_t);
50+
#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE
51+
extern void remove_created_addrprotos_file(void);
52+
#endif
5053

5154
#endif

0 commit comments

Comments
 (0)