From 211f6997944de593a3b37121ce05cb6a2c6ed28f Mon Sep 17 00:00:00 2001 From: Arnaud ANDRE Date: Mon, 18 Jan 2016 18:44:39 +0100 Subject: [PATCH] Add --start-delay option --- README.md | 11 ++++++++--- vrrp.c | 1 + vrrp.h | 3 +++ vrrp_options.c | 24 +++++++++++++++++++++++- vrrp_state.c | 10 +++++++++- vrrp_timer.h | 4 ++++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ff08204..faeb5a1 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,9 @@ Optional arguments: -t, --time delay Time interval between advertisements Seconds in VRRPv2 (default 1s), Centiseconds in VRRPv3 (default 100cs) + -T, --start-delay delay Use custom delay in INIT state + Seconds in VRRPv2 (default 1s), + Centiseconds in VRRPv3 (default 100cs) -P, --preempt on|off Switch preempt (default on) -r, --rfc version Specify protocol 'version' 2 (VRRPv2, RFC3768) by default, @@ -67,9 +70,11 @@ Optional arguments: -6, --ipv6 IPv6 support, (only in VRRPv3) -a, --auth pass Simple text password (only in VRRPv2) -f, --foreground Execute uvrrpd in foreground - -s, --script Path of hook script (default /etc/uvrrpd/uvrrpd-switch.sh) - -F --pidfile Create pid file 'name' - Default /var/run/uvrrp_${vrid}.pid + -s, --script Path of hook script (default /usr/local/sbin/vrrp-switch.sh) + -F --pidfile name Use alternate pid file 'name' + Default /run/uvrrp_${vrid}.pid + -C --control name Use alternate control file 'name' + Default /run/uvrrpd_ctrl.${vrid} -d, --debug -h, --help ``` diff --git a/vrrp.c b/vrrp.c index e3081d4..41f8031 100644 --- a/vrrp.c +++ b/vrrp.c @@ -63,6 +63,7 @@ void vrrp_init(struct vrrp *vrrp) /* timers */ vrrp->adv_int = 0; + vrrp->start_delay = 0; vrrp->master_adv_int = 0; vrrp_timer_clear(&vrrp->adv_timer); vrrp_timer_clear(&vrrp->masterdown_timer); diff --git a/vrrp.h b/vrrp.h index 3b7bea1..28f16d3 100644 --- a/vrrp.h +++ b/vrrp.h @@ -94,6 +94,9 @@ struct vrrp { */ uint16_t adv_int; + /* Start delay */ + uint16_t start_delay; + /* Master advertisement interval * only in VRRPv3 / rfc5798 */ diff --git a/vrrp_options.c b/vrrp_options.c index a5d5682..c3b9ec5 100644 --- a/vrrp_options.c +++ b/vrrp_options.c @@ -52,6 +52,9 @@ static void vrrp_usage(void) " -t, --time delay Time interval between advertisements\n" " Seconds in VRRPv2 (default 1s),\n" " Centiseconds in VRRPv3 (default 100cs)\n" + " -T, --start-delay delay Use custom delay in INIT state\n" + " Seconds in VRRPv2 (default 1s),\n" + " Centiseconds in VRRPv3 (default 100cs)\n" " -P, --preempt on|off Switch preempt (default on)\n" " -r, --rfc version Specify protocol 'version'\n" " 2 (VRRPv2, RFC3768) by default,\n" @@ -81,6 +84,7 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, {"interface", required_argument, 0, 'i'}, {"priority", required_argument, 0, 'p'}, {"time", required_argument, 0, 't'}, + {"start-delay", required_argument, 0, 'T'}, {"preempt", required_argument, 0, 'P'}, {"rfc", required_argument, 0, 'r'}, {"ipv6", no_argument, 0, '6'}, @@ -95,7 +99,7 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, }; while ((optc = - getopt_long(argc, argv, "v:i:p:t:P:r:6a:fs:F:C:dh", opts, + getopt_long(argc, argv, "v:i:p:t:T:P:r:6a:fs:F:C:dh", opts, NULL)) != EOF) { switch (optc) { @@ -164,6 +168,24 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, vrrp->adv_int = (uint16_t) opt; break; + /* start delay */ + case 'T': + err = mystrtoul(&opt, optarg, ADVINT_MAX); + if (err == -ERANGE) { + vrrp_usage(); + return -1; + } + if (err == -EINVAL) { + fprintf(stderr, + "Error parsing \"%s\" as a number\n", + optarg); + vrrp_usage(); + return err; + } + + vrrp->start_delay = (uint16_t) opt; + break; + /* preempt mode */ case 'P': if (matches(optarg, "on")) diff --git a/vrrp_state.c b/vrrp_state.c index 7bc5bf4..d3c8172 100644 --- a/vrrp_state.c +++ b/vrrp_state.c @@ -332,7 +332,15 @@ static int vrrp_state_goto_backup(struct vrrp *vrrp, struct vrrp_net *vnet) /* clear adv timer && set masterdown_timer */ vrrp_timer_clear(&vrrp->adv_timer); - VRRP_SET_MASTERDOWN_TIMER(vrrp); + if ((previous_state == INIT) && (vrrp->start_delay != 0)) { + log_notice("vrid %d :: applying start_delay %d%s", + vrrp->vrid, vrrp->start_delay, + (vrrp->version == 3 ? "cs":"s") + ); + VRRP_SET_STARTDELAY_TIMER(vrrp); + } + else + VRRP_SET_MASTERDOWN_TIMER(vrrp); log_debug("%d %d", vrrp->master_adv_int, 3 * vrrp->master_adv_int + SKEW_TIME(vrrp)); diff --git a/vrrp_timer.h b/vrrp_timer.h index 382f50f..536a862 100644 --- a/vrrp_timer.h +++ b/vrrp_timer.h @@ -70,5 +70,9 @@ int vrrp_timer_is_expired(struct vrrp_timer *timer); (v->version == 3 ? 0:SKEW_TIME( v )), \ (v->version == 3 ? SKEW_TIME( v ):0)) +#define VRRP_SET_STARTDELAY_TIMER( v ) \ + vrrp_timer_set(&v->masterdown_timer, \ + (v->version == 3 ? 0:v->start_delay), \ + (v->version == 3 ? v->start_delay:0)) #endif /* _VRRP_TIMER_H_ */