Skip to content

Commit 1960568

Browse files
harisasankHari Sasank
authored andcommitted
vrrp: support route propagation delay
When vrrp state moves out of a fault state, we would like to wait for an additional route propagated delay time, before doing a vrrp master election. During this interval, the packets that are received from other vrrp nodes, which can alter the state of the vrrp instance are dropped. The present nodes, does not pass to participate in leader election which can result in it becoming the master and taking over the VRRP IP.
1 parent d178d93 commit 1960568

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

keepalived/include/vrrp.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,17 @@ typedef struct _vrrp_t {
373373
* preemption based on higher prio over lower
374374
* prio is allowed. 0 means no delay.
375375
*/
376+
unsigned long route_propagation_delay;/* Seconds*TIMER_HZ to wait at startup until
377+
* MDT timer can start. 0 means no delay.
378+
*/
376379
timeval_t preempt_time; /* Time after which preemption can happen */
380+
timeval_t route_propagated_time; /* Time at which all routes are propagated.
381+
* VRRP packets to this interface are dropped before
382+
* all routes are propagated.
383+
*/
384+
bool apply_route_propagation;/* Apply the route propagation delay the next time when
385+
* instance tries to become master.
386+
*/
377387
int state; /* internal state (init/backup/master/fault) */
378388
#ifdef _WITH_SNMP_VRRP_
379389
int configured_state; /* the configured state of the instance */

keepalived/vrrp/vrrp.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,6 +1973,16 @@ vrrp_state_leave_fault(vrrp_t * vrrp)
19731973
/* Set the down timer */
19741974
vrrp->master_adver_int = vrrp->adver_int;
19751975
vrrp->ms_down_timer = VRRP_MS_DOWN_TIMER(vrrp);
1976+
if (vrrp->state == VRRP_STATE_BACK && vrrp->route_propagation_delay > 0)
1977+
{
1978+
vrrp->apply_route_propagation = true;
1979+
vrrp->route_propagated_time = timer_add_long(time_now, vrrp->route_propagation_delay);
1980+
}
1981+
if (vrrp->state == VRRP_STATE_FAULT)
1982+
{
1983+
vrrp->apply_route_propagation = false;
1984+
vrrp->route_propagated_time = time_now;
1985+
}
19761986
vrrp_init_instance_sands(vrrp);
19771987
vrrp->last_transition = timer_now();
19781988
}
@@ -3355,6 +3365,10 @@ vrrp_complete_instance(vrrp_t * vrrp)
33553365
, vrrp->iname);
33563366
vrrp->preempt_delay = false;
33573367
}
3368+
if (vrrp->route_propagation_delay) {
3369+
report_config_error(CONFIG_GENERAL_ERROR, "(%s) Warning - route propagation delay will not work with initial state MASTER - clearing", vrrp->iname);
3370+
vrrp->route_propagation_delay = 0;
3371+
}
33583372
}
33593373
if (vrrp->preempt_delay) {
33603374
if (vrrp->strict_mode) {
@@ -3370,6 +3384,12 @@ vrrp_complete_instance(vrrp_t * vrrp)
33703384
vrrp->preempt_delay = 0;
33713385
}
33723386
}
3387+
if (vrrp->route_propagation_delay) {
3388+
if (vrrp->strict_mode) {
3389+
report_config_error(CONFIG_GENERAL_ERROR, "(%s) route_propagation_delay is incompatible with strict mode - resetting", vrrp->iname);
3390+
vrrp->route_propagation_delay = 0;
3391+
}
3392+
}
33733393

