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

Fix calling protocol_to_index() and other minor changes #2375

Merged
merged 5 commits into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion keepalived/check/check_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ dump_vs(FILE *fp, const virtual_server_t *vs)
conf_write(fp, " protocol = UDP");
else if (vs->service_type == IPPROTO_SCTP)
conf_write(fp, " protocol = SCTP");
else if (vs->service_type == 0)
else if (vs->service_type == IPPROTO_IP)
conf_write(fp, " protocol = none");
else
conf_write(fp, " protocol = %d", vs->service_type);
Expand Down
40 changes: 15 additions & 25 deletions keepalived/check/ipvswrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "namespaces.h"
#ifdef _WITH_NFTABLES_
#include "check_nftables.h"
#include "check_data.h"
#endif

static bool no_ipvs = false;
Expand Down Expand Up @@ -580,32 +581,30 @@ ipvs_cmd(int cmd, virtual_server_t *vs, real_server_t *rs)

/* Set vs rule and send to kernel */
#ifdef _WITH_NFTABLES_
if (vs->service_type)
if (VS_USES_VSG_AUTO_FWMARK(vs))
proto_index = protocol_to_index(vs->service_type);
else
proto_index = PROTO_INDEX_MAX;
proto_index = PROTO_INDEX_NONE;
#endif

if (vs->vsg) {
#ifdef _WITH_NFTABLES_
if (cmd == IP_VS_SO_SET_ADD &&
global_data->ipvs_nf_table_name &&
proto_index < PROTO_INDEX_MAX &&
list_empty(&vs->vsg->vfwmark) &&
VS_USES_VSG_AUTO_FWMARK(vs) &&
!vs->vsg->auto_fwmark[proto_index]) {
vs->vsg->auto_fwmark[proto_index] = set_vs_fwmark(vs);
} else if (proto_index == PROTO_INDEX_MAX || !vs->vsg->auto_fwmark[proto_index])
} else if (proto_index == PROTO_INDEX_NONE || !vs->vsg->auto_fwmark[proto_index])
#endif
return ipvs_group_cmd(cmd, &srule, &drule, vs, rs);
}

