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

vrrp: use instance fault flags instead of a counter #2291

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
34 changes: 24 additions & 10 deletions keepalived/core/keepalived_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
vrrp->family == AF_INET ? VRRP_CONFIGURED_IFP(vrrp) :
#endif
vrrp->ifp) &&
vrrp->num_script_if_fault &&
(vrrp->num_track_fault || vrrp->flags_if_fault) &&
vrrp->family == ifa->ifa_family &&
vrrp->saddr.ss_family == AF_UNSPEC &&
(!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr)) {
Expand All @@ -1015,7 +1015,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
inet_ip4tosockaddr(addr.in, &vrrp->saddr);
else
inet_ip6tosockaddr(addr.in6, &vrrp->saddr);
try_up_instance(vrrp, false);
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
}
#ifdef _HAVE_VRRP_VMAC_
/* If IPv6 link local and vmac doesn't have an address or we have
Expand All @@ -1037,9 +1037,9 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
* does not have one, then we will need the following code
*/
if (add_link_local_address(vrrp->ifp, addr.in6) &&
vrrp->num_script_if_fault &&
(vrrp->num_track_fault || vrrp->flags_if_fault) &&
(!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr))
try_up_instance(vrrp, false);
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
} else
#endif
reset_link_local_address(&vrrp->ifp->sin6_addr, vrrp);
Expand Down Expand Up @@ -1163,7 +1163,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
}
else if (IF_ISUP(ifp)) {
/* We failed to add an address, so down the instance */
down_instance(vrrp);
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
vrrp->saddr.ss_family = AF_UNSPEC;
}
}
Expand All @@ -1181,7 +1181,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
__test_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->flags) ||
IF_ISUP(ifp)) &&
(!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr)) {
down_instance(vrrp);
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
vrrp->saddr.ss_family = AF_UNSPEC;
}
}
Expand Down Expand Up @@ -1583,10 +1583,24 @@ process_if_status_change(interface_t *ifp)
}

/* This vrrp's interface or underlying interface has changed */
if (now_up == (top->weight_multiplier == 1))
try_up_instance(vrrp, false);
else
down_instance(vrrp);
if (now_up == (top->weight_multiplier == 1)) {
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
VRRP_CONFIGURED_IFP(vrrp) == ifp)
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
else
#endif
/* assuming there is only one tracked interface per vrrp : to be checked */
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
} else {
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
VRRP_CONFIGURED_IFP(vrrp) == ifp)
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
else
#endif
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
}
}
}

Expand Down
23 changes: 21 additions & 2 deletions keepalived/include/vrrp.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@ typedef struct _unicast_peer_t {
list_head_t e_list;
} unicast_peer_t;


enum vrrp_if_fault_flags_bits {
VRRP_IF_FAULT_FLAG_UNSPECIFIED = 0,
VRRP_IF_FAULT_FLAG_INTERFACE_DOWN,
#ifdef _HAVE_VRRP_VMAC_
VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN,
VRRP_IF_FAULT_FLAG_DUPLICATE_VRID,
#endif /* _HAVE_VRRP_VMAC_ */
VRRP_IF_FAULT_FLAG_NO_SOURCE_IP,
VRRP_IF_FAULT_FLAG_CONFIG_ERROR,
};

#define VRRP_IF_FAULT_INTERFACE_DOWN 0x1
#ifdef _HAVE_VRRP_VMAC_
#define VRRP_IF_FAULT_BASE_INTERFACE_DOWN 0x2
#endif
#define VRRP_IF_FAULT_DUPLICATE_VRID 0x4

