Skip to content

Commit 3613636

Browse files
authored
Merge pull request #2291 from louis-6wind/fault-flag
vrrp: use instance fault flags instead of a counter
2 parents 1bb3f60 + 5c3eb9c commit 3613636

File tree

11 files changed

+181
-57
lines changed

11 files changed

+181
-57
lines changed

keepalived/core/keepalived_netlink.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
10101010
vrrp->family == AF_INET ? VRRP_CONFIGURED_IFP(vrrp) :
10111011
#endif
10121012
vrrp->ifp) &&
1013-
vrrp->num_script_if_fault &&
1013+
(vrrp->num_track_fault || vrrp->flags_if_fault) &&
10141014
vrrp->family == ifa->ifa_family &&
10151015
vrrp->saddr.ss_family == AF_UNSPEC &&
10161016
(!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr)) {
@@ -1019,7 +1019,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
10191019
inet_ip4tosockaddr(addr.in, &vrrp->saddr);
10201020
else
10211021
inet_ip6tosockaddr(addr.in6, &vrrp->saddr);
1022-
try_up_instance(vrrp, false);
1022+
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
10231023
}
10241024
#ifdef _HAVE_VRRP_VMAC_
10251025
/* If IPv6 link local and vmac doesn't have an address or we have
@@ -1041,9 +1041,9 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
10411041
* does not have one, then we will need the following code
10421042
*/
10431043
if (add_link_local_address(vrrp->ifp, addr.in6) &&
1044-
vrrp->num_script_if_fault &&
1044+
(vrrp->num_track_fault || vrrp->flags_if_fault) &&
10451045
(!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr))
1046-
try_up_instance(vrrp, false);
1046+
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
10471047
} else
10481048
#endif
10491049
reset_link_local_address(&vrrp->ifp->sin6_addr, vrrp);
@@ -1167,7 +1167,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
11671167
}
11681168
else if (IF_ISUP(ifp)) {
11691169
/* We failed to add an address, so down the instance */
1170-
down_instance(vrrp);
1170+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
11711171
vrrp->saddr.ss_family = AF_UNSPEC;
11721172
}
11731173
}
@@ -1195,7 +1195,7 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc
11951195
)
11961196
vrrp->saddr.ss_family = AF_UNSPEC;
11971197

1198-
down_instance(vrrp);
1198+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
11991199
vrrp->saddr.ss_family = AF_UNSPEC;
12001200
}
12011201
}
@@ -1601,10 +1601,24 @@ process_if_status_change(interface_t *ifp)
16011601
}
16021602

16031603
/* This vrrp's interface or underlying interface has changed */
1604-
if (now_up == (top->weight_multiplier == 1))
1605-
try_up_instance(vrrp, false);
1606-
else
1607-
down_instance(vrrp);
1604+
if (now_up == (top->weight_multiplier == 1)) {
1605+
#ifdef _HAVE_VRRP_VMAC_
1606+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
1607+
VRRP_CONFIGURED_IFP(vrrp) == ifp)
1608+
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
1609+
else
1610+
#endif
1611+
/* assuming there is only one tracked interface per vrrp : to be checked */
1612+
try_up_instance(vrrp, false, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
1613+
} else {
1614+
#ifdef _HAVE_VRRP_VMAC_
1615+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
1616+
VRRP_CONFIGURED_IFP(vrrp) == ifp)
1617+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
1618+
else
1619+
#endif
1620+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
1621+
}
16081622
}
16091623
}
16101624

keepalived/include/vrrp.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,24 @@ typedef struct _unicast_peer_t {
271271
list_head_t e_list;
272272
} unicast_peer_t;
273273