if (vs->vfwmark
#ifdef _WITH_NFTABLES_
|| (vs->vsg && proto_index < PROTO_INDEX_MAX && vs->vsg->auto_fwmark[proto_index])
|| VS_USES_VSG_AUTO_FWMARK(vs)
#endif
) {
#ifdef _WITH_NFTABLES_
srule.user.fwmark = vs->vsg ? vs->vsg->auto_fwmark[proto_index] : vs->vfwmark;
srule.user.fwmark = VS_USES_VSG_AUTO_FWMARK(vs) ? vs->vsg->auto_fwmark[proto_index] : vs->vfwmark;
#else
srule.user.fwmark = vs->vfwmark;
#endif
Expand All @@ -630,7 +629,7 @@ ipvs_cmd(int cmd, virtual_server_t *vs, real_server_t *rs)
vs->af == AF_UNSPEC &&
vs->vsg->have_ipv4 &&
vs->vsg->have_ipv6 &&
proto_index < PROTO_INDEX_MAX &&
proto_index != PROTO_INDEX_NONE &&
vs->vsg->auto_fwmark[proto_index]) {
srule.af = AF_INET6;
srule.user.netmask = 128;
Expand All @@ -648,14 +647,11 @@ ipvs_group_sync_entry(virtual_server_t *vs, virtual_server_group_entry_t *vsge)
real_server_t *rs;
ipvs_service_t srule;
ipvs_dest_t drule;
#ifdef _WITH_NFTABLES_
proto_index_t proto_index = protocol_to_index(vs->service_type);
#endif

ipvs_set_srule(IP_VS_SO_SET_ADDDEST, &srule, vs);
#ifdef _WITH_NFTABLES_
if (vs->vsg->auto_fwmark[proto_index])
srule.user.fwmark = vs->vsg->auto_fwmark[proto_index];
if (VS_USES_VSG_AUTO_FWMARK(vs))
srule.user.fwmark = vs->vsg->auto_fwmark[protocol_to_index(vs->service_type)];
else
#endif
if (vsge->is_fwmark)
Expand Down Expand Up @@ -696,13 +692,10 @@ ipvs_group_remove_entry(virtual_server_t *vs, virtual_server_group_entry_t *vsge
real_server_t *rs;
ipvs_service_t srule;
ipvs_dest_t drule;
#ifdef _WITH_NFTABLES_
proto_index_t proto_index = protocol_to_index(vs->service_type);
#endif

#ifdef _WITH_NFTABLES_
/* Prepare target rules */
if (vs->vsg->auto_fwmark[proto_index]) {
if (VS_USES_VSG_AUTO_FWMARK(vs)) {
/* Remove the fwmark entry(s) */
remove_vs_fwmark_entry(vs, vsge);

Expand All @@ -716,8 +709,8 @@ ipvs_group_remove_entry(virtual_server_t *vs, virtual_server_group_entry_t *vsge

ipvs_set_srule(IP_VS_SO_SET_DELDEST, &srule, vs);
#ifdef _WITH_NFTABLES_
if (vs->vsg->auto_fwmark[proto_index])
srule.user.fwmark = vs->vsg->auto_fwmark[proto_index];
if (VS_USES_VSG_AUTO_FWMARK(vs))
srule.user.fwmark = vs->vsg->auto_fwmark[protocol_to_index(vs->service_type)];
else
#endif
if (vsge->is_fwmark)
Expand Down Expand Up @@ -892,9 +885,6 @@ ipvs_update_stats(virtual_server_t *vs)
real_server_t *rs;
time_t cur_time = time(NULL);
uint16_t af;
#ifdef _WITH_NFTABLES_
proto_index_t proto_index = protocol_to_index(vs->service_type);
#endif

if (cur_time - vs->lastupdated < STATS_REFRESH)
return;
Expand All @@ -916,8 +906,8 @@ ipvs_update_stats(virtual_server_t *vs)
if (vs->vsg) {
for (af = (vs->vsg->have_ipv4) ? AF_INET : AF_INET6; af != AF_UNSPEC; af = af == AF_INET && vs->vsg->have_ipv6 ? AF_INET6 : AF_UNSPEC) {
#ifdef _WITH_NFTABLES_
if (global_data->ipvs_nf_table_name && vs->vsg->auto_fwmark[proto_index])
ipvs_update_vs_stats(vs, af, vs->vsg->auto_fwmark[proto_index], &nfaddr, 0);
if (VS_USES_VSG_AUTO_FWMARK(vs))
ipvs_update_vs_stats(vs, af, vs->vsg->auto_fwmark[protocol_to_index(vs->service_type)], &nfaddr, 0);
else
#endif
{
Expand Down
24 changes: 10 additions & 14 deletions keepalived/check/ipwrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "track_file.h"
#ifdef _WITH_NFTABLES_
#include "check_nftables.h"
#include "check_data.h"
#endif

static bool __attribute((pure))
Expand Down Expand Up @@ -358,7 +359,7 @@ clear_service_vs(virtual_server_t * vs, bool stopping)
/* The above will handle Omega case for VS as well. */

#ifdef _WITH_NFTABLES_
if (vs->vsg && vs->vsg->auto_fwmark[protocol_to_index(vs->service_type)])
if (VS_USES_VSG_AUTO_FWMARK(vs))
clear_vs_fwmark(vs);
#endif

Expand Down Expand Up @@ -627,17 +628,11 @@ perform_svr_state(bool alive, checker_t *checker)
static bool
init_service_vs(virtual_server_t * vs)
{
#ifdef _WITH_NFTABLES_
proto_index_t proto_index = 0;

if (vs->service_type != AF_UNSPEC)
proto_index = protocol_to_index(vs->service_type);
#endif

/* Init the VS root */
if (!ISALIVE(vs) || vs->vsg) {
#ifdef _WITH_NFTABLES_
if (ISALIVE(vs) && vs->vsg && (vs->service_type == AF_UNSPEC || vs->vsg->auto_fwmark[proto_index]))
if (ISALIVE(vs) &&
VS_USES_VSG_AUTO_FWMARK(vs))
set_vs_fwmark(vs);
else
#endif
Expand All @@ -650,9 +645,9 @@ init_service_vs(virtual_server_t * vs)
/* Processing real server queue */
init_service_rs(vs);

if (vs->reloaded && vs->vsgname
if (vs->reloaded && vs->vsg
#ifdef _WITH_NFTABLES_
&& !vs->vsg->auto_fwmark[proto_index]
&& !VS_USES_VSG_AUTO_FWMARK(vs)
#endif
) {
/* add reloaded dests into new vsg entries */
Expand Down Expand Up @@ -893,9 +888,10 @@ clear_diff_vsg(virtual_server_t *old_vs, virtual_server_t *new_vs)
virtual_server_group_t *new = new_vs->vsg;
#ifdef _WITH_NFTABLES_
bool vsg_already_done;
proto_index_t proto_index = protocol_to_index(new_vs->service_type);
proto_index_t proto_index;

if (old_vs->vsg->auto_fwmark[proto_index]) {
if (VS_USES_VSG_AUTO_FWMARK(old_vs)) {
proto_index = protocol_to_index(new_vs->service_type);
vsg_already_done = !!new_vs->vsg->auto_fwmark[proto_index];

new_vs->vsg->auto_fwmark[proto_index] = old_vs->vsg->auto_fwmark[proto_index];
Expand Down Expand Up @@ -1117,7 +1113,7 @@ clear_diff_services(void)
/* Remove diff entries from previous IPVS rules */
list_for_each_entry(vs, &old_check_data->vs, e_list) {
/*
* Try to find this vs into the new conf data
* Try to find this vs in the new conf data
* reloaded.
*/
new_vs = vs_exist(vs);
Expand Down
4 changes: 4 additions & 0 deletions keepalived/include/check_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ extern checker_t *current_checker;
#define CHECKER_ARG(X) ((X)->data)
#define CHECKER_NEW_CO() ((conn_opts_t *) MALLOC(sizeof (conn_opts_t)))
#define FMT_CHK(C) FMT_RS((C)->rs, (C)->vs)
#ifdef _WITH_NFTABLES_
#define VSG_USES_AUTO_FWMARK(vsg) (global_data->ipvs_nf_table_name && list_empty(&vsg->vfwmark))
#define VS_USES_VSG_AUTO_FWMARK(vs) (vs->vsg && VSG_USES_AUTO_FWMARK(vs->vsg))
#endif

#ifdef _CHECKER_DEBUG_
extern bool do_checker_debug;
Expand Down
13 changes: 10 additions & 3 deletions keepalived/include/check_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ typedef enum {
TCP_INDEX,
UDP_INDEX,
SCTP_INDEX,
PROTO_INDEX_MAX
PROTO_INDEX_NONE,
PROTO_INDEX_MAX = PROTO_INDEX_NONE
} proto_index_t;
#endif

Expand Down Expand Up @@ -274,8 +275,14 @@ real_weight(int64_t effective_weight)
}

#ifdef _WITH_NFTABLES_

/* We need to ensure that the file/function/line logged relates to where
* protocol_to_index() is called from.
*/
#define protocol_to_index(proto) protocol_to_index_flf(proto, __func__, __LINE__, __FILE__)

static inline proto_index_t
protocol_to_index(int proto)
protocol_to_index_flf(int proto, const char *func, int line, const char *file)
{
if (proto == IPPROTO_TCP)
return TCP_INDEX;
Expand All @@ -284,7 +291,7 @@ protocol_to_index(int proto)
if (proto == IPPROTO_SCTP)
return SCTP_INDEX;

log_message(LOG_INFO, "Unknown protocol %d at %s:%d in %s", proto, __func__, __LINE__, __FILE__);
log_message(LOG_INFO, "Unknown protocol %d in protocol_to_index() called from %s at %s:%d", proto, func, file, line);

return UDP_INDEX;
}
Expand Down
8 changes: 8 additions & 0 deletions test/ncat_resp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# For testing. Either have --ssl and -S in first and second commands, or omit both

# To run: ip netns exec high ncat -l -p 443 -e $(pwd)/test/ncat_resp.sh -k --ssl
# To test: ip netns exec low keepalived/keepalived -T -p 443 -s 10.200.30.211 -u /loadbalancer -P 1.1 -v -S

${0%/*}/tcp_server -Z -W / -w /loadbalancer.html fred -P -gG
Loading
Loading