/* parameters per virtual router -- rfc2338.6.1.2 */
typedef struct _vrrp_t {
sa_family_t family; /* AF_INET|AF_INET6 */
Expand Down Expand Up @@ -275,7 +293,8 @@ typedef struct _vrrp_t {
list_head_t track_bfd; /* tracked_bfd_t - BFD instance state we monitor */
#endif
unsigned num_config_faults; /* Number of configuration errors */
unsigned num_script_if_fault; /* Number of scripts and interfaces in fault state */
unsigned num_track_fault; /* Number of trackers (script, bfd...) in fault state */
unsigned long flags_if_fault; /* Flags of interface fault */
unsigned num_script_init; /* Number of scripts in init state */
bool notifies_sent; /* Set when initial notifies have been sent */
bool multicast_pkt; /* Last IPv6 packet received was multicast */
Expand Down Expand Up @@ -451,7 +470,7 @@ typedef struct _vrrp_t {
#endif
#define VRRP_PKT_SADDR(V) (((V)->saddr.ss_family) ? ((struct sockaddr_in *) &(V)->saddr)->sin_addr.s_addr : IF_ADDR(VRRP_CONFIGURED_IFP(V)))

#define VRRP_ISUP(V) (!(V)->num_script_if_fault)
#define VRRP_ISUP(V) (!(V)->num_track_fault && !(V)->flags_if_fault)


/* Configuration summary flags */
Expand Down
2 changes: 1 addition & 1 deletion keepalived/include/vrrp_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ extern void vrrp_dispatcher_release(vrrp_data_t *);
extern void vrrp_gratuitous_arp_thread(thread_ref_t);
extern void vrrp_lower_prio_gratuitous_arp_thread(thread_ref_t);
extern void vrrp_arp_thread(thread_ref_t);
extern void try_up_instance(vrrp_t *, bool);
extern void try_up_instance(vrrp_t *, bool, bool, enum vrrp_if_fault_flags_bits);
#ifdef _WITH_DUMP_THREADS_
extern void dump_threads(void);
#endif
Expand Down
2 changes: 1 addition & 1 deletion keepalived/include/vrrp_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ extern void alloc_track_bfd(const char *, list_head_t *, const vector_t *);
#endif
extern vrrp_script_t *find_script_by_name(const char *) __attribute__ ((pure));
extern void update_script_priorities(vrrp_script_t *, bool);
extern void down_instance(struct _vrrp_t *);
extern void down_instance(struct _vrrp_t *, bool, unsigned);
extern void vrrp_set_effective_priority(struct _vrrp_t *);
extern void initialise_tracking_priorities(void);
#ifdef _WITH_TRACK_PROCESS_
Expand Down
4 changes: 2 additions & 2 deletions keepalived/trackers/track_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ process_update_vrrp_track_file_status(const tracked_file_t *tfile, int new_statu
, vrrp->iname, tfile->fname);
if (top->weight)
vrrp->total_priority -= previous_status;
down_instance(vrrp);
down_instance(vrrp, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
} else if (previous_status == -254) {
if (top->weight) {
vrrp->total_priority += new_status;
Expand All @@ -712,7 +712,7 @@ process_update_vrrp_track_file_status(const tracked_file_t *tfile, int new_statu
log_message(LOG_INFO, "(%s) Setting effective priority to %d"
, vrrp->iname, vrrp->effective_priority);
}
try_up_instance(vrrp, false);
try_up_instance(vrrp, false, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
} else {
vrrp->total_priority += new_status - previous_status;
vrrp_set_effective_priority(vrrp);
Expand Down
33 changes: 23 additions & 10 deletions keepalived/vrrp/vrrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2346,8 +2346,15 @@ del_vrrp_from_interface(vrrp_t *vrrp, interface_t *ifp)

list_for_each_entry_safe(top, top_tmp, &ifp->tracking_vrrp, e_list) {
if (top->obj.vrrp == vrrp && top->type == TRACK_VRRP_DYNAMIC) {
if (!IF_ISUP(ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags))
vrrp->num_script_if_fault--;
if (!IF_ISUP(ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags)) {
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) && VRRP_CONFIGURED_IFP(vrrp) == ifp)
__clear_bit(VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN, &vrrp->flags_if_fault);
else
#endif
/* assuming there is only one tracked interface per vrrp : to be checked */
__clear_bit(VRRP_IF_FAULT_FLAG_INTERFACE_DOWN, &vrrp->flags_if_fault);
}
free_tracking_obj(top);
break;
}
Expand Down Expand Up @@ -2584,8 +2591,8 @@ open_sockpool_socket(sock_t *sock)
rb_for_each_entry(vrrp, &sock->rb_vrid, rb_vrid) {
if (vrrp->state != VRRP_STATE_FAULT)
log_message(LOG_INFO, "(%s): entering FAULT state (src address not configured)", vrrp->iname);
down_instance(vrrp);
if (vrrp->num_script_if_fault == 1)
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
if ((__num_bit(&vrrp->flags_if_fault) + vrrp->num_track_fault) == 1)
send_instance_notifies(vrrp);
}
sock->fd_in = -1;
Expand Down Expand Up @@ -3961,7 +3968,7 @@ vrrp_complete_instance(vrrp_t * vrrp)
}

/* Add us to the vrrp list of the script, and update
* effective_priority and num_script_if_fault */
* effective_priority, flags_if_fault and num_track_fault */
list_for_each_entry_safe(sc, sc_tmp, &vrrp->track_script, e_list) {
vrrp_script_t *vsc = sc->scr;

Expand Down Expand Up @@ -4062,7 +4069,7 @@ sync_group_tracking_init(void)
bool sgroup_has_prio_owner;

/* Add sync group members to the vrrp list of the script, file, i/f,
* and update effective_priority and num_script_if_fault */
* and update effective_priority, flags_if_fault and num_track_fault */
list_for_each_entry(sgroup, &vrrp_data->vrrp_sync_group, e_list) {
if (list_empty(&sgroup->vrrp_instances))
continue;
Expand Down Expand Up @@ -4674,11 +4681,17 @@ vrrp_complete_init(void)
#endif

/* If we add VMAC interfaces, we read netlink messages, which
* may include link down/link up, and these will alter num_script_if_fault
* may include link down/link up, and these will alter num_track_fault and flags_if_fault
* but that is initialised in initialise_tracking_priorities() called below.
* We therefore need to clear num_script_if_fault here. */
list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list)
vrrp->num_script_if_fault = vrrp->num_config_faults;
* We therefore need to clear num_track_fault and flags_if_fault here. */
list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) {
if (vrrp->num_config_faults)
__set_bit(VRRP_IF_FAULT_FLAG_CONFIG_ERROR, &vrrp->flags_if_fault);
else {
vrrp->num_track_fault = 0;
vrrp->flags_if_fault = 0;
}
}

/* Remove any VIPs from the list of default addresses for interfaces */
if (!reload)
Expand Down
3 changes: 2 additions & 1 deletion keepalived/vrrp/vrrp_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,8 @@ dump_vrrp(FILE *fp, const vrrp_t *vrrp)
conf_write(fp, " Wantstate = %s", get_state_str(vrrp->wantstate));
conf_write(fp, " Number of config faults = %u", vrrp->num_config_faults);
if (fp) {
conf_write(fp, " Number of interface and track script faults = %u", vrrp->num_script_if_fault);
conf_write(fp, " Number of tracker faults = %u", vrrp->num_track_fault);
conf_write(fp, " Flags of interface faults = %#lx", vrrp->flags_if_fault);
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags))
conf_write(fp, " Duplicate VRID");
Expand Down
37 changes: 28 additions & 9 deletions keepalived/vrrp/vrrp_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,12 @@ interface_down(interface_t *ifp)

if (route_found) {
/* Bring down vrrp instance/sync group */
down_instance(vrrp);
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) && VRRP_CONFIGURED_IFP(vrrp) == ifp)
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
else
#endif
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
}
}