274+
275+
enum vrrp_if_fault_flags_bits {
276+
VRRP_IF_FAULT_FLAG_UNSPECIFIED = 0,
277+
VRRP_IF_FAULT_FLAG_INTERFACE_DOWN,
278+
#ifdef _HAVE_VRRP_VMAC_
279+
VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN,
280+
VRRP_IF_FAULT_FLAG_DUPLICATE_VRID,
281+
#endif /* _HAVE_VRRP_VMAC_ */
282+
VRRP_IF_FAULT_FLAG_NO_SOURCE_IP,
283+
VRRP_IF_FAULT_FLAG_CONFIG_ERROR,
284+
};
285+
286+
#define VRRP_IF_FAULT_INTERFACE_DOWN 0x1
287+
#ifdef _HAVE_VRRP_VMAC_
288+
#define VRRP_IF_FAULT_BASE_INTERFACE_DOWN 0x2
289+
#endif
290+
#define VRRP_IF_FAULT_DUPLICATE_VRID 0x4
291+
274292
/* parameters per virtual router -- rfc2338.6.1.2 */
275293
typedef struct _vrrp_t {
276294
sa_family_t family; /* AF_INET|AF_INET6 */
@@ -304,7 +322,8 @@ typedef struct _vrrp_t {
304322
list_head_t track_bfd; /* tracked_bfd_t - BFD instance state we monitor */
305323
#endif
306324
unsigned num_config_faults; /* Number of configuration errors */
307-
unsigned num_script_if_fault; /* Number of scripts and interfaces in fault state */
325+
unsigned num_track_fault; /* Number of trackers (script, bfd...) in fault state */
326+
unsigned long flags_if_fault; /* Flags of interface fault */
308327
unsigned num_script_init; /* Number of scripts in init state */
309328
bool notifies_sent; /* Set when initial notifies have been sent */
310329
bool multicast_pkt; /* Last IPv6 packet received was multicast */
@@ -483,7 +502,7 @@ enum vrrp_packet_status {
483502
#endif
484503
#define VRRP_PKT_SADDR(V) (((V)->saddr.ss_family) ? ((struct sockaddr_in *) &(V)->saddr)->sin_addr.s_addr : IF_ADDR(VRRP_CONFIGURED_IFP(V)))
485504

486-
#define VRRP_ISUP(V) (!(V)->num_script_if_fault)
505+
#define VRRP_ISUP(V) (!(V)->num_track_fault && !(V)->flags_if_fault)
487506

488507

489508
/* Configuration summary flags */

keepalived/include/vrrp_scheduler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ extern void vrrp_gratuitous_arp_vmac_update_thread(thread_ref_t);
7272
#endif
7373
extern void vrrp_arp_thread(thread_ref_t);
7474
extern void vrrp_gna_thread(thread_ref_t);
75-
extern void try_up_instance(vrrp_t *, bool);
75+
extern void try_up_instance(vrrp_t *, bool, bool, enum vrrp_if_fault_flags_bits);
7676
#ifdef _WITH_DUMP_THREADS_
7777
extern void dump_threads(void);
7878
#endif

keepalived/include/vrrp_track.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ extern void alloc_track_bfd(const char *, list_head_t *, const vector_t *);
204204
#endif
205205
extern vrrp_script_t *find_script_by_name(const char *) __attribute__ ((pure));
206206
extern void update_script_priorities(vrrp_script_t *, bool);
207-
extern void down_instance(struct _vrrp_t *);
207+
extern void down_instance(struct _vrrp_t *, bool, unsigned);
208208
extern void vrrp_set_effective_priority(struct _vrrp_t *);
209209
extern void initialise_tracking_priorities(void);
210210
#ifdef _WITH_TRACK_PROCESS_

keepalived/trackers/track_file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ process_update_vrrp_track_file_status(const tracked_file_t *tfile, int new_statu
709709
, vrrp->iname, tfile->fname);
710710
if (top->weight)
711711
vrrp->total_priority -= previous_status;
712-
down_instance(vrrp);
712+
down_instance(vrrp, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
713713
} else if (previous_status == -254) {
714714
if (top->weight) {
715715
vrrp->total_priority += new_status;
@@ -722,7 +722,7 @@ process_update_vrrp_track_file_status(const tracked_file_t *tfile, int new_statu
722722
log_message(LOG_INFO, "(%s) Setting effective priority to %d"
723723
, vrrp->iname, vrrp->effective_priority);
724724
}
725-
try_up_instance(vrrp, false);
725+
try_up_instance(vrrp, false, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
726726
} else {
727727
vrrp->total_priority += new_status - previous_status;
728728
vrrp_set_effective_priority(vrrp);

keepalived/vrrp/vrrp.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,8 +2520,15 @@ del_vrrp_from_interface(vrrp_t *vrrp, interface_t *ifp)
25202520

25212521
list_for_each_entry_safe(top, top_tmp, &ifp->tracking_vrrp, e_list) {
25222522
if (top->obj.vrrp == vrrp && top->type == TRACK_VRRP_DYNAMIC) {
2523-
if (!IF_ISUP(ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags))
2524-
vrrp->num_script_if_fault--;
2523+
if (!IF_ISUP(ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags)) {
2524+
#ifdef _HAVE_VRRP_VMAC_
2525+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) && VRRP_CONFIGURED_IFP(vrrp) == ifp)
2526+
__clear_bit(VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN, &vrrp->flags_if_fault);
2527+
else
2528+
#endif
2529+
/* assuming there is only one tracked interface per vrrp : to be checked */
2530+
__clear_bit(VRRP_IF_FAULT_FLAG_INTERFACE_DOWN, &vrrp->flags_if_fault);
2531+
}
25252532
free_tracking_obj(top);
25262533
break;
25272534
}
@@ -2776,8 +2783,8 @@ open_sockpool_socket(sock_t *sock)
27762783
rb_for_each_entry(vrrp, &sock->rb_vrid, rb_vrid) {
27772784
if (vrrp->state != VRRP_STATE_FAULT)
27782785
log_message(LOG_INFO, "(%s): entering FAULT state (src address not configured)", vrrp->iname);
2779-
down_instance(vrrp);
2780-
if (vrrp->num_script_if_fault == 1)
2786+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_NO_SOURCE_IP);
2787+
if ((__num_bit(&vrrp->flags_if_fault) + vrrp->num_track_fault) == 1)
27812788
send_instance_notifies(vrrp);
27822789
}
27832790
sock->fd_in = -1;
@@ -4175,7 +4182,7 @@ vrrp_complete_instance(vrrp_t * vrrp)
41754182
}
41764183

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

@@ -4276,7 +4283,7 @@ sync_group_tracking_init(void)
42764283
bool sgroup_has_prio_owner;
42774284

42784285
/* Add sync group members to the vrrp list of the script, file, i/f,
4279-
* and update effective_priority and num_script_if_fault */
4286+
* and update effective_priority, flags_if_fault and num_track_fault */
42804287
list_for_each_entry(sgroup, &vrrp_data->vrrp_sync_group, e_list) {
42814288
if (list_empty(&sgroup->vrrp_instances))
42824289
continue;
@@ -4892,11 +4899,17 @@ vrrp_complete_init(void)
48924899
#endif
48934900

48944901
/* If we add VMAC interfaces, we read netlink messages, which
4895-
* may include link down/link up, and these will alter num_script_if_fault
4902+
* may include link down/link up, and these will alter num_track_fault and flags_if_fault
48964903
* but that is initialised in initialise_tracking_priorities() called below.
4897-
* We therefore need to clear num_script_if_fault here. */
4898-
list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list)
4899-
vrrp->num_script_if_fault = vrrp->num_config_faults;
4904+
* We therefore need to clear num_track_fault and flags_if_fault here. */
4905+
list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) {
4906+
if (vrrp->num_config_faults)
4907+
__set_bit(VRRP_IF_FAULT_FLAG_CONFIG_ERROR, &vrrp->flags_if_fault);
4908+
else {
4909+
vrrp->num_track_fault = 0;
4910+
vrrp->flags_if_fault = 0;
4911+
}
4912+
}
49004913

49014914
/* Remove any VIPs from the list of default addresses for interfaces */
49024915
if (!reload)

keepalived/vrrp/vrrp_data.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,8 @@ dump_vrrp(FILE *fp, const vrrp_t *vrrp)
642642
conf_write(fp, " Wantstate = %s", get_state_str(vrrp->wantstate));
643643
conf_write(fp, " Number of config faults = %u", vrrp->num_config_faults);
644644
if (fp) {
645-
conf_write(fp, " Number of interface and track script faults = %u", vrrp->num_script_if_fault);
645+
conf_write(fp, " Number of tracker faults = %u", vrrp->num_track_fault);
646+
conf_write(fp, " Flags of interface faults = %#lx", vrrp->flags_if_fault);
646647
#ifdef _HAVE_VRRP_VMAC_
647648
if (__test_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags))
648649
conf_write(fp, " Duplicate VRID");

keepalived/vrrp/vrrp_if.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,12 @@ interface_down(interface_t *ifp)
14141414

14151415
if (route_found) {
14161416
/* Bring down vrrp instance/sync group */
1417-
down_instance(vrrp);
1417+
#ifdef _HAVE_VRRP_VMAC_
1418+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) && VRRP_CONFIGURED_IFP(vrrp) == ifp)
1419+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
1420+
else
1421+
#endif
1422+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
14181423
}
14191424
}
14201425