33743394
if (vrrp->down_timer_adverts != VRRP_DOWN_TIMER_ADVERTS && vrrp->strict_mode) {
33753395
report_config_error(CONFIG_GENERAL_ERROR, "(%s) down_timer_adverts is incompatible with"

keepalived/vrrp/vrrp_parser.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,18 @@ vrrp_preempt_delay_handler(const vector_t *strvec)
11441144
current_vrrp->preempt_delay = preempt_delay;
11451145
}
11461146
static void
1147+
vrrp_route_propagation_delay_handler(const vector_t *strvec)
1148+
{
1149+
unsigned route_propagation_delay;
1150+
1151+
if (!read_decimal_unsigned_strvec(strvec, 1, &route_propagation_delay, 0, TIMER_MAX_SEC * TIMER_HZ, TIMER_HZ_DIGITS, true)) {
1152+
report_config_error(CONFIG_GENERAL_ERROR, "(%s) route_propagation_delay not valid! must be between 0-%u", current_vrrp->iname, TIMER_MAX_SEC);
1153+
current_vrrp->route_propagation_delay = 0;
1154+
}
1155+
else
1156+
current_vrrp->route_propagation_delay = route_propagation_delay;
1157+
}
1158+
static void
11471159
vrrp_notify_backup_handler(const vector_t *strvec)
11481160
{
11491161
if (current_vrrp->script_backup) {
@@ -2211,6 +2223,7 @@ init_vrrp_keywords(bool active)
22112223
install_keyword("preempt", &vrrp_preempt_handler);
22122224
install_keyword("nopreempt", &vrrp_nopreempt_handler);
22132225
install_keyword("preempt_delay", &vrrp_preempt_delay_handler);
2226+
install_keyword("route_propagation_delay", &vrrp_route_propagation_delay_handler);
22142227
install_keyword("debug", &vrrp_debug_handler);
22152228
install_keyword_quoted("notify_backup", &vrrp_notify_backup_handler);
22162229
install_keyword_quoted("notify_master", &vrrp_notify_master_handler);

keepalived/vrrp/vrrp_scheduler.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ vrrp_init_state(list_head_t *l)
239239
* very quickly (1usec) */
240240
vrrp->state = VRRP_STATE_BACK;
241241
vrrp->ms_down_timer = 1;
242+
if (vrrp->route_propagation_delay > 0)
243+
{
244+
vrrp->apply_route_propagation = true;
245+
vrrp->route_propagated_time = timer_add_long(time_now, vrrp->route_propagation_delay);
246+
}
247+
242248
}
243249

244250
// TODO Do we need -> vrrp_restore_interface(vrrp, false, false);
@@ -250,6 +256,12 @@ vrrp_init_state(list_head_t *l)
250256
} else
251257
vrrp->ms_down_timer = VRRP_MS_DOWN_TIMER(vrrp);
252258

259+
if (vrrp->route_propagation_delay > 0)
260+
{
261+
vrrp->apply_route_propagation = true;
262+
vrrp->route_propagated_time = timer_add_long(time_now, vrrp->route_propagation_delay);
263+
}
264+
253265
#ifdef _WITH_SNMP_RFCV3_
254266
vrrp->stats->next_master_reason = VRRPV3_MASTER_REASON_MASTER_NO_RESPONSE;
255267
#endif
@@ -323,6 +335,14 @@ vrrp_init_instance_sands(vrrp_t *vrrp)
323335
vrrp->sands = timer_add_long(vrrp_delayed_start_time, vrrp->ms_down_timer);
324336
else
325337
vrrp->sands = timer_add_long(time_now, vrrp->ms_down_timer);
338+
if (vrrp->apply_route_propagation)
339+
{
340+
log_message(LOG_INFO, "Applied vrrp route propagation delay of %lu on instance (%s)",
341+
vrrp->route_propagation_delay, vrrp->iname);
342+
vrrp->sands = timer_add_long(vrrp->sands, vrrp->route_propagation_delay);
343+
vrrp->apply_route_propagation = false;
344+
vrrp->route_propagated_time = vrrp->sands;
345+
}
326346
}
327347
else if (vrrp->state == VRRP_STATE_FAULT || vrrp->state == VRRP_STATE_INIT)
328348
vrrp->sands.tv_sec = TIMER_DISABLED;
@@ -1086,6 +1106,15 @@ vrrp_dispatcher_read(sock_t *sock)
10861106
continue;
10871107
}
10881108

1109+
if (vrrp->route_propagation_delay > 0)
1110+
{
1111+
/* Ignore the message if it is received before all the routes are
1112+
* propagated */
1113+
set_time_now();
1114+
if (timercmp(&time_now, &vrrp->route_propagated_time, <)) {
1115+
return sock->fd_in;
1116+
}
1117+
}
10891118
/* Save non packet data */
10901119
vrrp->pkt_saddr = src_addr;
10911120
vrrp->rx_ttl_hl = -1; /* Default to not received */

0 commit comments

Comments
 (0)