Expand Down Expand Up @@ -1410,8 +1415,15 @@ cleanup_lost_interface(interface_t *ifp)
if (top->weight) {
vrrp->total_priority -= top->weight * top->weight_multiplier;
vrrp_set_effective_priority(vrrp);
} else
down_instance(vrrp);
} else {
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
VRRP_CONFIGURED_IFP(vrrp) == ifp)
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
else
#endif
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
}
}
continue;
}
Expand Down Expand Up @@ -1451,7 +1463,7 @@ cleanup_lost_interface(interface_t *ifp)
vrrp->configured_ifp == ifp &&
__test_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags)) {
__clear_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags);
vrrp->num_script_if_fault--;
__clear_bit(VRRP_IF_FAULT_FLAG_DUPLICATE_VRID, &vrrp->flags_if_fault);
}
#endif

Expand All @@ -1468,8 +1480,15 @@ cleanup_lost_interface(interface_t *ifp)
}
}

if (IF_ISUP(ifp))
down_instance(vrrp);
if (IF_ISUP(ifp)) {
#ifdef _HAVE_VRRP_VMAC_
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
VRRP_CONFIGURED_IFP(vrrp) == ifp)
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
else
#endif
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
}
}

interface_down(ifp);
Expand Down Expand Up @@ -1525,7 +1544,7 @@ setup_interface(vrrp_t *vrrp)
open_sockpool_socket(vrrp->sockets);