@@ -1451,8 +1456,15 @@ cleanup_lost_interface(interface_t *ifp)
14511456
if (top->weight) {
14521457
vrrp->total_priority -= top->weight * top->weight_multiplier;
14531458
vrrp_set_effective_priority(vrrp);
1454-
} else
1455-
down_instance(vrrp);
1459+
} else {
1460+
#ifdef _HAVE_VRRP_VMAC_
1461+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
1462+
VRRP_CONFIGURED_IFP(vrrp) == ifp)
1463+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
1464+
else
1465+
#endif
1466+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
1467+
}
14561468
}
14571469
continue;
14581470
}
@@ -1492,7 +1504,7 @@ cleanup_lost_interface(interface_t *ifp)
14921504
vrrp->configured_ifp == ifp &&
14931505
__test_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags)) {
14941506
__clear_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags);
1495-
vrrp->num_script_if_fault--;
1507+
__clear_bit(VRRP_IF_FAULT_FLAG_DUPLICATE_VRID, &vrrp->flags_if_fault);
14961508
}
14971509
#endif
14981510

@@ -1509,8 +1521,15 @@ cleanup_lost_interface(interface_t *ifp)
15091521
}
15101522
}
15111523

1512-
if (IF_ISUP(ifp))
1513-
down_instance(vrrp);
1524+
if (IF_ISUP(ifp)) {
1525+
#ifdef _HAVE_VRRP_VMAC_
1526+
if (__test_bit(VRRP_VMAC_BIT, &vrrp->flags) &&
1527+
VRRP_CONFIGURED_IFP(vrrp) == ifp)
1528+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN);
1529+
else
1530+
#endif
1531+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_INTERFACE_DOWN);
1532+
}
15141533
}
15151534

