From 3ac75804b6c56e79cc3cf808960c85ca237c5e66 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Tue, 12 Sep 2023 10:29:11 +0100 Subject: [PATCH 1/3] vrrp: Remove extraneous log message for netlink interface message Signed-off-by: Quentin Armitage --- keepalived/core/keepalived_netlink.c | 1 - 1 file changed, 1 deletion(-) diff --git a/keepalived/core/keepalived_netlink.c b/keepalived/core/keepalived_netlink.c index 2a855fa51c..9a42a2724f 100644 --- a/keepalived/core/keepalived_netlink.c +++ b/keepalived/core/keepalived_netlink.c @@ -2004,7 +2004,6 @@ netlink_if_link_filter(__attribute__((unused)) struct sockaddr_nl *snl, struct n if (tb[IFLA_IFNAME] == NULL) return -1; name = (char *)RTA_DATA(tb[IFLA_IFNAME]); -log_message(LOG_INFO, "Got netlink new message for %s", name); /* Skip it if already exists */ ifp = if_get_by_ifname(name, IF_CREATE_NETLINK); From 5dd228e3568aa37383612f8273927e7591248dd1 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Tue, 12 Sep 2023 10:29:52 +0100 Subject: [PATCH 2/3] vrrp: Allow DBus to work with VRRP instances without configured interface keepalived uses "none" for the interface in the DBus path if a VRRP instance has no configured interface. However, it was not checking explicitly for "none" when a query was received. This commit now adds a specific check. Signed-off-by: Quentin Armitage --- keepalived/vrrp/vrrp_dbus.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c index e14d6e6d7a..9e4aad53bf 100644 --- a/keepalived/vrrp/vrrp_dbus.c +++ b/keepalived/vrrp/vrrp_dbus.c @@ -207,13 +207,18 @@ static vrrp_t * __attribute__ ((pure)) get_vrrp_instance(const char *ifname, int vrid, int family) { vrrp_t *vrrp; + bool no_if = !strcmp(ifname, no_interface); list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) { - if (vrrp->ifp && - vrrp->vrid == vrid && - vrrp->family == family && - !valid_path_cmp(VRRP_CONFIGURED_IFP(vrrp)->ifname, ifname)) - return vrrp; + if (vrrp->vrid == vrid && + vrrp->family == family) { + if (no_if) { + if (!vrrp->ifp) + return vrrp; + } else if (vrrp->ifp && + !valid_path_cmp(VRRP_CONFIGURED_IFP(vrrp)->ifname, ifname)) + return vrrp; + } } return NULL; From b91a718759a1c0260b1d1b73fb55f3dc2ac115b9 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Tue, 12 Sep 2023 10:34:00 +0100 Subject: [PATCH 3/3] vrrp: Allow specification of string used by DBus for no interface keepalived used the string "none" in the DBus path if a VRRP instance did not have an interface configured. This could cause a problem if a system had an interface named "none". This commit adds global configuration option dbus_no_interface_name to allow the string to be specified. Signed-off-by: Quentin Armitage --- doc/man/man5/keepalived.conf.5.in | 5 +++++ keepalived/core/global_data.c | 5 +++++ keepalived/core/global_parser.c | 13 +++++++++++++ keepalived/include/global_data.h | 1 + keepalived/include/vrrp_dbus.h | 1 + keepalived/vrrp/vrrp_dbus.c | 13 ++++++++----- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/doc/man/man5/keepalived.conf.5.in b/doc/man/man5/keepalived.conf.5.in index ebae31b2ce..6b05b2dc1c 100644 --- a/doc/man/man5/keepalived.conf.5.in +++ b/doc/man/man5/keepalived.conf.5.in @@ -683,6 +683,11 @@ possibly following any cleanup actions needed. # (default: org.keepalived.Vrrp1) \fBdbus_service_name \fRSERVICE_NAME + # String to use for DBus path when VRRP instance has no interface configured + # Useful if your system has an interface named "none"! + # (default: "none") + \fBdbus_no_interface_name \fRNAME + # Specify the default username/groupname to run scripts under. # If this option is not specified, the user defaults to keepalived_script # if that user exists, otherwise the uid/gid under which keepalived is running. diff --git a/keepalived/core/global_data.c b/keepalived/core/global_data.c index 7288651267..3343985327 100644 --- a/keepalived/core/global_data.c +++ b/keepalived/core/global_data.c @@ -46,6 +46,9 @@ #ifdef _WITH_JSON_ #include "global_json.h" #endif +#ifdef _WITH_DBUS_ +#include "vrrp_dbus.h" +#endif /* global vars */ data_t *global_data = NULL; @@ -417,6 +420,7 @@ free_global_data(data_t * data) #endif #ifdef _WITH_DBUS_ FREE_CONST_PTR(data->dbus_service_name); + FREE_CONST_PTR(data->dbus_no_interface_name); #endif #ifndef _ONE_PROCESS_DEBUG_ FREE_CONST_PTR(data->reload_check_config); @@ -779,6 +783,7 @@ dump_global_data(FILE *fp, data_t * data) #ifdef _WITH_DBUS_ conf_write(fp, " DBus %s", data->enable_dbus ? "enabled" : "disabled"); conf_write(fp, " DBus service name = %s", data->dbus_service_name ? data->dbus_service_name : ""); + conf_write(fp, " DBus no interface name = %s", data->dbus_no_interface_name ? data->dbus_no_interface_name : dbus_no_interface_name); #endif conf_write(fp, " Script security %s", script_security ? "enabled" : "disabled"); if (!get_default_script_user(&uid, &gid)) diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c index 422d027844..a572771f39 100644 --- a/keepalived/core/global_parser.c +++ b/keepalived/core/global_parser.c @@ -1661,6 +1661,18 @@ dbus_service_name_handler(const vector_t *strvec) FREE_CONST_PTR(global_data->dbus_service_name); global_data->dbus_service_name = set_value(strvec); } + +static void +dbus_no_interface_name_handler(const vector_t *strvec) +{ + if (vector_size(strvec) < 2) { + report_config_error(CONFIG_GENERAL_ERROR, "dbus_no_interface_name missing - ignoring"); + return; + } + + FREE_CONST_PTR(global_data->dbus_no_interface_name); + global_data->dbus_no_interface_name = set_value(strvec); +} #endif static void @@ -2474,6 +2486,7 @@ init_global_keywords(bool global_active) #ifdef _WITH_DBUS_ install_keyword("enable_dbus", &enable_dbus_handler); install_keyword("dbus_service_name", &dbus_service_name_handler); + install_keyword("dbus_no_interface_name", &dbus_no_interface_name_handler); #endif install_keyword("script_user", &script_user_handler); install_keyword("enable_script_security", &script_security_handler); diff --git a/keepalived/include/global_data.h b/keepalived/include/global_data.h index 1e81586cb1..a0bbbb08a1 100644 --- a/keepalived/include/global_data.h +++ b/keepalived/include/global_data.h @@ -255,6 +255,7 @@ typedef struct _data { #ifdef _WITH_DBUS_ bool enable_dbus; const char *dbus_service_name; + const char *dbus_no_interface_name; #endif #ifdef _WITH_VRRP_ unsigned vrrp_netlink_cmd_rcv_bufs; diff --git a/keepalived/include/vrrp_dbus.h b/keepalived/include/vrrp_dbus.h index a408123b26..8f715420d2 100644 --- a/keepalived/include/vrrp_dbus.h +++ b/keepalived/include/vrrp_dbus.h @@ -30,6 +30,7 @@ #include "vrrp.h" #include "list_head.h" +extern const char *dbus_no_interface_name; void dbus_send_state_signal(vrrp_t *); void dbus_remove_object(const vrrp_t *); diff --git a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c index 9e4aad53bf..8f30c803e0 100644 --- a/keepalived/vrrp/vrrp_dbus.c +++ b/keepalived/vrrp/vrrp_dbus.c @@ -127,7 +127,7 @@ static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t startup_cond = PTHREAD_COND_INITIALIZER; /* Global file variables */ -static const char * const no_interface = "none"; +const char *dbus_no_interface_name = "none"; static GDBusNodeInfo *vrrp_introspection_data = NULL; static GDBusNodeInfo *vrrp_instance_introspection_data = NULL; static GDBusConnection *global_connection; @@ -207,7 +207,7 @@ static vrrp_t * __attribute__ ((pure)) get_vrrp_instance(const char *ifname, int vrid, int family) { vrrp_t *vrrp; - bool no_if = !strcmp(ifname, no_interface); + bool no_if = !strcmp(ifname, dbus_no_interface_name); list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) { if (vrrp->vrid == vrid && @@ -525,7 +525,7 @@ dbus_create_object_params(const char *instance_name, const char *interface_name, static void dbus_create_object(vrrp_t *vrrp) { - dbus_create_object_params(vrrp->iname, vrrp->ifp ? IF_NAME(VRRP_CONFIGURED_IFP(vrrp)) : no_interface, vrrp->vrid, vrrp->family, false); + dbus_create_object_params(vrrp->iname, vrrp->ifp ? IF_NAME(VRRP_CONFIGURED_IFP(vrrp)) : dbus_no_interface_name, vrrp->vrid, vrrp->family, false); } static bool @@ -697,6 +697,9 @@ dbus_main(void *param) return free_wait(); } + if (global_data->dbus_no_interface_name) + dbus_no_interface_name = global_data->dbus_no_interface_name; + service_name = global_data->dbus_service_name ? global_data->dbus_service_name : DBUS_SERVICE_NAME; owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, service_name, @@ -741,7 +744,7 @@ dbus_send_state_signal(vrrp_t *vrrp) if (global_connection == NULL) return; - object_path = dbus_object_create_path_instance(vrrp->ifp ? IF_NAME(VRRP_CONFIGURED_IFP(vrrp)) : no_interface, vrrp->vrid, vrrp->family); + object_path = dbus_object_create_path_instance(vrrp->ifp ? IF_NAME(VRRP_CONFIGURED_IFP(vrrp)) : dbus_no_interface_name, vrrp->vrid, vrrp->family); args = g_variant_new("(u)", vrrp->state); dbus_emit_signal(global_connection, object_path, DBUS_VRRP_INSTANCE_INTERFACE, "VrrpStatusChange", args); @@ -872,7 +875,7 @@ dbus_reload(const list_head_t *o, const list_head_t *n) const char *n_name; bool match_found; - n_name = vrrp_n->ifp ? VRRP_CONFIGURED_IFP(vrrp_n)->ifname : no_interface; + n_name = vrrp_n->ifp ? VRRP_CONFIGURED_IFP(vrrp_n)->ifname : dbus_no_interface_name; /* Try and find an instance with same vrid/family/interface that existed before and now */ match_found = false;