Skip to content

Commit

Permalink
Merge pull request #2487 from pqarmitage/updates
Browse files Browse the repository at this point in the history
Update reading of iproute2 config files to handle new locations
  • Loading branch information
pqarmitage authored Oct 28, 2024
2 parents e0b820c + 1ae1256 commit f5beb00
Show file tree
Hide file tree
Showing 9 changed files with 508 additions and 20 deletions.
82 changes: 82 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ AC_ARG_WITH(run-dir,
AC_ARG_WITH(tmp-dir,
[AS_HELP_STRING([--with-tmp-dir=PATH_TO_TMP], [specify directory where run-time temporary files are to be located])],
[TMP_DIR_SPECIFIED=Y], [TMP_DIR_SPECIFIED=N])
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 @@ -1732,6 +1738,15 @@ for flag in IFA_FLAGS; do
fi
done
dnl - Introduced in Linux 5.18
AC_CHECK_DECLS([IFA_PROTO], [], [], [[#include <linux/if_addr.h>]])
for flag in IFA_PROTO; do
AS_VAR_COPY([decl_var], [ac_cv_have_decl_$flag])
if test ${decl_var} = yes; then
add_system_opt[${flag}]
fi
done
dnl -- RedHat backported ENCAP_IP and ENCAP_IP6 without MPLS and ILA
AS_IF([test $ac_cv_have_decl_RTA_ENCAP = yes],
[
Expand Down Expand Up @@ -2726,6 +2741,68 @@ fi
AC_DEFINE_UNQUOTED([KA_TMP_DIR], [ "${KA_TMP_DIR}" ], [Location for temporary files])
AC_SUBST([KA_TMP_DIR], [${KA_TMP_DIR}])
dnl -- iproute2 can have directories other than /usr/share/iproute2 and /etc/iproute2 configured
dnl -- for config files if options for the paths are specified. Otherwise try to find the paths
dnl -- in the ip-route man page, and if that fails, try finding the strings in the executable.
dnl -- The latter two options are not very nice, but I can't think of a better way.
dnl -- Finally, there are runtime configuration options to override these defaults.
AS_IF([test .${with_iproute_usr_dir} != . ], [iproute_usr_dir="$with_iproute_usr_dir"])
AS_IF([test .${with_iproute_etc_dir} != . ], [iproute_etc_dir="$with_iproute_etc_dir"])
AS_IF([test .${with_iproute_usr_dir} = . && test .${with_iproute_etc_dir} = . ],
[
dnl -- try the man page
man ip-route | grep -q /rt_tables
AS_IF([test $? = 0],
[
IPROUTE_DIRS=$(man ip route | tr " \t" "\n\n" | $SED -e "s/[[\.,;:?\!]]*//g" | grep "/rt_tables$" | $SED -e "s:/rt_tables$::")
set $(<<<$IPROUTE_DIRS sort -u)
second_route=$2
set $IPROUTE_DIRS
AS_IF([test .$second_route = .],
[
iproute_etc_dir=$1
iproute_usr_dir=
],
[
iproute_usr_dir=$1
iproute_etc_dir=$2
])
],
[
# try finding the paths in the executable
set $(strings $(type -p ip) | grep /rt_tables | $SED -e "s:/rt_tables::")
for i in $1 $2; do
grep -q /etc <<<$i
AS_IF([test $? -eq 0], [iproute_etc_dir=$i])
grep -q /usr <<<$i
AS_IF([test $? -eq 0], [iproute_usr_dir=$i])
done
])
AS_IF([test .${iproute_etc_dir}${iproute_usr_dir} = . ],
[
iproute_etc_dir=/etc/iproute2
iproute_usr_dir=/usr/share/iproute2
])
])
AS_IF([test .${iproute_etc_dir} != . ],
[
AC_DEFINE_UNQUOTED([IPROUTE_ETC_DIR], ["$iproute_etc_dir"], [etc path to iproute2 config files])
add_config_opt([IPROUTE_ETC_DIR=$iproute_etc_dir])
])
AS_IF([test .${iproute_usr_dir} != . ],
[
AC_DEFINE_UNQUOTED([IPROUTE_USR_DIR], ["$iproute_usr_dir"], [usr path to iproute2 config files])
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 @@ -3454,6 +3531,11 @@ echo "init type : ${INIT_TYPE}"
echo "systemd notify : ${USE_SYSTEMD_NOTIFY}"
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
17 changes: 17 additions & 0 deletions keepalived/core/global_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,15 @@ init_global_data(data_t * data, data_t *prev_global_data, bool copy_unchangeable
data->snmp_rs_stats_update_interval = data->snmp_vs_stats_update_interval;
#endif
#endif

#ifdef _WITH_VRRP_
#ifdef IPROUTE_USR_DIR
if (!data->iproute_usr_dir && IPROUTE_USR_DIR[0])
data->iproute_usr_dir = STRDUP(IPROUTE_USR_DIR);
#endif
if (!data->iproute_etc_dir && IPROUTE_ETC_DIR[0])
data->iproute_etc_dir = STRDUP(IPROUTE_ETC_DIR);
#endif
}

void
Expand Down Expand Up @@ -503,6 +512,10 @@ free_global_data(data_t **datap)
FREE_CONST_PTR(data->reload_time_file);
#endif
FREE_CONST_PTR(data->config_directory);
#ifdef _WITH_VRRP_
FREE_CONST_PTR(data->iproute_usr_dir);
FREE_CONST_PTR(data->iproute_etc_dir);
#endif
FREE(data);

*datap = NULL;
Expand Down Expand Up @@ -924,4 +937,8 @@ dump_global_data(FILE *fp, data_t * data)
#ifdef _WITH_JSON_
conf_write(fp, " json_version %u", global_data->json_version);
#endif
#ifdef _WITH_VRRP_
conf_write(fp, " iproute usr directory %s", global_data->iproute_usr_dir ? global_data->iproute_usr_dir : "(none)");
conf_write(fp, " iproute etc directory %s", global_data->iproute_etc_dir ? global_data->iproute_etc_dir : "(none)");
#endif
}
55 changes: 45 additions & 10 deletions keepalived/core/global_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ vrrp_higher_prio_send_advert_handler(const vector_t *strvec)
else
global_data->vrrp_higher_prio_send_advert = true;
}
#endif

#if defined _WITH_IPTABLES_ || defined _WITH_NFTABLES_
static bool
Expand All @@ -1090,6 +1091,7 @@ check_valid_iptables_ipset_nftables_name(const vector_t *strvec, unsigned entry,
}
#endif

#ifdef _WITH_VRRP_
#ifdef _WITH_IPTABLES_
static bool
check_valid_iptables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name)
Expand Down Expand Up @@ -1275,15 +1277,16 @@ vrrp_iptables_handler(__attribute__((unused)) const vector_t *strvec)
global_data->vrrp_nf_chain_priority = -1;
}
#endif
#endif

#ifdef _WITH_NFTABLES_
#ifdef _WITH_VRRP_
static bool
check_valid_nftables_chain_name(const vector_t *strvec, unsigned entry, const char *log_name)
{
return check_valid_iptables_ipset_nftables_name(strvec, entry, NFT_TABLE_MAXNAMELEN, "nftables", log_name);
}

#ifdef _WITH_VRRP_
static void
vrrp_nftables_handler(__attribute__((unused)) const vector_t *strvec)
{
Expand Down Expand Up @@ -1376,6 +1379,8 @@ nftables_counters_handler(__attribute__((unused)) const vector_t *strvec)
global_data->nf_counters = true;
}
#endif

#ifdef _WITH_VRRP_
static void
vrrp_version_handler(const vector_t *strvec)
{
Expand Down Expand Up @@ -2427,7 +2432,7 @@ json_version_handler(const vector_t *strvec)
unsigned version = true;

if (vector_size(strvec) < 2) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires version", strvec_slot(strvec, 1));
report_config_error(CONFIG_GENERAL_ERROR, "%s requires version", strvec_slot(strvec, 0));
return;
}

Expand All @@ -2440,6 +2445,30 @@ json_version_handler(const vector_t *strvec)
}
#endif

#ifdef _WITH_VRRP_
static void
iproute_usr_handler(const vector_t *strvec)
{
if (vector_size(strvec) != 2) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires path", strvec_slot(strvec, 0));
return;
}

global_data->iproute_usr_dir = STRDUP(strvec_slot(strvec, 1));
}

static void
iproute_etc_handler(const vector_t *strvec)
{
if (vector_size(strvec) != 2) {
report_config_error(CONFIG_GENERAL_ERROR, "%s requires path", strvec_slot(strvec, 0));
return;
}

global_data->iproute_etc_dir = STRDUP(strvec_slot(strvec, 1));
}
#endif

void
init_global_keywords(bool global_active)
{
Expand Down Expand Up @@ -2533,17 +2562,9 @@ init_global_keywords(bool global_active)
#endif
#endif
#ifdef _WITH_NFTABLES_
#ifdef _WITH_VRRP_
install_keyword("nftables", &vrrp_nftables_handler);
install_keyword("nftables_priority", &vrrp_nftables_priority_handler);
install_keyword("nftables_ifindex", &vrrp_nftables_ifindex_handler);
#endif
#ifdef _WITH_LVS_
install_keyword("nftables_ipvs", &ipvs_nftables_handler);
install_keyword("nftables_ipvs_priority", &ipvs_nftables_priority_handler);
install_keyword("nftables_ipvs_start_fwmark", &ipvs_nftables_start_fwmark_handler);
#endif
install_keyword("nftables_counters", &nftables_counters_handler);
#endif
install_keyword("vrrp_check_unicast_src", &vrrp_check_unicast_src_handler);
install_keyword("vrrp_skip_check_adv_addr", &vrrp_check_adv_addr_handler);
Expand All @@ -2554,6 +2575,16 @@ init_global_keywords(bool global_active)
install_keyword("vrrp_cpu_affinity", &vrrp_cpu_affinity_handler);
install_keyword("vrrp_rlimit_rttime", &vrrp_rt_rlimit_handler);
install_keyword("vrrp_rlimit_rtime", &vrrp_rt_rlimit_handler); /* Deprecated 02/02/2020 */
#endif
#ifdef _WITH_NFTABLES_
#ifdef _WITH_LVS_
install_keyword("nftables_ipvs", &ipvs_nftables_handler);
install_keyword("nftables_ipvs_priority", &ipvs_nftables_priority_handler);
install_keyword("nftables_ipvs_start_fwmark", &ipvs_nftables_start_fwmark_handler);
#endif
#if defined _WITH_VRRP_ || defined _WITH_LVS_
install_keyword("nftables_counters", &nftables_counters_handler);
#endif
#endif
install_keyword("notify_fifo", &global_notify_fifo);
install_keyword_quoted("notify_fifo_script", &global_notify_fifo_script);
Expand Down Expand Up @@ -2653,4 +2684,8 @@ init_global_keywords(bool global_active)
#ifdef _WITH_JSON_
install_keyword("json_version", &json_version_handler);
#endif
#ifdef _WITH_VRRP_
install_keyword("iproute_usr_dir", &iproute_usr_handler);
install_keyword("iproute_etc_dir", &iproute_etc_handler);
#endif
}
4 changes: 4 additions & 0 deletions keepalived/include/global_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ typedef struct _data {
#ifdef _WITH_JSON_
unsigned json_version;
#endif
#ifdef _WITH_VRRP_
const char *iproute_usr_dir;
const char *iproute_etc_dir;
#endif
} data_t;

/* Global vars exported */
Expand Down
1 change: 1 addition & 0 deletions keepalived/include/vrrp_ipaddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,6 @@ extern void get_diff_address(vrrp_t *, vrrp_t *, list_head_t *);
extern void clear_address_list(list_head_t *, bool);
extern void clear_diff_static_addresses(void);
extern void reinstate_static_address(ip_address_t *);
extern void set_addrproto(void);

#endif
7 changes: 7 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 Expand Up @@ -1126,6 +1130,9 @@ start_vrrp_child(void)
systemd_unset_notify();
#endif

/* Set the protocol for ip addresses we add */
set_addrproto();

#ifdef _VRRP_FD_DEBUG_
if (do_vrrp_fd_debug)
set_extra_threads_debug(dump_vrrp_fd);
Expand Down
17 changes: 17 additions & 0 deletions keepalived/vrrp/vrrp_ipaddress.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@

#define INFINITY_LIFE_TIME 0xFFFFFFFF

#if HAVE_DECL_IFA_PROTO
static uint8_t address_protocol;
#endif

const char *
ipaddresstos(char *buf, const ip_address_t *ip_addr)
{
Expand Down Expand Up @@ -212,6 +216,10 @@ netlink_ipaddress(ip_address_t *ip_addr, int cmd)

if (ip_addr->have_peer)
addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &ip_addr->peer, req.ifa.ifa_family == AF_INET6 ? 16 : 4);

#if HAVE_DECL_IFA_PROTO // introduced in Linux v5.18
addattr8(&req.n, sizeof(req), IFA_PROTO, address_protocol);
#endif
}

/* If the state of the interface or its parent is down, it might be because the interface
Expand Down Expand Up @@ -838,3 +846,12 @@ void reinstate_static_address(ip_address_t *ip_addr)
format_ipaddress(ip_addr, buf, sizeof(buf));
log_message(LOG_INFO, "Restoring deleted static address %s", buf);
}

void
set_addrproto(void)
{
#if HAVE_DECL_IFA_PROTO
if (!find_rttables_addrproto("keepalived", &address_protocol))
create_rttables_addrproto("keepalived", &address_protocol);
#endif
}
Loading

0 comments on commit f5beb00

Please sign in to comment.