15161535
interface_down(ifp);
@@ -1566,7 +1585,7 @@ setup_interface(vrrp_t *vrrp)
15661585
open_sockpool_socket(vrrp->sockets);
15671586

15681587
if (vrrp_initialised) {
1569-
vrrp->state = vrrp->num_script_if_fault ? VRRP_STATE_FAULT : VRRP_STATE_BACK;
1588+
vrrp->state = (vrrp->num_track_fault || vrrp->flags_if_fault) ? VRRP_STATE_FAULT : VRRP_STATE_BACK;
15701589
vrrp_init_instance_sands(vrrp);
15711590
vrrp_thread_add_read(vrrp);
15721591
}
@@ -1679,7 +1698,7 @@ update_added_interface(interface_t *ifp)
16791698
if (IF_BASE_IFP(VRRP_CONFIGURED_IFP(vrrp)) == IF_BASE_IFP(VRRP_CONFIGURED_IFP(vrrp1)) &&
16801699
vrrp->family == vrrp1->family &&
16811700
vrrp->vrid == vrrp1->vrid) {
1682-
vrrp->num_script_if_fault++;
1701+
__set_bit(VRRP_IF_FAULT_FLAG_DUPLICATE_VRID, &vrrp->flags_if_fault);
16831702
__set_bit(VRRP_FLAG_DUPLICATE_VRID_FAULT, &vrrp->flags);
16841703
log_message(LOG_INFO, "VRID conflict between %s and %s IPv%d vrid %d",
16851704
vrrp->iname, vrrp1->iname, vrrp->family == AF_INET ? 4 : 6, vrrp->vrid);
@@ -1701,7 +1720,7 @@ update_added_interface(interface_t *ifp)
17011720
if (!IF_ISUP(vrrp->configured_ifp->base_ifp) && !__test_bit(VRRP_FLAG_DONT_TRACK_PRIMARY, &vrrp->flags)) {
17021721
log_message(LOG_INFO, "(%s) interface %s is down",
17031722
vrrp->iname, vrrp->configured_ifp->base_ifp->ifname);
1704-
vrrp->num_script_if_fault++;
1723+
__set_bit(VRRP_IF_FAULT_FLAG_BASE_INTERFACE_DOWN, &vrrp->flags_if_fault);
17051724
}
17061725
}
17071726