if (vrrp_initialised) {
vrrp->state = vrrp->num_script_if_fault ? VRRP_STATE_FAULT : VRRP_STATE_BACK;
vrrp->state = (vrrp->num_track_fault || vrrp->flags_if_fault) ? VRRP_STATE_FAULT : VRRP_STATE_BACK;
vrrp_init_instance_sands(vrrp);
vrrp_thread_add_read(vrrp);
}
Expand Down Expand Up @@ -1638,7 +1657,7 @@ update_added_interface(interface_t *ifp)
if (IF_BASE_IFP(VRRP_CONFIGURED_IFP(vrrp)) == IF_BASE_IFP(VRRP_CONFIGURED_IFP(vrrp1)) &&
vrrp->family == vrrp1->family &&
vrrp->vrid == vrrp1->vrid) {
vrrp->num_script_if_fault++;
__set_bit(VRRP_IF_FAULT_FLAG_DUPLICATE_VRID, &vrrp->flags_if_fault);
__set_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags);
log_message(LOG_INFO, "VRID conflict between %s and %s IPv%d vrid %d",
vrrp->iname, vrrp1->iname, vrrp->family == AF_INET ? 4 : 6, vrrp->vrid);
Expand All @@ -1653,7 +1672,7 @@ update_added_interface(interface_t *ifp)
if (!IF_ISUP(vrrp->configured_ifp->base_ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags)) {
log_message(LOG_INFO, "(%s) interface %s is down",
vrrp->iname, vrrp->configured_ifp->base_ifp->ifname);
vrrp->num_script_if_fault++;
__set_bit(VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN, &vrrp->flags_if_fault);
}
}

Expand Down
33 changes: 26 additions & 7 deletions keepalived/vrrp/vrrp_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <stdio.h>
#include <inttypes.h>

#include <assert.h>

#include "vrrp_scheduler.h"
#include "vrrp_track.h"
#ifdef _HAVE_VRRP_VMAC_
Expand Down Expand Up @@ -285,7 +287,8 @@ vrrp_init_state(list_head_t *l)
if (vrrp_begin_state != vrrp->state)
vrrp->last_transition = timer_now();
if (vrrp_begin_state != vrrp->state &&
(vrrp->state != VRRP_STATE_FAULT || vrrp->num_script_if_fault))
(vrrp->state != VRRP_STATE_FAULT ||
vrrp->num_track_fault || vrrp->flags_if_fault))
send_instance_notifies(vrrp);
else if (reload && global_data->fifo_write_vrrp_states_on_reload)
notify_instance_fifo(vrrp);
Expand Down Expand Up @@ -661,17 +664,33 @@ vrrp_lower_prio_gratuitous_arp_thread(thread_ref_t thread)
}

void
try_up_instance(vrrp_t *vrrp, bool leaving_init)
try_up_instance(vrrp_t *vrrp,bool leaving_init,
bool resolved_script,
enum vrrp_if_fault_flags_bits resolved_flag)
{
int wantstate;
ip_address_t ip_addr = {};

/* We can not use try_up_instance() for several resolution
* at the same time
*/
assert(!(resolved_script && resolved_flag != VRRP_IF_FAULT_FLAG_UNSPECIFIED));

if (leaving_init) {
if (vrrp->num_script_if_fault)
if (vrrp->num_track_fault || vrrp->flags_if_fault)
return;
} else {
if (resolved_script)
vrrp->num_track_fault--;
if (resolved_flag != VRRP_IF_FAULT_FLAG_UNSPECIFIED)
__clear_bit(resolved_flag, &vrrp->flags_if_fault);
}
else if (--vrrp->num_script_if_fault || vrrp->num_script_init) {
if (!vrrp->num_script_if_fault) {

if (vrrp->num_track_fault || vrrp->flags_if_fault)
return;

if (vrrp->num_script_init) {
if (!vrrp->num_track_fault && !vrrp->flags_if_fault) {
if (vrrp->sync) {
vrrp->sync->num_member_fault--;
vrrp->sync->state = VRRP_STATE_INIT;
Expand Down Expand Up @@ -800,9 +819,9 @@ vrrp_handle_bfd_event(bfd_event_t * evt)
}

if (!!vbfd->bfd_up == (tbfd->weight_multiplier == 1))
try_up_instance(vrrp, false);
try_up_instance(vrrp, false, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
else
down_instance(vrrp);
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
}

break;
Expand Down
Loading