* keepalived-0.7.1 released.
* Fixed a MISC_CHECK issue when registering next timer checker. Must
register a new timer thread before forking process. This imply for
the user the extra script call must not execute in more than
checker->vs->delay_loop.
* Extented the ipfwwrapper (for LVS kernel 2.2) to not set ipchains
rules if nat_mask is not specified in the configuration file.
* VRRP : Added support to delayed gratuitous ARP send. When one instance
enter to MASTER state a timer thread is registered. The default delay
is 5secs. This delay is configurable per vrrp instance and handle the
'garp_master_delay' keyword. This delay refer to the delay after
MASTER state transition we want to launch gratuitous ARP.
* VRRP : Force health checker enable flag if VRRP framework is not
selected.
* VRRP : Review the gratuitous ARP helper function to only send
gratuitous ARP if VRRP VIPs are set.
* VRRP : Review the FSM to eliminate stalled flapping loop. The state
transition diagram implemented is :
+---------------+
+----------------| |----------------+
| | Fault | |
| +------------>| |<------------+ |
| | +---------------+ | |
| | | | |
| | V | |
| | +---------------+ | |
| | +--------->| |<---------+ | |
| | | | Initialize | | | |
| | | +-------| |-------+ | | |
| | | | +---------------+ | | | |
| | | | | | | |
V | | V V | | V
+---------------+ +---------------+
| |---------------------->| |
| Master | | Backup |
| |<----------------------| |
+---------------+ +---------------+
The state DUMMY_MASTER state has been removed since it is a fake.
* VRRP : In order to handle all possible state transition, a Transition
State Matrix design (TSM) has been added. This matrix defines
transition state handlers for VRRP sync group extension. The TSM
implemented is (cf: vrrp_scheduler.c for more informations) :
\ E | B | M | F |
S \ | | | |
------+-----+-----+-----+ Legend:
B | x 1 2 | B: VRRP BACKUP state
------+ | M: VRRP MASTER state
M | 3 x 4 | F: VRRP FAULT state
------+ | S: VRRP start state (before transition)
F | 5 6 x | E: VRRP end state (after transition)
------+-----------------+ [1..6]: Handler functions.
* VRRP : Set ms_down_timer to 3 * advert_int + TIMER_SKEW when leaving
MASTER state.
* VRRP : In MASTER state, when incoming advert match or FAULT state is
requested then force leaving MASTER state transition. (review the
previous election approach).
* VRRP : Optimized the leave FAULT state transition. Directly coded into
the FSM for speed up recovery or code readability.
* VRRP : Extended smtp notifier for BACKUP state. Review the MASTER state
notification to only notify when VIPs are set.
* some cosmetics patches.
* Adam Fletcher, <adamf@rovia.com> created the 'Keepalived+LVS NAT HOWTO'
+2002-09-17 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-0.7.1 released.
+ * Fixed a MISC_CHECK issue when registering next timer checker. Must
+ register a new timer thread before forking process. This imply for
+ the user the extra script call must not execute in more than
+ checker->vs->delay_loop.
+ * Extented the ipfwwrapper (for LVS kernel 2.2) to not set ipchains
+ rules if nat_mask is not specified in the configuration file.
+ * VRRP : Added support to delayed gratuitous ARP send. When one instance
+ enter to MASTER state a timer thread is registered. The default delay
+ is 5secs. This delay is configurable per vrrp instance and handle the
+ 'garp_master_delay' keyword. This delay refer to the delay after
+ MASTER state transition we want to launch gratuitous ARP.
+ * VRRP : Force health checker enable flag if VRRP framework is not
+ selected.
+ * VRRP : Review the gratuitous ARP helper function to only send
+ gratuitous ARP if VRRP VIPs are set.
+ * VRRP : Review the FSM to eliminate stalled flapping loop. The state
+ transition diagram implemented is :
+ +---------------+
+ +----------------| |----------------+
+ | | Fault | |
+ | +------------>| |<------------+ |
+ | | +---------------+ | |
+ | | | | |
+ | | V | |
+ | | +---------------+ | |
+ | | +--------->| |<---------+ | |
+ | | | | Initialize | | | |
+ | | | +-------| |-------+ | | |
+ | | | | +---------------+ | | | |
+ | | | | | | | |
+ V | | V V | | V
+ +---------------+ +---------------+
+ | |---------------------->| |
+ | Master | | Backup |
+ | |<----------------------| |
+ +---------------+ +---------------+
+
+ The state DUMMY_MASTER state has been removed since it is a fake.
+ * VRRP : In order to handle all possible state transition, a Transition
+ State Matrix design (TSM) has been added. This matrix defines
+ transition state handlers for VRRP sync group extension. The TSM
+ implemented is (cf: vrrp_scheduler.c for more informations) :
+ \ E | B | M | F |
+ S \ | | | |
+ ------+-----+-----+-----+ Legend:
+ B | x 1 2 | B: VRRP BACKUP state
+ ------+ | M: VRRP MASTER state
+ M | 3 x 4 | F: VRRP FAULT state
+ ------+ | S: VRRP start state (before transition)
+ F | 5 6 x | E: VRRP end state (after transition)
+ ------+-----------------+ [1..6]: Handler functions.
+ * VRRP : Set ms_down_timer to 3 * advert_int + TIMER_SKEW when leaving
+ MASTER state.
+ * VRRP : In MASTER state, when incoming advert match or FAULT state is
+ requested then force leaving MASTER state transition. (review the
+ previous election approach).
+ * VRRP : Optimized the leave FAULT state transition. Directly coded into
+ the FSM for speed up recovery or code readability.
+ * VRRP : Extended smtp notifier for BACKUP state. Review the MASTER state
+ notification to only notify when VIPs are set.
+ * some cosmetics patches.
+ * Adam Fletcher, <adamf@rovia.com> created the 'Keepalived+LVS NAT HOWTO'
+
2002-08-05 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.6.10 released.
* Fixed a faked flag during VRRP VIP set. Updated the IP address set flag to reflect
considering keepalived, please refer to the keepalived homepage into the
documentation section.
- http://keepalived.sourceforge.net
+ http://www.keepalived.org
Have fun with it !
Summary: Generic HA monitor build upon VRRP and services poller, strongly recommanded for LVS HA.
Name: keepalived
Packager: Christophe Varoqui, <christophe.varoqui@free.fr>
-Version: 0.6.10
+Version: 0.7.1
Release: 1
-Source: http://www.keepalived.org/software/keepalived-0.6.10.tar.gz
+Source: http://www.keepalived.org/software/keepalived-0.7.1.tar.gz
Copyright: GPL
Group: Utilities/File
BuildRoot: /tmp/%{name}-%{version}.build
%prep
rm -rf %{buildroot}
-%setup -n keepalived-0.6.10
+%setup -n keepalived-0.7.1
%build
./configure --prefix=%{buildroot} --exec-prefix=%{buildroot} --sysconfdir=%{buildroot}/etc
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: main.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: data.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
if (vrrp->lvs_syncd_if)
syslog(LOG_INFO, " Runing LVS sync daemon on interface = %s",
vrrp->lvs_syncd_if);
+ if (vrrp->garp_delay)
+ syslog(LOG_INFO, " Gratuitous ARP delay = %d", vrrp->garp_delay);
syslog(LOG_INFO, " Virtual Router ID = %d", vrrp->vrid);
syslog(LOG_INFO, " Priority = %d", vrrp->priority);
syslog(LOG_INFO, " Advert interval = %dsec",
#ifdef _KRNL_2_2_
case 0:
syslog(LOG_INFO, " lb_kind = NAT");
- syslog(LOG_INFO, " nat mask = %s", inet_ntop2(vs->nat_mask));
+ if (vs->nat_mask)
+ syslog(LOG_INFO, " nat mask = %s", inet_ntop2(vs->nat_mask));
break;
case IP_MASQ_F_VS_DROUTE:
syslog(LOG_INFO, " lb_kind = DR");
* Part: Layer4 checkers handling. Register worker threads &
* upper layer checkers.
*
- * Version: $Id: layer4.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: layer4.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: list.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: main.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: Memory management framework. This framework is used to
* find any memory leak.
*
- * Version: $Id: memory.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: memory.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: parser.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: parser.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
vrrp->lvs_syncd_if = set_value(strvec);
}
static void
+vrrp_garp_delay_handler(vector strvec)
+{
+ vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ vrrp->garp_delay = atoi(VECTOR_SLOT(strvec, 1));
+}
+static void
vrrp_auth_type_handler(vector strvec)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
install_keyword("certificate", &sslcert_handler);
install_keyword("key", &sslkey_handler);
+#ifdef _WITH_VRRP_
/* VRRP Instance mapping */
install_keyword_root("vrrp_sync_group", &vrrp_sync_group_handler);
install_keyword("group", &vrrp_group_handler);
install_keyword("notify_fault", &vrrp_notify_fault_handler);
install_keyword("smtp_alert", &vrrp_smtp_handler);
install_keyword("lvs_sync_daemon_interface", &vrrp_lvs_syncd_handler);
+ install_keyword("garp_master_delay", &vrrp_garp_delay_handler);
install_keyword("authentication", NULL);
install_sublevel();
install_keyword("auth_type", &vrrp_auth_type_handler);
install_keyword("auth_pass", &vrrp_auth_pass_handler);
install_sublevel_end();
+#endif
#ifdef _WITH_LVS_
/* Real server group mapping */
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: pidfile.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: scheduler.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* using the smtp protocol according to the RFC 821. A non blocking
* timeouted connection is used to handle smtp protocol.
*
- * Version: $Id: smtp.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: smtp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: timer.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: utils.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vector.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
INCLUDES = -I../include
CFLAGS = @CFLAGS@ $(INCLUDES) \
-Wall -Wunused -Wstrict-prototypes
-DEFS = -D$(KERNEL) -D@IPVS_SUPPORT@ -D@IPVS_SYNCD@ @DFLAGS@ $(CIFLAGS)
+DEFS = -D$(KERNEL) -D@IPVS_SUPPORT@ -D@IPVS_SYNCD@ -D@VRRP_SUPPORT@ @DFLAGS@ $(CIFLAGS)
COMPILE = $(CC) $(CFLAGS) $(DEFS)
OBJS = check_api.o check_tcp.o check_http.o check_ssl.o \
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_api.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
chk->rs = rs;
chk->data = data;
chk->enabled = (vs->vfwmark) ? 1 : 0;
+#ifdef _WITHOUT_VRRP_
+ chk->enabled = 1;
+#endif
/* queue the checker */
list_add(checkers_queue, chk);
*
* Part: CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
*
- * Version: $Id: check_ci.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_ci.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
*
* Part: WEB CHECK. Common HTTP/SSL checker primitives.
*
- * Version: $Id: check_http.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_http.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
return epilog(thread, 1, 1, 0) + 1;
}
}
- return epilog(thread, 0, 0, 0) + 1;
+ return epilog(thread, 1, 0, 0) + 1;
}
/* Asynchronous HTTP stream reader */
* Part: MISC CHECK. Perform a system call to run an extra
* system prog or script.
*
- * Version: $Id: check_misc.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_misc.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
return 0;
}
+ /* Register next timer checker */
+ thread_add_timer(thread->master, misc_check_thread, checker,
+ checker->vs->delay_loop);
+
/* Daemonization to not degrade our scheduling timer */
pid = fork();
}
}
- /* Register next timer checker */
- thread_add_timer(thread->master, misc_check_thread, checker,
- checker->vs->delay_loop);
-
exit(0);
}
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: check_ssl.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_ssl.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: TCP checker.
*
- * Version: $Id: check_tcp.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_tcp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
struct ip_fwuser ctl;
int ret = 1;
+ /* Exit if NAT mask is not specified */
+ if (!vs->nat_mask)
+ return IPFW_SUCCESS;
+
memset(&ctl, 0, sizeof (struct ip_fwuser));
/* Create the firewall MASQ rule */
* Part: IPVS Kernel wrapper. Use setsockopt call to add/remove
* server to/from the loadbalanced server pool.
*
- * Version: $Id: ipvswrapper.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $id: ipwrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_api.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: check_ci.c include file.
*
- * Version: $Id: check_ci.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_ci.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_http.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_misc.c include file.
*
- * Version: $Id: check_misc.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_misc.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_http.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_tcp.c include file.
*
- * Version: $Id: check_tcp.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: check_tcp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: daemon.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: data.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: layer4.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: list.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: main.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x00060a
-#define DATE_CODE 0x050802
+#define VERSION_CODE 0x000701
+#define DATE_CODE 0x110902
#define KEEPALIVED_VERSION(version) \
(version >> 16) & 0xFF, \
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: memory.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: parser.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: pidfile.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: scheduler.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: smtp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: timer.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: utils.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vector.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define VRRP_AUTH_AH 2 /* AH(IPSec) authentification - rfc2338.5.3.6 */
#define VRRP_ADVER_DFL 1 /* advert. interval (in sec) -- rfc2338.5.3.7 */
#define VRRP_PREEMPT_DFL 1 /* rfc2338.6.1.2.Preempt_Mode */
+#define VRRP_GARP_DELAY 5 /* Default delay to launch gratuitous arp */
/*
* parameters per vrrp sync group. A vrrp_sync_group is a set
* instance FSM & running on specific interface
* => eth0 for example.
*/
+ int garp_delay; /* Delay to launch gratuitous ARP */
int vrid; /* virtual id. from 1(!) to 255 */
int priority; /* priority value */
int naddr; /* number of ip addresses */
#define VRRP_STATE_MAST 2 /* rfc2338.6.4.3 */
#define VRRP_STATE_FAULT 3 /* internal */
#define VRRP_STATE_GOTO_MASTER 4 /* internal */
-#define VRRP_STATE_DUMMY_MAST 5 /* internal */
-#define VRRP_STATE_LEAVE_MASTER 6 /* internal */
-#define VRRP_STATE_GOTO_DUMMY_MAST 97 /* internal */
+#define VRRP_STATE_LEAVE_MASTER 5 /* internal */
#define VRRP_STATE_GOTO_FAULT 98 /* internal */
#define VRRP_DISPATCHER 99 /* internal */
#define VRRP_MCAST_RETRY 10 /* internal */
-#define VRRP_MAX_FSM_STATE 5 /* internal */
+#define VRRP_MAX_FSM_STATE 4 /* internal */
/* VRRP packet handling */
#define VRRP_PACKET_OK 0
extern int vrrp_send_adv(vrrp_rt * vrrp, int prio);
extern int vrrp_state_fault_rx(vrrp_rt * vrrp, char *buf, int buflen);
extern int vrrp_state_master_rx(vrrp_rt * vrrp, char *buf, int buflen);
-extern void vrrp_state_master_tx(vrrp_rt * vrrp, const int prio);
+extern int vrrp_state_master_tx(vrrp_rt * vrrp, const int prio);
extern void vrrp_state_backup(vrrp_rt * vrrp, char *buf, int buflen);
extern void vrrp_state_goto_master(vrrp_rt * vrrp);
extern void vrrp_state_leave_master(vrrp_rt * vrrp);
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_notify.c include file.
*
- * Version: $Id: vrrp_notify.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_notify.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
} while (0)
#define VRRP_FSM_READ(V, B, L) \
-do { \
+do { \
if ((*(VRRP_FSM[(V)->state].read))) \
(*(VRRP_FSM[(V)->state].read)) (V, B, L); \
} while (0)
+/* VRRP TSM Macro */
+#define VRRP_TSM_HANDLE(S,V) \
+do { \
+ if ((V)->sync && \
+ S != VRRP_STATE_GOTO_MASTER) \
+ if ((*(VRRP_TSM[S][(V)->state].handler))) \
+ (*(VRRP_TSM[S][(V)->state].handler)) (V); \
+} while (0)
+
/* extern prototypes */
extern int vrrp_read_dispatcher_thread(thread * thread);
*
* Part: vrrp_sync.c include file.
*
- * Version: $Id: vrrp_sync.h,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_sync.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* local include */
#include "vrrp.h"
+/* TSM size */
+#define VRRP_MAX_TSM_STATE 3
+
/* MACRO definition */
#define GROUP_STATE(G) ((G)->state)
#define GROUP_NAME(G) ((G)->gname)
/* extern prototypes */
+extern void vrrp_init_instance_sands(vrrp_rt * vrrp);
extern vrrp_sgroup *vrrp_get_sync_group(char *iname);
extern int vrrp_sync_group_up(vrrp_sgroup * vgroup);
extern int vrrp_sync_leave_fault(vrrp_rt * vrrp);
-extern void vrrp_sync_read_to(vrrp_rt * vrrp, int prev_state);
-extern void vrrp_sync_read(vrrp_rt * vrrp, int prev_state);
+extern void vrrp_sync_backup(vrrp_rt *);
+extern void vrrp_sync_master(vrrp_rt *);
+extern void vrrp_sync_master_election(vrrp_rt *);
+extern void vrrp_sync_fault(vrrp_rt *);
#endif
delay_loop 6
lb_algo rr
lb_kind NAT
- nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc
}
- connect_port 443
+ connect_port 444
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
vrrp_instance VI_1 {
state MASTER
interface eth0
+ garp_master_delay 10
smtp_alert
virtual_router_id 51
priority 100
advert_int 1
authentication {
- auth_type AH
+ auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
priority 100
advert_int 1
authentication {
- auth_type AH
+ auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
+++ /dev/null
-# Generated automatically from Makefile.in by configure.
-# Makefile
-#
-# Keepalived OpenSource project.
-#
-# Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
-
-CC = gcc
-INCLUDES = -I../include
-CFLAGS = -g -O2 -I/usr/src/linux/include $(INCLUDES) \
- -Wall -Wunused -Wstrict-prototypes
-DEFS = -D_KRNL_2_4_ -D_WITH_LVS_ -D_WITHOUT_IPVS_SYNCD_
-COMPILE = $(CC) $(CFLAGS) $(DEFS)
-
-OBJS = vrrp.o vrrp_notify.o vrrp_scheduler.o vrrp_sync.o \
- vrrp_netlink.o vrrp_if.o vrrp_ipaddress.o vrrp_ipsecah.o
-HEADERS = $(OBJS:.o=.h)
-
-.c.o:
- $(COMPILE) -c $<
-
-all: $(OBJS)
-
-clean:
- rm -f *.a *.o *~
-
-distclean: clean
- rm -f Makefile
-
-vrrp.o: vrrp.c ../include/vrrp.h ../include/vrrp_scheduler.h \
- ../include/vrrp_notify.h ../include/ipvswrapper.h ../include/memory.h \
- ../include/list.h ../include/data.h
-vrrp_notify.o: vrrp_notify.c ../include/vrrp_notify.h ../include/memory.h
-vrrp_scheduler.o: vrrp_scheduler.c ../include/vrrp_scheduler.h \
- ../include/vrrp_ipsecah.h ../include/vrrp_if.h ../include/vrrp.h \
- ../include/vrrp_sync.h ../include/vrrp_notify.h ../include/ipvswrapper.h \
- ../include/memory.h ../include/list.h ../include/data.h ../include/smtp.h
-vrrp_sync.o: vrrp_sync.c ../include/vrrp_sync.h ../include/vrrp_if.h \
- ../include/vrrp_notify.h ../include/data.h
-vrrp_netlink.o: vrrp_netlink.c ../include/vrrp_netlink.h ../include/check_api.h \
- ../include/vrrp_if.h ../include/memory.h ../include/scheduler.h \
- ../include/utils.h
-vrrp_if.o: vrrp_if.c ../include/vrrp_if.h ../include/vrrp_netlink.h \
- ../include/scheduler.h ../include/data.h ../include/memory.h \
- ../include/utils.h
-vrrp_ipaddress.o: vrrp_ipaddress.c ../include/vrrp_ipaddress.h \
- ../include/vrrp_netlink.h ../include/utils.h
-vrrp_ipsecah.o: vrrp_ipsecah.c ../include/vrrp_ipsecah.h
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
{
int i, j;
+ /* Only send gratuitous ARP if VIP are set */
+ if (!VRRP_VIP_ISSET(vrrp))
+ return;
+
/* send gratuitous arp for each virtual ip */
syslog(LOG_INFO, "VRRP_Instance(%s) Sending gratuitous ARP on %s",
vrrp->iname, IF_NAME(vrrp->ifp));
*/
vrrp_send_adv(vrrp, vrrp->priority);
- if (vrrp->wantstate == VRRP_STATE_MAST) {
- vrrp->state = VRRP_STATE_MAST;
- syslog(LOG_INFO, "VRRP_Instance(%s) Transition to MASTER STATE",
- vrrp->iname);
- } else {
- vrrp->state = VRRP_STATE_DUMMY_MAST;
- syslog(LOG_INFO,
- "VRRP_Instance(%s) Transition to DUMMY_MASTER STATE",
- vrrp->iname);
- }
+ vrrp->state = VRRP_STATE_MAST;
+ syslog(LOG_INFO, "VRRP_Instance(%s) Transition to MASTER STATE",
+ vrrp->iname);
}
/* leaving master state */
notify_instance_exec(vrrp, VRRP_STATE_FAULT);
break;
}
+
+ /* Set the down timer */
+ vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
}
/* BACKUP state processing */
}
/* MASTER state processing */
-void
+int
vrrp_state_master_tx(vrrp_rt * vrrp, const int prio)
{
+ int ret = 0;
+
if (!VRRP_VIP_ISSET(vrrp)) {
syslog(LOG_INFO, "VRRP_Instance(%s) Entering MASTER STATE",
vrrp->iname);
vrrp_state_become_master(vrrp);
+ ret = 1;
}
vrrp_send_adv(vrrp,
(prio ==
VRRP_PRIO_OWNER) ? VRRP_PRIO_OWNER : vrrp->priority);
+ return ret;
}
int
vrrp->iname);
vrrp->ms_down_timer =
3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
+ vrrp->wantstate = VRRP_STATE_BACK;
vrrp->state = VRRP_STATE_BACK;
return 1;
}
vrrp = ELEMENT_DATA(e);
/* remove VIPs */
- if (vrrp->state == VRRP_STATE_MAST ||
- vrrp->state == VRRP_STATE_DUMMY_MAST)
+ if (vrrp->state == VRRP_STATE_MAST)
vrrp_restore_interface(vrrp, 1);
#ifdef _HAVE_IPVS_SYNCD_
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* authentication data encryption using HMAC MD5 according to
* RFCs 2085 & 2104.
*
- * Version: $Id: vrrp_ipsecah.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: VRRP state transition notification scripts handling.
*
- * Version: $Id: vrrp_notify.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_notify.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
extern thread_master *master;
extern data *conf_data;
-/* VRRP FSM definition */
+/* VRRP FSM (Finite State Machine) design.
+ *
+ * The state transition diagram implemented is :
+ *
+ * +---------------+
+ * +----------------| |----------------+
+ * | | Fault | |
+ * | +------------>| |<------------+ |
+ * | | +---------------+ | |
+ * | | | | |
+ * | | V | |
+ * | | +---------------+ | |
+ * | | +--------->| |<---------+ | |
+ * | | | | Initialize | | | |
+ * | | | +-------| |-------+ | | |
+ * | | | | +---------------+ | | | |
+ * | | | | | | | |
+ * V | | V V | | V
+ * +---------------+ +---------------+
+ * | |---------------------->| |
+ * | Master | | Backup |
+ * | |<----------------------| |
+ * +---------------+ +---------------+
+ */
static void vrrp_backup(vrrp_rt *, char *, int);
static void vrrp_leave_master(vrrp_rt *, char *, int);
static void vrrp_leave_fault(vrrp_rt *, char *, int);
static void vrrp_become_master(vrrp_rt *, char *, int);
-static void vrrp_leave_dummy_master(vrrp_rt *, char *, int);
static void vrrp_goto_master(vrrp_rt *);
static void vrrp_master(vrrp_rt *);
static void vrrp_fault(vrrp_rt *);
-static void vrrp_dummy_master(vrrp_rt *);
struct {
void (*read) (vrrp_rt *, char *, int);
void (*read_to) (vrrp_rt *);
-} VRRP_FSM[VRRP_MAX_FSM_STATE + 1] = {
+} VRRP_FSM[VRRP_MAX_FSM_STATE + 1] =
+{
/* Stream Read Handlers | Stream Read_to handlers *
*------------------------------+------------------------------*/
{NULL, NULL},
{vrrp_backup, vrrp_goto_master}, /* BACKUP */
{vrrp_leave_master, vrrp_master}, /* MASTER */
{vrrp_leave_fault, vrrp_fault}, /* FAULT */
- {vrrp_become_master, vrrp_goto_master}, /* GOTO_MASTER */
- {vrrp_leave_dummy_master, vrrp_dummy_master} /* DUMMY_MASTER */
+ {vrrp_become_master, vrrp_goto_master} /* GOTO_MASTER */
};
+/* VRRP TSM (Transition State Matrix) design.
+ *
+ * Introducing the Synchronization extension to VRRP
+ * protocol, introduce the need for a transition machinery.
+ * This mecanism can be designed using a diagonal matrix.
+ * We call this matrix the VRRP TSM:
+ *
+ * \ E | B | M | F |
+ * S \ | | | |
+ * ------+-----+-----+-----+ Legend:
+ * B | x 1 2 | B: VRRP BACKUP state
+ * ------+ | M: VRRP MASTER state
+ * M | 3 x 4 | F: VRRP FAULT state
+ * ------+ | S: VRRP start state (before transition)
+ * F | 5 6 x | E: VRRP end state (after transition)
+ * ------+-----------------+ [1..6]: Handler functions.
+ *
+ * So we have have to implement n(n-1) handlers in order to deal with
+ * all transitions possible. This matrix defines the maximum handlers
+ * to implement for having the most time optimized transition machine.
+ * For example:
+ * . The handler (1) will sync all the BACKUP VRRP instances of a
+ * group to MASTER state => we will call it vrrp_sync_master.
+ * .... and so on for all other state ....
+ *
+ * This matrix is the strict implementation way. For readability and
+ * performance we have implemented some handlers directly into the VRRP
+ * FSM. For instance the handlers (5) & (6) are directly into the VRRP
+ * FSM since it will speed up convergence to init state.
+ * Additionnaly, we have implemented some other handlers into the matrix
+ * in order to speed up group synchronization takeover. For instance
+ * transitions :
+ * o B->B: To catch wantstate MASTER transition to force sync group
+ * to this transition state too.
+ * o F->F: To speed up FAULT state transition if group is not already
+ * synced to FAULT state.
+ */
+struct {
+ void (*handler) (vrrp_rt *);
+} VRRP_TSM[VRRP_MAX_TSM_STATE + 1][VRRP_MAX_TSM_STATE + 1] =
+{
+ { {NULL}, {NULL}, {NULL}, {NULL} },
+ { {NULL}, {vrrp_sync_master_election}, {vrrp_sync_master}, {vrrp_sync_fault} },
+ { {NULL}, {vrrp_sync_backup}, {NULL}, {vrrp_sync_fault} },
+ { {NULL}, {NULL}, {NULL}, {vrrp_sync_fault} }
+};
+
+
/* SMTP alert notifier */
static void
vrrp_smtp_notifier(vrrp_rt * vrrp)
{
- if (vrrp->smtp_alert)
- smtp_alert(master, NULL, vrrp, "Transition to MASTER state",
- "=> VRRP Instance is now owning VRRP VIPs <=\n\n");
+ if (vrrp->smtp_alert) {
+ if (vrrp->state == VRRP_STATE_MAST)
+ smtp_alert(master, NULL, vrrp,
+ "Entering MASTER state",
+ "=> VRRP Instance is now owning VRRP VIPs <=\n\n");
+ if (vrrp->state == VRRP_STATE_BACK)
+ smtp_alert(master, NULL, vrrp,
+ "Entering BACKUP state",
+ "=> VRRP Instance is nolonger owning VRRP VIPs <=\n\n");
+ }
}
/*
ipvs_syncd_cmd(IPVS_STARTDAEMON,
vrrp->lvs_syncd_if, IPVS_BACKUP);
#endif
+ syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE",
+ vrrp->iname);
vrrp->state = VRRP_STATE_BACK;
}
}
}
static void
-vrrp_init_instance_sands(vrrp_rt * vrrp)
-{
- TIMEVAL timer;
-
- timer = timer_now();
-
- if (vrrp->state == VRRP_STATE_BACK || vrrp->state == VRRP_STATE_FAULT) {
- vrrp->sands.tv_sec = timer.tv_sec +
- vrrp->ms_down_timer / TIMER_HZ;
- vrrp->sands.tv_usec = timer.tv_usec +
- vrrp->ms_down_timer % TIMER_HZ;
- }
- if (vrrp->state == VRRP_STATE_GOTO_MASTER ||
- vrrp->state == VRRP_STATE_GOTO_DUMMY_MAST ||
- vrrp->state == VRRP_STATE_MAST ||
- vrrp->state == VRRP_STATE_DUMMY_MAST ||
- vrrp->state == VRRP_STATE_GOTO_FAULT) {
- vrrp->sands.tv_sec = timer.tv_sec + vrrp->adver_int / TIMER_HZ;
- vrrp->sands.tv_usec = timer.tv_usec;
- }
-}
-
-static void
vrrp_init_sands(list l)
{
vrrp_rt *vrrp;
/* Then jump to master state */
vrrp->wantstate = VRRP_STATE_MAST;
vrrp_state_goto_master(vrrp);
- vrrp_smtp_notifier(vrrp);
}
static void
vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
vrrp_state_leave_master(vrrp);
} else if (vrrp_state_master_rx(vrrp, vrrp_buffer, len)) {
- vrrp->wantstate = VRRP_STATE_BACK;
vrrp_state_leave_master(vrrp);
+ vrrp_smtp_notifier(vrrp);
}
}
vrrp_become_master(vrrp, vrrp_buffer, len);
}
} else {
- vrrp->state = VRRP_STATE_BACK;
+ if (vrrp->sync) {
+ if (vrrp_sync_leave_fault(vrrp)) {
+ syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE",
+ vrrp->iname);
+ vrrp->state = VRRP_STATE_BACK;
+ vrrp_smtp_notifier(vrrp);
+ }
+ } else {
+ syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE",
+ vrrp->iname);
+ vrrp->state = VRRP_STATE_BACK;
+ vrrp_smtp_notifier(vrrp);
+ }
}
}
static void
-vrrp_leave_dummy_master(vrrp_rt * vrrp, char *vrrp_buffer, int len)
-{
-/*
- vrrp_rt *vrrp_isync;
-
- if (vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_FAULT &&
- vrrp->wantstate == VRRP_STATE_GOTO_DUMMY_MAST) {
- vrrp->wantstate = VRRP_STATE_DUMMY_MAST;
- syslog(LOG_INFO, "VRRP_Instance(%s) leaving DUMMY MASTER state"
- , vrrp->iname);
- vrrp_state_leave_master(vrrp);
- }
-
- if (vrrp_isync->state != VRRP_STATE_FAULT) {
- switch (vrrp_isync->state) {
- case VRRP_STATE_BACK:
- vrrp->state = VRRP_STATE_BACK;
- break;
- case VRRP_STATE_MAST:
- vrrp_become_master(vrrp, vrrp_buffer, len);
- break;
- }
- }
- }
-*/
-}
-
-static void
vrrp_goto_master(vrrp_rt * vrrp)
{
if (!IF_ISUP(vrrp->ifp)) {
vrrp->ipsecah_counter->seq_number = 0;
}
- if (vrrp->wantstate != VRRP_STATE_GOTO_DUMMY_MAST)
- vrrp->wantstate = VRRP_STATE_MAST;
-
/* handle master state transition */
+ vrrp->wantstate = VRRP_STATE_MAST;
vrrp_state_goto_master(vrrp);
- vrrp_smtp_notifier(vrrp);
}
}
+/* Delayed gratuitous ARP thread */
+int
+vrrp_gratuitous_arp_thread(thread * thread)
+{
+ vrrp_rt *vrrp = THREAD_ARG(thread);
+
+ /* Simply broadcast the gratuitous ARP */
+ vrrp_send_gratuitous_arp(vrrp);
+
+ return 0;
+}
+
static void
vrrp_master(vrrp_rt * vrrp)
{
syslog(LOG_INFO, "VRRP_Instance(%s) Now in FAULT state",
vrrp->iname);
} else if (vrrp->state == VRRP_STATE_MAST) {
- /* send the VRRP advert */
- vrrp_state_master_tx(vrrp, 0);
+ /*
+ * Send the VRRP advert.
+ * If we catch the master transition
+ * <=> vrrp_state_master_tx(...) = 1
+ * register a gratuitous arp thread delayed to 5 secs.
+ */
+ if (vrrp_state_master_tx(vrrp, 0)) {
+ thread_add_timer(master, vrrp_gratuitous_arp_thread,
+ vrrp,
+ (vrrp->garp_delay) ?
+ vrrp->garp_delay : VRRP_GARP_DELAY);
+ vrrp_smtp_notifier(vrrp);
+ }
}
}
/* Otherwise, we transit to init state */
if (vrrp->init_state == VRRP_STATE_BACK)
vrrp->state = VRRP_STATE_BACK;
- else {
+ else
vrrp_goto_master(vrrp);
- vrrp_smtp_notifier(vrrp);
- }
- }
-}
-
-static void
-vrrp_dummy_master(vrrp_rt * vrrp)
-{
- /* Check if interface we are running on is UP */
- if (!IF_ISUP(vrrp->ifp))
- vrrp->wantstate = VRRP_STATE_GOTO_FAULT;
-
- if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT) {
- vrrp->ms_down_timer =
- 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
-
- /* handle backup state transition */
- vrrp_state_leave_master(vrrp);
- } else {
- /* send the VRRP advert */
- vrrp_state_master_tx(vrrp, 0);
}
}
VRRP_FSM_READ_TO(vrrp);
/* handle instance synchronization */
- vrrp_sync_read_to(vrrp, prev_state);
+// printf("Send [%s] TSM transtition : [%d,%d] Wantstate = [%d]\n"
+// , vrrp->iname
+// , prev_state
+// , vrrp->state
+// , vrrp->wantstate);
+ VRRP_TSM_HANDLE(prev_state, vrrp);
/*
* We are sure the instance exist. So we can
VRRP_FSM_READ(vrrp, vrrp_buffer, len);
/* handle instance synchronization */
- vrrp_sync_read(vrrp, prev_state);
+// printf("Read [%s] TSM transtition : [%d,%d] Wantstate = [%d]\n"
+// , vrrp->iname
+// , prev_state
+// , vrrp->state
+// , vrrp->wantstate);
+ VRRP_TSM_HANDLE(prev_state, vrrp);
/*
* Refresh sands only if found matching instance.
/* Dispatcher state handler */
if (thread->type == THREAD_READ_TIMEOUT)
fd = vrrp_dispatcher_read_to(thread->u.fd);
- else if (thread->arg)
+ else if (thread->arg) {
fd = vrrp_dispatcher_read_to(-1);
- else
+ } else
fd = vrrp_dispatcher_read(thread->u.fd);
/* register next dispatcher thread */
*
* Part: VRRP synchronization framework.
*
- * Version: $Id: vrrp_sync.c,v 0.6.10 2002/08/06 02:18:05 acassen Exp $
+ * Version: $Id: vrrp_sync.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* extern global vars */
extern data *conf_data;
+/* Compute the new instance sands */
+void
+vrrp_init_instance_sands(vrrp_rt * vrrp)
+{
+ TIMEVAL timer;
+
+ timer = timer_now();
+
+ if (vrrp->state == VRRP_STATE_BACK || vrrp->state == VRRP_STATE_FAULT) {
+ vrrp->sands.tv_sec = timer.tv_sec + vrrp->ms_down_timer / TIMER_HZ;
+ vrrp->sands.tv_usec = timer.tv_usec + vrrp->ms_down_timer % TIMER_HZ;
+ }
+ if (vrrp->state == VRRP_STATE_GOTO_MASTER ||
+ vrrp->state == VRRP_STATE_MAST ||
+ vrrp->state == VRRP_STATE_GOTO_FAULT) {
+ vrrp->sands.tv_sec = timer.tv_sec + vrrp->adver_int / TIMER_HZ;
+ vrrp->sands.tv_usec = timer.tv_usec;
+ }
+}
+
/* return the first group found for a specific instance */
vrrp_sgroup *
vrrp_get_sync_group(char *iname)
return 0;
}
-static void
+void
+vrrp_sync_master_election(vrrp_rt * vrrp)
+{
+ int i;
+ char *str;
+ vrrp_rt *isync;
+ vrrp_sgroup *vgroup = vrrp->sync;
+
+ if (vrrp->wantstate != VRRP_STATE_GOTO_MASTER)
+ return;
+ if (GROUP_STATE(vrrp->sync) == VRRP_STATE_FAULT)
+ return;
+
+ syslog(LOG_INFO, "VRRP_Group(%s) Transition to MASTER state",
+ GROUP_NAME(vrrp->sync));
+
+ for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+ str = VECTOR_SLOT(vgroup->iname, i);
+ isync = vrrp_get_instance(str);
+ if (isync != vrrp)
+ isync->wantstate = VRRP_STATE_GOTO_MASTER;
+
+ /* Force a new protocol master election */
+ syslog(LOG_INFO,
+ "VRRP_Instance(%s) forcing a new MASTER election",
+ isync->iname);
+ vrrp_send_adv(isync, isync->priority);
+ }
+ vgroup->state = VRRP_STATE_MAST;
+ notify_group_exec(vgroup, VRRP_STATE_MAST);
+}
+
+void
vrrp_sync_backup(vrrp_rt * vrrp)
{
int i;
vrrp_rt *isync;
vrrp_sgroup *vgroup = vrrp->sync;
+ if (GROUP_STATE(vrrp->sync) != VRRP_STATE_MAST)
+ return;
+
syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to BACKUP state",
GROUP_NAME(vrrp->sync));
for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
str = VECTOR_SLOT(vgroup->iname, i);
isync = vrrp_get_instance(str);
- if (isync != vrrp)
+ if (isync != vrrp) {
isync->wantstate = VRRP_STATE_BACK;
+ vrrp_state_leave_master(isync);
+ vrrp_init_instance_sands(isync);
+ }
}
vgroup->state = VRRP_STATE_BACK;
notify_group_exec(vgroup, VRRP_STATE_BACK);
}
-static void
-vrrp_sync_master_to(vrrp_rt * vrrp)
+void
+vrrp_sync_master(vrrp_rt * vrrp)
{
int i;
char *str;
vrrp_rt *isync;
vrrp_sgroup *vgroup = vrrp->sync;
+ if (GROUP_STATE(vrrp->sync) != VRRP_STATE_BACK)
+ return;
+
syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to MASTER state",
GROUP_NAME(vrrp->sync));
/* Send the higher priority advert on all synced instances */
if (isync != vrrp) {
- syslog(LOG_INFO,
- "VRRP_Instance(%s) sending OWNER advert",
- isync->iname);
- vrrp_state_master_tx(isync, VRRP_PRIO_OWNER);
- isync->state = VRRP_STATE_MAST;
+ isync->wantstate = VRRP_STATE_MAST;
+ vrrp_state_goto_master(isync);
+ vrrp_init_instance_sands(isync);
}
}
vgroup->state = VRRP_STATE_MAST;
notify_group_exec(vgroup, VRRP_STATE_MAST);
}
-static void
-vrrp_sync_fault_to(vrrp_rt * vrrp)
+void
+vrrp_sync_fault(vrrp_rt * vrrp)
{
int i;
char *str;
vrrp_rt *isync;
vrrp_sgroup *vgroup = vrrp->sync;
+ if (GROUP_STATE(vrrp->sync) == VRRP_STATE_FAULT)
+ return;
+
syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to FAULT state",
GROUP_NAME(vrrp->sync));
* => by default ms_down_timer is set to 3secs.
* => Takeover will be less than 3secs !
*/
- if (isync != vrrp)
+ if (isync != vrrp) {
if (isync->state == VRRP_STATE_MAST)
isync->wantstate = VRRP_STATE_GOTO_FAULT;
+ if (isync->state == VRRP_STATE_BACK)
+ isync->state = VRRP_STATE_FAULT;
+ }
}
vgroup->state = VRRP_STATE_FAULT;
notify_group_exec(vgroup, VRRP_STATE_FAULT);
}
-
-static void
-vrrp_sync_dmaster_to(vrrp_rt * vrrp)
-{
- int i;
- char *str;
- vrrp_rt *isync;
- vrrp_sgroup *vgroup = vrrp->sync;
-
- for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
- str = VECTOR_SLOT(vgroup->iname, i);
- isync = vrrp_get_instance(str);
- if (isync != vrrp) {
- if (isync->state == VRRP_STATE_FAULT) {
- syslog(LOG_INFO,
- "VRRP_Instance(%s) Transition to DUMMY MASTER",
- isync->iname);
- isync->wantstate = VRRP_STATE_GOTO_DUMMY_MAST;
- }
- }
- }
- vgroup->state = VRRP_STATE_DUMMY_MAST;
-}
-
-/* Read TimeOut synchronization handler */
-void
-vrrp_sync_read_to(vrrp_rt * vrrp, int prev_state)
-{
- /* Nothing to sync */
- if (!vrrp->sync)
- return;
-
- /* Sync the group instance to MASTER state */
- if (prev_state == VRRP_STATE_BACK && vrrp->state == VRRP_STATE_MAST)
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_BACK)
- vrrp_sync_master_to(vrrp);
-
- /* sync the group instance to FAULT state */
- if (prev_state == VRRP_STATE_MAST && vrrp->state == VRRP_STATE_FAULT)
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
- vrrp_sync_fault_to(vrrp);
-
- /*
- * Break a MASTER/BACKUP state loop after sync instance
- * FAULT state transition.
- * => We doesn't receive remote MASTER adverts.
- * => Emulate a DUMMY master to break the loop.
- */
- if (prev_state == VRRP_STATE_MAST && vrrp->state == VRRP_STATE_BACK)
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_FAULT)
- vrrp_sync_dmaster_to(vrrp);
-
- /* previous state symetry */
- if (vrrp->state == VRRP_STATE_DUMMY_MAST)
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
- vrrp->state = VRRP_STATE_MAST;
-}
-
-/* Read TimeOut synchronization handler */
-void
-vrrp_sync_read(vrrp_rt * vrrp, int prev_state)
-{
- /* Nothing to sync */
- if (!vrrp->sync)
- return;
-
- /* sync the group instance to BACKUP state */
- if (prev_state == VRRP_STATE_MAST && vrrp->state == VRRP_STATE_BACK)
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
- vrrp_sync_backup(vrrp);
-
- /*
- * Handle wanted transition to MASTER state.
- * When Instance not in FAULT state, we received a remote
- * lower priotity advert => Force a new VRRP election.
- */
- if (vrrp->state == VRRP_STATE_BACK &&
- vrrp->wantstate == VRRP_STATE_GOTO_MASTER) {
- if (GROUP_STATE(vrrp->sync) != VRRP_STATE_FAULT) {
- /* Force a new protocol master election */
- syslog(LOG_INFO,
- "VRRP_Instance(%s) forcing a new MASTER election",
- vrrp->iname);
- vrrp_send_adv(vrrp, vrrp->priority);
- }
- }
-}