keepalived/vrrp/vrrp_scheduler.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <stdio.h>
3333
#include <inttypes.h>
3434

35+
#include <assert.h>
36+
3537
#include "vrrp_scheduler.h"
3638
#include "vrrp_track.h"
3739
#ifdef _HAVE_VRRP_VMAC_
@@ -287,7 +289,8 @@ vrrp_init_state(list_head_t *l)
287289
if (vrrp_begin_state != vrrp->state)
288290
vrrp->last_transition = timer_now();
289291
if (vrrp_begin_state != vrrp->state &&
290-
(vrrp->state != VRRP_STATE_FAULT || vrrp->num_script_if_fault))
292+
(vrrp->state != VRRP_STATE_FAULT ||
293+
vrrp->num_track_fault || vrrp->flags_if_fault))
291294
send_instance_notifies(vrrp);
292295
else if (reload && global_data->fifo_write_vrrp_states_on_reload)
293296
notify_instance_fifo(vrrp);
@@ -688,17 +691,33 @@ vrrp_gratuitous_arp_vmac_update_thread(thread_ref_t thread)
688691
#endif
689692

690693
void
691-
try_up_instance(vrrp_t *vrrp, bool leaving_init)
694+
try_up_instance(vrrp_t *vrrp,bool leaving_init,
695+
bool resolved_script,
696+
enum vrrp_if_fault_flags_bits resolved_flag)
692697
{
693698
int wantstate;
694699
ip_address_t ip_addr = {0};
695700

701+
/* We can not use try_up_instance() for several resolution
702+
* at the same time
703+
*/
704+
assert(!(resolved_script && resolved_flag != VRRP_IF_FAULT_FLAG_UNSPECIFIED));
705+
696706
if (leaving_init) {
697-
if (vrrp->num_script_if_fault)
707+
if (vrrp->num_track_fault || vrrp->flags_if_fault)
698708
return;
709+
} else {
710+
if (resolved_script)
711+
vrrp->num_track_fault--;
712+
if (resolved_flag != VRRP_IF_FAULT_FLAG_UNSPECIFIED)
713+
__clear_bit(resolved_flag, &vrrp->flags_if_fault);
699714
}
700-
else if (--vrrp->num_script_if_fault || vrrp->num_script_init) {
701-
if (!vrrp->num_script_if_fault) {
715+
716+
if (vrrp->num_track_fault || vrrp->flags_if_fault)
717+
return;
718+
719+
if (vrrp->num_script_init) {
720+
if (!vrrp->num_track_fault && !vrrp->flags_if_fault) {
702721
if (vrrp->sync) {
703722
vrrp->sync->num_member_fault--;
704723
vrrp->sync->state = VRRP_STATE_INIT;
@@ -827,9 +846,9 @@ vrrp_handle_bfd_event(bfd_event_t * evt)
827846
}
828847

829848
if (!!vbfd->bfd_up == (tbfd->weight_multiplier == 1))
830-
try_up_instance(vrrp, false);
849+
try_up_instance(vrrp, false, true, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
831850
else
832-
down_instance(vrrp);
851+
down_instance(vrrp, false, VRRP_IF_FAULT_FLAG_UNSPECIFIED);
833852
}
834853

835854
break;

0 commit comments

Comments
 (0)