Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update reading of iproute2 config files to handle new locations #2487

Merged
merged 8 commits into from
Oct 28, 2024
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
Loading