* keepalived-0.6.1 released.
* Aneesh Kumar, <aneesh.kumar@digital.com> and I added support to
Cluster Infrastructure checkers. Providing HA-LVS for their cluster
project (http://ci-linux.sourceforge.net/). The new checker added
provide a derivation to the internal CI healthcheck mechanism.
* Enhanced the Kernel netlink reflector to drive global healthcheckers
activity. The policy implemented here is : If healthchecker is performing
test on a service that belong to a VIP not owned by the director, then
the healthchecker is suspended. This suspend/active state is particulary
usefull if runing VRRP for HA => That way the backup LVS will not charge
the realserver pool since LVS VIP is owned by master LVS.
* Cosmetics patches into the vector lib.
* VRRP : Rewrote the previous VRRP synchronization instance policy.
Created a new config block called "vrrp_sync_group" that define VRRP
instances synchronization dependences. That way we replace the previous
"by-pair" sync approach by this "by-group" approach. This can be useefull
for firewall HA with many NICs. Created a dedicated framework to speed up
takeover synchronization.
* VRRP : Added support to CIDR notation for VRRP VIPs definitions
=> VRRP VIPs definition like a.b.c.d/e. By default "e" value is set to 32.
* VRRP : Added support to multicast source IP address selection
=> "mcast_src_ip" keyword. Can be usefull for strongly filtered env.
The mcast group subscription is done using the NIC default IP after this
mcast_src_ip is used if specified.
* VRRP : Enhanced the link media failure detection. Added support to the
new kernel SIOCETHTOOL probing for ETHTOOL_GLINK command. New drivers
use this ETHTOOL interface to report link failure activity. During
bootstrap a probe is done to determine the proper polling method to
use for link media failure detection. The policy used is : probe for
SIOCGMIIREG if not supported then try SIOCETHTOOL GLINK probe, otherwise
use a ioctl SIOCGIFFLAGS polling function mirroring kernel NIC flags to
localy reflected representation.
* Ramon Kagan, <rkagan@YorkU.CA> and I updated the UserGuide.pdf.
+2002-06-13 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-0.6.1 released.
+ * Aneesh Kumar, <aneesh.kumar@digital.com> and I added support to
+ Cluster Infrastructure checkers. Providing HA-LVS for their cluster
+ project (http://ci-linux.sourceforge.net/). The new checker added
+ provide a derivation to the internal CI healthcheck mechanism.
+ * Enhanced the Kernel netlink reflector to drive global healthcheckers
+ activity. The policy implemented here is : If healthchecker is performing
+ test on a service that belong to a VIP not owned by the director, then
+ the healthchecker is suspended. This suspend/active state is particulary
+ usefull if runing VRRP for HA => That way the backup LVS will not charge
+ the realserver pool since LVS VIP is owned by master LVS.
+ * Cosmetics patches into the vector lib.
+ * VRRP : Rewrote the previous VRRP synchronization instance policy.
+ Created a new config block called "vrrp_sync_group" that define VRRP
+ instances synchronization dependences. That way we replace the previous
+ "by-pair" sync approach by this "by-group" approach. This can be useefull
+ for firewall HA with many NICs. Created a dedicated framework to speed up
+ takeover synchronization.
+ * VRRP : Added support to CIDR notation for VRRP VIPs definitions
+ => VRRP VIPs definition like a.b.c.d/e. By default "e" value is set to 32.
+ * VRRP : Added support to multicast source IP address selection
+ => "mcast_src_ip" keyword. Can be usefull for strongly filtered env.
+ The mcast group subscription is done using the NIC default IP after this
+ mcast_src_ip is used if specified.
+ * VRRP : Enhanced the link media failure detection. Added support to the
+ new kernel SIOCETHTOOL probing for ETHTOOL_GLINK command. New drivers
+ use this ETHTOOL interface to report link failure activity. During
+ bootstrap a probe is done to determine the proper polling method to
+ use for link media failure detection. The policy used is : probe for
+ SIOCGMIIREG if not supported then try SIOCETHTOOL GLINK probe, otherwise
+ use a ioctl SIOCGIFFLAGS polling function mirroring kernel NIC flags to
+ localy reflected representation.
+ * Ramon Kagan, <rkagan@YorkU.CA> and I updated the UserGuide.pdf.
+
2002-05-30 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.5.9 released.
* Added support to realserver_group. The work is not yet finished since
KERNEL := _KRNL_2_$(shell uname -r | cut -d'.' -f2)_
IPVS_FLAG := @IPVS_SUPPORT@
VRRP_FLAG := @VRRP_SUPPORT@
+CI_LINUX := @CI_LINUX@
prefix = @prefix@
exec_prefix = @exec_prefix@
VRRP_OBJS = \
vrrp.o \
vrrp_scheduler.o \
+ vrrp_sync.o \
vrrp_netlink.o \
vrrp_if.o \
vrrp_ipaddress.o \
vrrp_ipsecah.o
endif
+ifeq ($(CI_LINUX),_WITH_CI_LINUX_)
+CI_LINUX_OBJ = check_ci.o
+CIFLAGS = -D$(CI_LINUX)
+endif
+
INCLUDE = -I/usr/src/linux/include
-OBJS = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS)
+OBJS = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS) $(CI_LINUX_OBJ)
.c.o:
- $(CC) -o $@ $(CFLAGS) $(IPVSFLAGS) $(INCLUDE) -c $*.c
+ $(CC) -o $@ $(CFLAGS) $(IPVSFLAGS) $(CIFLAGS) $(INCLUDE) -c $*.c
all: $(EXEC)
strip $(EXEC)
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_api.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "check_tcp.h"
#include "check_http.h"
#include "check_ssl.h"
+#ifdef _WITH_CI_LINUX_
+ #include "check_ci.h"
+#endif
extern thread_master *master;
extern data *conf_data;
real_server *rs = LIST_TAIL_DATA(vs->rs);
checker *chk = (checker *)MALLOC(sizeof(checker));
- chk->free = free;
- chk->dump = dump;
- chk->launch = launch;
- chk->vs = vs;
- chk->rs = rs;
- chk->data = data;
+ chk->free = free;
+ chk->dump = dump;
+ chk->launch = launch;
+ chk->vs = vs;
+ chk->rs = rs;
+ chk->data = data;
/* queue the checker */
list_add(checkers_queue, chk);
}
}
+/* Sync checkers activity with netlink kernel reflection */
+void update_checker_activity(uint32_t address, int enable)
+{
+ checker *checker;
+ element e;
+
+ /* Processing Healthcheckers queue */
+ if (!LIST_ISEMPTY(checkers_queue))
+ for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
+ checker = ELEMENT_DATA(e);
+ if (CHECKER_VIP(checker) == address) {
+ if (!CHECKER_ENABLED(checker) && enable) {
+ syslog(LOG_INFO, "Netlink reflector reports IP %s added"
+ , ip_ntoa(address));
+ syslog(LOG_INFO, "Activating healtchecker for VIP %s"
+ , ip_ntoa(address));
+ }
+ if (CHECKER_ENABLED(checker) && !enable) {
+ syslog(LOG_INFO, "Netlink reflector reports IP %s removed"
+ , ip_ntoa(address));
+ syslog(LOG_INFO, "Suspending healtchecker for VIP %s"
+ , ip_ntoa(address));
+ }
+ checker->enabled = enable;
+ }
+ }
+}
+
/* Install checkers keywords */
void install_checkers_keyword(void)
{
install_tcp_check_keyword();
install_http_check_keyword();
install_ssl_check_keyword();
+#ifdef _WITH_CI_LINUX_
+ install_ci_check_keyword();
+#endif
}
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_api.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
void (*free) (void *);
void (*dump) (void *);
int (*launch) (struct _thread *);
- virtual_server *vs; /* pointer to the checker thread virtualserver */
- real_server *rs; /* pointer to the checker thread realserver */
+ virtual_server *vs; /* pointer to the checker thread virtualserver */
+ real_server *rs; /* pointer to the checker thread realserver */
void *data;
+ int enabled; /* Activation flag */
} checker;
/* Checkers queue */
#define CHECKER_GET() (CHECKER_DATA(LIST_TAIL_DATA(checkers_queue)))
#define CHECKER_VALUE_INT(X) (atoi(VECTOR_SLOT(X,1)))
#define CHECKER_VALUE_STRING(X) (set_value(X))
+#define CHECKER_VIP(C) (SVR_IP((C)->vs))
+#define CHECKER_VPORT(C) (SVR_PORT((C)->vs))
#define CHECKER_RIP(C) (SVR_IP((C)->rs))
#define CHECKER_RPORT(C) (SVR_PORT((C)->rs))
#define CHECKER_VHOST(C) (VHOST((C)->vs))
+#define CHECKER_ENABLED(C) ((C)->enabled)
+#define CHECKER_ENABLE(C) ((C)->enabled = 1)
+#define CHECKER_DISABLE(C) ((C)->enabled = 0)
/* Prototypes definition */
extern void init_checkers_queue(void);
extern void free_checkers_queue(void);
extern void register_checkers_thread(void);
extern void install_checkers_keyword(void);
+extern void update_checker_activity(uint32_t address, int enable);
#endif
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
+ *
+ * Version: $Id: check_ci.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Authors: Alexandre Cassen, <acassen@linux-vs.org>
+ * Aneesh Kumar K.V, <aneesh.kumar@digital.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "check_ci.h"
+#include "check_api.h"
+#include "memory.h"
+#include "parser.h"
+#include "smtp.h"
+#include "ipwrapper.h"
+
+/* CI nodemap declaration */
+static nodenum_ip_map_t *nodemap;
+
+/* Configuration stream handling */
+void free_ci_check(void *data)
+{
+ if (nodemap) {
+ FREE(nodemap);
+ nodemap = NULL;
+ }
+}
+void dump_ci_check(void *data)
+{
+ syslog(LOG_INFO, " Keepalive method = CI-LINUX");
+}
+void ci_get_handler(vector strvec)
+{
+ int size = sizeof(nodenum_ip_map_t)*cluster_maxnodes()+1;
+ nodemap = (nodenum_ip_map_t *)ALLOC(size);
+
+ /*
+ * If we can not initialize node map we don t queue a new checker.
+ * The default action if so is:
+ * The realserver activity will not be monitored by the CI-LINUX
+ * Healchecker. This mean that this realserver will be present into
+ * LVS topology even if it is failing.
+ */
+ if (initialize_nodemap(nodemap) < 0) {
+ syslog(LOG_ERR, "[CI-LINUX] Failed to initialize the node map from %s"
+ , CLUSTERTAB);
+ } else
+ queue_checker(free_ci_check, dump_ci_check
+ , ci_check_thread
+ , NULL);
+}
+void install_ci_check_keyword(void)
+{
+ install_keyword("CI-LINUX", &ci_get_handler);
+}
+
+int initialize_nodemap(nodenum_ip_map_t *nodemap)
+{
+ FILE *fp;
+ char buf[BUFFSIZE];
+ int node_number ;
+
+ if ((fp = fopen(CLUSTERTAB,"r")) == NULL)
+ return -1;
+
+ while (fscanf(fp,"%s",buf) != EOF) {
+ if (buf[0] == '#') {
+ if (fscanf(fp, "%[^\n]", buf) == EOF) {
+ syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+ return -1;
+ }
+ bzero(buf,BUFFSIZE);
+ continue;
+ }
+ node_number = atoi(buf);
+ if (node_number > cluster_maxnodes()) {
+ syslog(LOG_ERR, "[CI-LINUX] Node number greater than MAX node num\n");
+ return -1;
+ }
+ if (fscanf(fp, "%s",buf) == EOF) {
+ syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+ return -1;
+ }
+ nodemap[node_number].addr_ip = inet_addr(buf);
+ if (fscanf(fp, "%[^\n]", buf) == EOF) {
+ syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
+ return -1;
+ }
+ bzero(buf, BUFFSIZE);
+ }
+ return 1;
+}
+
+clusternode_t address_to_nodenum(uint32_t addr_ip)
+{
+ int i ;
+ int max_nodes = cluster_maxnodes();
+
+ for (i = 1; i<= max_nodes; i++) {
+ if (nodemap[i].addr_ip == addr_ip)
+ return i;
+ }
+ return 0; /* Not a valid node */
+}
+
+int nodestatus(uint32_t addr_ip)
+{
+ int node_num;
+ clusternode_info_t ni;
+
+ if ((node_num = address_to_nodenum(addr_ip)) == 0)
+ return UNKNOWN_NODE;
+
+ if (clusternode_info(node_num, sizeof(ni), &ni) >= 0)
+ /*
+ * I am insterested only in two state
+ * either fully up or down.
+ */
+ return (ni.node_state == CLUSTERNODE_UP)?UP:DOWN;
+ else
+ syslog(LOG_ERR, "[CI-LINUX] Error in getting the cluster information");
+
+ return UNKNOWN_NODE;
+}
+
+/* Cluster Infrastructure checker thread */
+int ci_check_thread(thread *thread)
+{
+ checker *checker = THREAD_ARG(thread);
+ int status ;
+
+ /*
+ * Register a new checker thread & return
+ * if checker is disabled
+ */
+ if (!CHECKER_ENABLED(checker)) {
+ thread_add_timer(thread->master, ci_check_thread
+ , checker
+ , checker->vs->delay_loop);
+ return 0;
+ }
+
+
+ /* Check the CI node status */
+ status = nodestatus(CHECKER_RIP(checker));
+
+ switch(status) {
+ case UP:
+ if (!ISALIVE(checker->rs)) {
+ smtp_alert(thread->master, checker->rs
+ , NULL
+ , "UP"
+ , "=> CI-Linux CHECK succeed on service <=\n\n");
+ perform_svr_state(UP, checker->vs, checker->rs);
+ }
+ break;
+ case DOWN:
+ if (ISALIVE(checker->rs)) {
+ smtp_alert(thread->master, checker->rs
+ , NULL
+ , "DOWN"
+ , "=> CI-Linux CHECK failed on service <=\n\n");
+ perform_svr_state(DOWN, checker->vs, checker->rs);
+ }
+ break;
+ default:
+ syslog(LOG_ERR,"[CI-LINUX] Unknown node status");
+ }
+
+ /* Register the next check */
+ thread_add_timer(thread->master, ci_check_thread
+ , checker
+ , checker->vs->delay_loop);
+ return 0;
+}
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: check_ci.c include file.
+ *
+ * Version: $Id: check_ci.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Authors: Alexandre Cassen, <acassen@linux-vs.org>
+ * Aneesh Kumar K.V, <aneesh.kumar@digital.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _CI_LINUX_H
+#define _CI_LINUX_H
+
+/* system includes */
+#include <signal.h>
+#include <pthread.h>
+#include <linux/cluster.h> /* Should change this to cluster.h alone */
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/* local includes */
+#include "scheduler.h"
+
+#define SIGCLUSTER 2
+#define CLUSTERTAB "/etc/clustertab"
+#define BUFFSIZE 100
+#define UP 1
+#define DOWN 2
+#define UNKNOWN_NODE 0
+
+typedef struct nodenum_ip_map {
+ uint32_t addr_ip;
+} nodenum_ip_map_t;
+
+/* Prototypes defs */
+extern int initialize_nodemap(nodenum_ip_map_t *nodemap);
+extern clusternode_t address_to_nodenum(uint32_t addr_ip);
+extern int nodestatus(uint32_t addr_ip);
+extern void install_ci_check_kerword(void);
+
+#endif
*
* Part: WEB CHECK. Common HTTP/SSL checker primitives.
*
- * Version: $Id: check_http.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_http.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
enum connect_result status;
int fd;
+ /*
+ * Register a new checker thread & return
+ * if checker is disabled
+ */
+ if (!CHECKER_ENABLED(checker)) {
+ thread_add_timer(thread->master, http_connect_thread
+ , checker
+ , checker->vs->delay_loop);
+ return 0;
+ }
+
/* Find eventual url end */
fetched_url = fetch_next_url(http_get_check);
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* Part: MISC CHECK. Perform a system call to run an extra
* system prog or script.
*
- * Version: $Id: check_misc.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_misc.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
thread_add_timer(thread->master, misc_check_thread
, checker
, checker->vs->delay_loop);
+ /*
+ * Register a new checker thread & return
+ * if checker is disabled
+ */
+ if (!CHECKER_ENABLED(checker))
+ return 0;
/* Daemonization to not degrade our scheduling timer */
if (xdaemon(0, 0, 1))
*
* Part: check_misc.c include file.
*
- * Version: $Id: check_misc.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_misc.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: check_ssl.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_ssl.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: TCP checker.
*
- * Version: $Id: check_tcp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_tcp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
checker = THREAD_ARG(thread);
tcp_check = CHECKER_ARG(checker);
+ /*
+ * Register a new checker thread & return
+ * if checker is disabled
+ */
+ if (!CHECKER_ENABLED(checker)) {
+ thread_add_timer(thread->master, tcp_connect_thread
+ , checker
+ , checker->vs->delay_loop);
+ return 0;
+ }
+
if ( (fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connect fail to create socket.");
*
* Part: check_tcp.c include file.
*
- * Version: $Id: check_tcp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: check_tcp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int connection_to;
} tcp_checker;
-
/* Prototypes defs */
extern void install_tcp_check_keyword(void);
ac_help="$ac_help
--disable-vrrp do not use the VRRP framework"
ac_help="$ac_help
+ --with-ci_linux Compile with Cluster Infrastructure support (default no)"
+ac_help="$ac_help
--enable-debug compile with debugging flags"
# Initialize some variables set by options.
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:537: checking for $ac_word" >&5
+echo "configure:539: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:567: checking for $ac_word" >&5
+echo "configure:569: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:618: checking for $ac_word" >&5
+echo "configure:620: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:650: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:652: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
cat > conftest.$ac_ext << EOF
-#line 661 "configure"
+#line 663 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:692: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:697: checking whether we are using GNU C" >&5
+echo "configure:699: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:725: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:727: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:787: checking for a BSD compatible install" >&5
+echo "configure:789: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
:
fi
+# Check whether --with-ci_linux or --without-ci_linux was given.
+if test "${with_ci_linux+set}" = set; then
+ withval="$with_ci_linux"
+ ci_linux=$withval
+else
+ ci_linux="no"
+fi
+
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
if test "${enable_vrrp}" = "no"; then
VRRP_SUPPORT="_WITHOUT_VRRP_"
fi
+if test "${ci_linux}" = "yes"; then
+ CI_LINUX="_WITH_CI_LINUX_"
+fi
if test "${enable_debug}" = "yes"; then
DFLAGS="-D_DEBUG_"
+
IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_"
if test ${IPVS_MAJOR} -eq 0; then
if test ${IPVS_MINOR} -eq 9; then
echo $ac_n "checking for MD5_Init in -lcrypto""... $ac_c" 1>&6
-echo "configure:945: checking for MD5_Init in -lcrypto" >&5
+echo "configure:959: checking for MD5_Init in -lcrypto" >&5
ac_lib_var=`echo crypto'_'MD5_Init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lcrypto $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 953 "configure"
+#line 967 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
MD5_Init()
; return 0; }
EOF
-if { (eval echo configure:964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for SSL_CTX_new in -lssl""... $ac_c" 1>&6
-echo "configure:993: checking for SSL_CTX_new in -lssl" >&5
+echo "configure:1007: checking for SSL_CTX_new in -lssl" >&5
ac_lib_var=`echo ssl'_'SSL_CTX_new | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lssl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1001 "configure"
+#line 1015 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
SSL_CTX_new()
; return 0; }
EOF
-if { (eval echo configure:1012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1026: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:1041: checking for poptGetContext in -lpopt" >&5
+echo "configure:1055: checking for poptGetContext in -lpopt" >&5
ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lpopt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1049 "configure"
+#line 1063 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
poptGetContext()
; return 0; }
EOF
-if { (eval echo configure:1060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
{ echo "configure: error: Popt libraries is required" 1>&2; exit 1; }
fi
+if test "${ci_linux}" = "yes"; then
+echo $ac_n "checking for cluster_maxnodes in -lcluster""... $ac_c" 1>&6
+echo "configure:1104: checking for cluster_maxnodes in -lcluster" >&5
+ac_lib_var=`echo cluster'_'cluster_maxnodes | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcluster $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1112 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cluster_maxnodes();
+
+int main() {
+cluster_maxnodes()
+; return 0; }
+EOF
+if { (eval echo configure:1123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo cluster | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lcluster $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: libcluster libraries are required" 1>&2; exit 1; }
+fi
+
+fi
if test "${KERNEL_CODE}" = "2"; then
LIBFW="libipfwc/libipfwc.a"
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1095: checking how to run the C preprocessor" >&5
+echo "configure:1159: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1110 "configure"
+#line 1174 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1116: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1127 "configure"
+#line 1191 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1133: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1144 "configure"
+#line 1208 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1150: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1214: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1175: checking for ANSI C header files" >&5
+echo "configure:1239: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1180 "configure"
+#line 1244 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1252: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1205 "configure"
+#line 1269 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1223 "configure"
+#line 1287 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
:
else
cat > conftest.$ac_ext <<EOF
-#line 1244 "configure"
+#line 1308 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
exit (0); }
EOF
-if { (eval echo configure:1255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1279: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1343: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1284 "configure"
+#line 1348 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1300: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1324: checking for $ac_hdr" >&5
+echo "configure:1388: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1329 "configure"
+#line 1393 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1334: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1398: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1367: checking for $ac_hdr" >&5
+echo "configure:1431: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1436 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+if test "${ci_linux}" = "yes"; then
+for ac_hdr in linux/cluster.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1472: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1372 "configure"
+#line 1477 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1377: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1482: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
else
echo "$ac_t""no" 1>&6
+{ echo "configure: error: linux/cluster.h file not found" 1>&2; exit 1; }
fi
done
+fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1405: checking for working const" >&5
+echo "configure:1512: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1410 "configure"
+#line 1517 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:1459: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1566: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1480: checking for pid_t" >&5
+echo "configure:1587: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1485 "configure"
+#line 1592 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1513: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1620: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1518 "configure"
+#line 1625 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1527: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1634: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:1550: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:1657: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <<EOF
-#line 1556 "configure"
+#line 1663 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
-#line 1574 "configure"
+#line 1681 "configure"
#include "confdefs.h"
#include <termio.h>
Autoconf TCGETA
fi
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1596: checking return type of signal handlers" >&5
+echo "configure:1703: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1601 "configure"
+#line 1708 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
int i;
; return 0; }
EOF
-if { (eval echo configure:1618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1725: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
for ac_func in gettimeofday select socket strerror strtol uname
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1639: checking for $ac_func" >&5
+echo "configure:1746: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1644 "configure"
+#line 1751 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:1667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
s%@DFLAGS@%$DFLAGS%g
s%@IPVS_SUPPORT@%$IPVS_SUPPORT%g
s%@VRRP_SUPPORT@%$VRRP_SUPPORT%g
+s%@CI_LINUX@%$CI_LINUX%g
s%@IPVS_SYNCD@%$IPVS_SYNCD%g
s%@LIBFW@%$LIBFW%g
s%@LIBOBJS@%$LIBOBJS%g
else
echo "Use VRRP Framework : No"
fi
+if test "${CI_LINUX}" = "_WITH_CI_LINUX_"; then
+ echo "Use CI_LINUX Framework : Yes"
+else
+ echo "Use CI_LINUX Framework : No"
+fi
if test "${DFLAGS}" = "-D_DEBUG_"; then
echo "Use Debug flags : Yes"
else
[ --disable-lvs do not use the LVS framework])
AC_ARG_ENABLE(vrrp,
[ --disable-vrrp do not use the VRRP framework])
+AC_ARG_WITH(ci_linux,
+ [ --with-ci_linux Compile with Cluster Infrastructure support (default no)],
+ ci_linux=$withval,ci_linux="no")
AC_ARG_ENABLE(debug,
[ --enable-debug compile with debugging flags])
if test "${enable_vrrp}" = "no"; then
VRRP_SUPPORT="_WITHOUT_VRRP_"
fi
+if test "${ci_linux}" = "yes"; then
+ CI_LINUX="_WITH_CI_LINUX_"
+fi
if test "${enable_debug}" = "yes"; then
DFLAGS="-D_DEBUG_"
AC_SUBST(DFLAGS)
AC_SUBST(IPVS_SUPPORT)
AC_SUBST(VRRP_SUPPORT)
+AC_SUBST(CI_LINUX)
dnl ----[ LVS syncd support probe ]---
dnl Sync daemon is supported since LVS 0.9.2 for kernel 2.4
AC_CHECK_LIB(crypto, MD5_Init,,AC_MSG_ERROR([OpenSSL libraries are required]))
AC_CHECK_LIB(ssl, SSL_CTX_new,,AC_MSG_ERROR([OpenSSL libraries are required]))
AC_CHECK_LIB(popt, poptGetContext,,AC_MSG_ERROR([Popt libraries is required]))
+if test "${ci_linux}" = "yes"; then
+AC_CHECK_LIB(cluster,cluster_maxnodes,,AC_MSG_ERROR([libcluster libraries are required]))
+fi
dnl ----[ Create object list ]----
if test "${KERNEL_CODE}" = "2"; then
!!! OpenSSL is not properly installed on your system. !!!
!!! Can not include OpenSSL headers files. !!!]))
AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h syslog.h unistd.h)
+if test "${ci_linux}" = "yes"; then
+AC_CHECK_HEADERS(linux/cluster.h,,AC_MSG_ERROR([linux/cluster.h file not found]))
+fi
dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
AC_C_CONST
else
echo "Use VRRP Framework : No"
fi
+if test "${CI_LINUX}" = "_WITH_CI_LINUX_"; then
+ echo "Use CI_LINUX Framework : Yes"
+else
+ echo "Use CI_LINUX Framework : No"
+fi
if test "${DFLAGS}" = "-D_DEBUG_"; then
echo "Use Debug flags : Yes"
else
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: main.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: daemon.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: data.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "utils.h"
#include "check_api.h"
#include "vrrp.h"
+#include "vrrp_sync.h"
extern data *conf_data;
}
/* VRRP facility functions */
+static void free_vgroup(void *data)
+{
+ vrrp_sgroup *vgroup = data;
+
+ FREE(vgroup->gname);
+ free_strvec(vgroup->iname);
+ FREE(vgroup);
+}
+static void dump_vgroup(void *data)
+{
+ vrrp_sgroup *vgroup = data;
+ int i;
+ char *str;
+
+ syslog(LOG_INFO, " VRRP Sync Group = %s, %s"
+ , vgroup->gname
+ , (vgroup->state == VRRP_STATE_MAST)?"MASTER":"BACKUP");
+ for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+ str = VECTOR_SLOT(vgroup->iname, i);
+ syslog(LOG_INFO, " monitor = %s", str);
+ }
+}
+
static void free_vrrp(void *data)
{
vrrp_rt *vrrp = data;
FREE(vrrp->iname);
- FREE_PTR(vrrp->isync);
FREE_PTR(vrrp->lvs_syncd_if);
FREE_PTR(vrrp->vaddr);
FREE_PTR(vrrp->evaddr);
int i;
syslog(LOG_INFO, " VRRP Instance = %s", vrrp->iname);
- if (vrrp->isync)
- syslog(LOG_INFO, " Sync with instance = %s", vrrp->isync);
if (vrrp->init_state == VRRP_STATE_BACK)
syslog(LOG_INFO, " Want State = BACKUP");
else
syslog(LOG_INFO, " Want State = MASTER");
syslog(LOG_INFO, " Runing on device = %s", IF_NAME(vrrp->ifp));
+ if (vrrp->mcast_saddr)
+ syslog(LOG_INFO, " Using mcast src_ip = %s"
+ , ip_ntoa(vrrp->mcast_saddr));
if (vrrp->lvs_syncd_if)
syslog(LOG_INFO, " Runing LVS sync daemon on interface = %s"
, vrrp->lvs_syncd_if);
}
syslog(LOG_INFO, " VIP count = %d", vrrp->naddr);
for (i = 0; i < vrrp->naddr; i++)
- syslog(LOG_INFO, " VIP%d = %s", i+1, ip_ntoa(vrrp->vaddr[i].addr));
+ syslog(LOG_INFO, " VIP%d = %s/%d", i+1, ip_ntoa(vrrp->vaddr[i].addr)
+ , vrrp->vaddr[i].mask);
if (vrrp->neaddr) {
syslog(LOG_INFO, " Excluded VIP count = %d", vrrp->neaddr);
for (i = 0; i < vrrp->neaddr; i++)
- syslog(LOG_INFO, " E-VIP%d = %s", i+1, ip_ntoa(vrrp->evaddr[i].addr));
+ syslog(LOG_INFO, " E-VIP%d = %s/%d", i+1, ip_ntoa(vrrp->evaddr[i].addr)
+ , vrrp->evaddr[i].mask);
}
if (vrrp->script_backup)
syslog(LOG_INFO, " Backup state transition script = %s"
if (vrrp->smtp_alert)
syslog(LOG_INFO, " Using smtp notification");
}
+void alloc_vrrp_sync_group(char *gname, vector iname)
+{
+ int size = strlen(gname);
+ vrrp_sgroup *new;
+
+ /* Allocate new VRRP group structure */
+ new = (vrrp_sgroup *)MALLOC(sizeof(vrrp_sgroup));
+ new->gname = (char *)MALLOC(size+1);
+ memcpy(new->gname, gname, size);
+ new->iname = iname;
+
+ list_add(conf_data->vrrp_sync_group, new);
+}
void alloc_vrrp(char *iname)
{
int size = strlen(iname);
new->adver_int = TIMER_HZ;
new->iname = (char *)MALLOC(size+1);
memcpy(new->iname, iname, size);
+ new->sync = vrrp_get_sync_group(iname);
list_add(conf_data->vrrp, new);
}
void alloc_vrrp_vip(char *vip)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- uint32_t ipaddr = inet_addr(vip);
+ uint32_t ipaddr = ip_ston(vip);
+ uint8_t mask = ip_stom(vip);
vrrp->naddr++;
if (vrrp->vaddr)
else
vrrp->vaddr = (vip_addr *)MALLOC(sizeof(*vrrp->vaddr));
vrrp->vaddr[vrrp->naddr-1].addr = ipaddr;
+ vrrp->vaddr[vrrp->naddr-1].mask = mask;
vrrp->vaddr[vrrp->naddr-1].set = 0;
}
void alloc_vrrp_evip(char *vip)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- uint32_t ipaddr = inet_addr(vip);
+ uint32_t ipaddr = ip_ston(vip);
+ uint8_t mask = ip_stom(vip);
vrrp->neaddr++;
if (vrrp->evaddr)
else
vrrp->evaddr = (vip_addr *)MALLOC(sizeof(*vrrp->evaddr));
vrrp->evaddr[vrrp->neaddr-1].addr = ipaddr;
+ vrrp->evaddr[vrrp->neaddr-1].mask = mask;
vrrp->evaddr[vrrp->neaddr-1].set = 0;
}
new = (data *)MALLOC(sizeof(data));
new->email = alloc_list(free_email, dump_email);
new->vrrp = alloc_list(free_vrrp, dump_vrrp);
+ new->vrrp_sync_group = alloc_list(free_vgroup, dump_vgroup);
new->vs = alloc_list(free_vs, dump_vs);
new->group = alloc_list(free_group, dump_group);
free_ssl();
free_list(conf_data->email);
free_list(conf_data->vrrp);
+ free_list(conf_data->vrrp_sync_group);
free_list(conf_data->vs);
free_list(conf_data->group);
syslog(LOG_INFO, "------< VRRP Topology >------");
dump_list(conf_data->vrrp);
}
+ if (!LIST_ISEMPTY(conf_data->vrrp_sync_group)) {
+ syslog(LOG_INFO, "------< VRRP Sync groups >------");
+ dump_list(conf_data->vrrp_sync_group);
+ }
if (!LIST_ISEMPTY(conf_data->group)) {
syslog(LOG_INFO, "------< Real Servers groups >------");
dump_list(conf_data->group);
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: data.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* local includes */
#include "list.h"
+#include "vector.h"
/* Daemon dynamic data structure definition */
#define MAX_TIMEOUT_LENGTH 5
SSL_DATA *ssl;
list email;
list vrrp;
+ list vrrp_sync_group;
list vs;
list group;
} data;
/* prototypes */
extern void alloc_email(char *addr);
extern SSL_DATA *alloc_ssl(void);
+extern void alloc_vrrp_sync_group(char *gname, vector iname);
extern void alloc_vrrp(char *iname);
extern void alloc_vrrp_vip(char *vip);
extern void alloc_vrrp_evip(char *vip);
# pidfile: /var/run/keepalived.pid
# config: /etc/keepalived/keepalived.conf
+# Global definitions
+PID_FILE="/var/run/keepalived.pid"
+
# See how we were called.
case "$1" in
start)
;;
stop)
echo -n "Shutting down Keepalived for LVS: "
- PID=`ps ax | grep keepalived | awk '{print $1}'`
+ PID=`cat $PID_FILE`
kill $PID
echo
;;
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: IPVS Kernel wrapper. Use setsockopt call to add/remove
* server to/from the loadbalanced server pool.
*
- * Version: $Id: ipvswrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $id: ipwrapper.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: Layer4 checkers handling. Register worker threads &
* upper layer checkers.
*
- * Version: $Id: layer4.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: layer4.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: layer4.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: list.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: list.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: main.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#ifdef _WITH_LVS_
init_checkers_queue();
#endif
- init_keywords();
init_data(conf_file);
if (!conf_data) {
syslog(LOG_INFO, "Stopping "VERSION_STRING);
register_vrrp_thread();
/* processing the master thread queues, return and execute one ready thread */
- while(thread_fetch(master, &thread)) {
+ while (thread_fetch(master, &thread)) {
/* Run until error, used for debuging only */
#ifdef _DEBUG_
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: main.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_netlink.h"
/* global var */
-thread_master *master;
+thread_master *master = NULL;
unsigned int debug;
unsigned long mem_allocated = 0;
data *conf_data;
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x000509
-#define DATE_CODE 0x1E0502
+#define VERSION_CODE 0x000601
+#define DATE_CODE 0x0D0602
#define KEEPALIVED_VERSION(version) \
(version >> 16) & 0xFF, \
* Part: Memory management framework. This framework is used to
* find any memory leak.
*
- * Version: $Id: memory.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: memory.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
void *xalloc(unsigned long size)
{
void *mem;
+ if ((mem = malloc(size)))
+ mem_allocated += size;
+ return mem;
+}
+void *zalloc(unsigned long size)
+{
+ void *mem;
if ((mem = malloc(size))) {
memset(mem, 0, size);
mem_allocated += size;
int i = 0;
long check;
- buf = xalloc(size+sizeof(long)) ;
+ buf = zalloc(size + sizeof(long));
check = 0xa5a5 + size;
*(long *)((char *)buf+size) = check;
alloc_list[i].type = 9;
if (debug & 1)
- printf("%sxalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n"
+ printf("%szalloc[%3d:%3d], %p, %4ld at %s, %3d, %s\n"
,nspace(s++), i, number_alloc_list, buf, size, file, line, function);
n++;
/* not found */
if (i == number_alloc_list) {
- printf("realloc ERROR no matching xalloc %p \n", buffer);
+ printf("realloc ERROR no matching zalloc %p \n", buffer);
number_alloc_list++;
alloc_list[i].ptr = buf;
alloc_list[i].size = 0;
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: memory.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
extern unsigned int debug;
extern unsigned long mem_allocated;
extern void *xalloc(unsigned long size);
+extern void *zalloc(unsigned long size);
extern void xfree(void *p);
+/* Global alloc macro */
+#define ALLOC(n) (xalloc(n))
+
/* Local defines */
#ifdef _DEBUG_
#else
-#define MALLOC(n) (xalloc(n))
+#define MALLOC(n) (zalloc(n))
#define FREE(p) (xfree(p))
#define REALLOC(p,n) (realloc((p),(n)))
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: parser.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: parser.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
vector_free(keywords);
}
-/*
-static void dump_strvec(vector strvec)
-{
- int i;
- char *str;
-
- if (!strvec)
- return;
-
- printf("String Vector : ");
-
- for (i = 0; i < VECTOR_SIZE(strvec); i++) {
- str = VECTOR_SLOT(strvec, i);
- printf("[%i]=%s ", i, str);
- }
- printf("\n");
-}
-*/
-
-static void free_strvec(vector strvec)
-{
- int i;
- char *str;
-
- if (!strvec)
- return;
-
- for (i=0; i < VECTOR_SIZE(strvec); i++)
- if ((str = VECTOR_SLOT(strvec, i)) != NULL)
- FREE(str);
-
- vector_free(strvec);
-}
-
static vector alloc_strvec(char *string)
{
char *cp, *start, *token;
}
/* VRRP handlers */
-static void vrrp_handler(vector strvec)
+static void vrrp_sync_group_handler(vector strvec)
{
- alloc_vrrp(VECTOR_SLOT(strvec, 1));
+ vector iname = read_value_block();
+ alloc_vrrp_sync_group(VECTOR_SLOT(strvec, 1), iname);
}
-static void vrrp_isync_handler(vector strvec)
+static void vrrp_handler(vector strvec)
{
- vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- vrrp->isync = set_value(strvec);
+ alloc_vrrp(VECTOR_SLOT(strvec, 1));
}
static void vrrp_state_handler(vector strvec)
{
char *str = VECTOR_SLOT(strvec, 1);
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ vrrp_sgroup *vgroup = vrrp->sync;
if (!strcmp(str, "MASTER")) {
vrrp->wantstate = VRRP_STATE_MAST;
vrrp->wantstate = VRRP_STATE_BACK;
vrrp->init_state = VRRP_STATE_BACK;
}
+
+ /* set eventual sync group */
+ if (vgroup)
+ vgroup->state = vrrp->wantstate;
}
static void vrrp_int_handler(vector strvec)
{
vrrp->ifp = if_get_by_ifname(name);
}
+static void vrrp_mcastip_handler(vector strvec)
+{
+ vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
+ vrrp->mcast_saddr = inet_addr(VECTOR_SLOT(strvec, 1));
+}
static void vrrp_vrid_handler(vector strvec)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
install_keyword("key", &sslkey_handler);
/* VRRP Instance mapping */
+ install_keyword_root("vrrp_sync_group", &vrrp_sync_group_handler);
install_keyword_root("vrrp_instance", &vrrp_handler);
install_keyword("state", &vrrp_state_handler);
install_keyword("interface", &vrrp_int_handler);
+ install_keyword("mcast_src_ip", &vrrp_mcastip_handler);
install_keyword("virtual_router_id", &vrrp_vrid_handler);
install_keyword("priority", &vrrp_prio_handler);
install_keyword("advert_int", &vrrp_adv_handler);
install_keyword("virtual_ipaddress", &vrrp_vip_handler);
install_keyword("virtual_ipaddress_excluded", &vrrp_evip_handler);
- install_keyword("sync_instance", &vrrp_isync_handler);
install_keyword("preempt", &vrrp_preempt_handler);
install_keyword("debug", &vrrp_debug_handler);
install_keyword("notify_backup", &vrrp_notify_backup_handler);
return;
}
+ /* Init Keywords structure */
+ init_keywords();
+
/* Init data structure */
conf_data = alloc_data();
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: parser.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: pidfile.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: pidfile.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
! Configuration File for keepalived
-global_defs {
- notification_email {
- acassen@canal-plus.com
- }
- notification_email_from keepalived@canal-plus.com
- smtp_server 172.31.47.6
- smtp_connect_timeout 30
- lvs_id LVS_DEVEL
+vrrp_sync_group G1 {
+ VI_1
+ VI_2
+ VI_5
+ VI_6
+ VI_7
+ VI_8
+ VI_9
+}
+
+vrrp_sync_group G2 {
+ VI_3
+ VI_4
}
vrrp_instance VI_1 {
- state MASTER
interface eth0
+ state MASTER
virtual_router_id 51
- priority 150
- advert_int 1
- authentication {
- auth_type AH
- auth_pass 1111
- }
+ priority 100
virtual_ipaddress {
- 192.168.200.16
- 192.168.200.17
- 192.168.200.18
+ 192.168.200.18/25
}
}
vrrp_instance VI_2 {
- interface eth0
+ interface eth1
+ state MASTER
virtual_router_id 52
priority 100
- advert_int 1
virtual_ipaddress {
- 192.168.200.19
- 192.168.200.20
- 192.168.200.21
+ 192.168.201.18/26
}
- sync_instance VI_3
}
vrrp_instance VI_3 {
- interface eth1
+ interface eth0
virtual_router_id 53
priority 100
- advert_int 1
virtual_ipaddress {
- 192.168.201.19
- 192.168.201.20
- 192.168.201.21
+ 192.168.200.19/27
+ }
+}
+
+vrrp_instance VI_4 {
+ interface eth1
+ virtual_router_id 54
+ priority 100
+ virtual_ipaddress {
+ 192.168.201.19/28
+ }
+}
+
+vrrp_instance VI_5 {
+ state MASTER
+ interface eth0
+ virtual_router_id 55
+ priority 100
+ virtual_ipaddress {
+ 192.168.200.20/27
+ }
+}
+
+
+vrrp_instance VI_6 {
+ state MASTER
+ interface eth0
+ virtual_router_id 56
+ priority 100
+ virtual_ipaddress {
+ 192.168.200.21/27
}
- sync_instance VI_2
}
-virtual_server 192.168.200.19 80 {
- delay_loop 20
- lb_algo rr
- lb_kind NAT
- nat_mask 255.255.255.0
- persistence_timeout 50
- protocol TCP
+vrrp_instance VI_7 {
+ state MASTER
+ interface eth0
+ virtual_router_id 57
+ priority 100
+ virtual_ipaddress {
+ 192.168.200.22/27
+ }
+}
- real_server 192.168.201.100 80 {
- weight 1
- TCP_CHECK {
- connect_timeout 3
- }
+vrrp_instance VI_8 {
+ state MASTER
+ interface eth0
+ virtual_router_id 58
+ priority 100
+ virtual_ipaddress {
+ 192.168.200.23/27
+ }
+}
+
+vrrp_instance VI_9 {
+ state MASTER
+ interface eth0
+ virtual_router_id 59
+ priority 100
+ virtual_ipaddress {
+ 192.168.200.24/27
}
}
+
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: scheduler.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: scheduler.h,v 0.6.1 2002/06/13 15:12:26 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.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: smtp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: smtp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: timer.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: timer.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: utils.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "utils.h"
+/* Display a buffer into a HEXA formated output */
void print_buffer(int count, char *buff)
{
int i,j,c;
}
}
+/* IP network to ascii representation */
char *ip_ntoa(uint32_t ip)
{
- static char buf[20];
+ static char buf[16];
unsigned char *bytep;
bytep = (unsigned char *) &(ip);
sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
+
+/* IP string to network representation */
+uint32_t ip_ston(char *addr)
+{
+ char *cp = addr;
+ static char buf[16];
+ int strlen;
+
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ strlen = cp - addr;
+ memcpy(buf, addr, strlen);
+ buf[strlen + 1] = '\0';
+ return inet_addr(buf);
+}
+
+/* IP string to network mask representation */
+uint8_t ip_stom(char *addr)
+{
+ uint8_t mask = 32;
+ char *cp = addr;
+
+ while (*cp != '/' && *cp != '\0')
+ cp++;
+ if (*cp == '/')
+ return atoi(++cp);
+ return mask;
+}
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: utils.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* system includes */
#include <stdio.h>
+#include <stdlib.h>
#include <stdint.h>
+#include <string.h>
+#include <arpa/inet.h>
/* Prototypes defs */
extern void print_buffer(int count, char *buff);
extern char *ip_ntoa(uint32_t ip);
+extern uint32_t ip_ston(char *addr);
+extern uint8_t ip_stom(char *addr);
#endif
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vector.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
FREE(v->slot);
FREE(v);
}
+void free_strvec(vector strvec)
+{
+ int i;
+ char *str;
+
+ if (!strvec)
+ return;
+
+ for (i=0; i < VECTOR_SIZE(strvec); i++)
+ if ((str = VECTOR_SLOT(strvec, i)) != NULL)
+ FREE(str);
+
+ vector_free(strvec);
+}
/* Set a vector slot value */
void vector_set_slot(vector v, void *value)
if (v->slot[i] != NULL)
printf(" Slot [%d]: %p\n", i, VECTOR_SLOT(v, i));
}
+
+void dump_strvec(vector strvec)
+{
+ int i;
+ char *str;
+
+ if (!strvec)
+ return;
+
+ printf("String Vector : ");
+
+ for (i = 0; i < VECTOR_SIZE(strvec); i++) {
+ str = VECTOR_SLOT(strvec, i);
+ printf("[%i]=%s ", i, str);
+ }
+ printf("\n");
+}
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vector.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
extern vector vector_alloc(void);
extern void vector_alloc_slot(vector v);
extern void vector_free(vector v);
+extern void free_strvec(vector strvec);
extern void vector_set_slot(vector v, void *value);
extern void vector_dump(vector v);
+extern void dump_strvec(vector strvec);
#endif
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
vip_addr *vadd = (type == VRRP_VIP_TYPE)?&vrrp->vaddr[i]:&vrrp->evaddr[i];
if(!cmd && !vadd->set) continue;
retry:
- if (netlink_address_ipv4(ifindex , ntohl(vadd->addr), cmd) < 0) {
+ if (netlink_address_ipv4(ifindex , vadd->addr, vadd->mask, cmd) < 0) {
err = 1;
vadd->set = 0;
syslog(LOG_INFO, "cant %s the address %s to %s\n"
, IF_NAME(vrrp->ifp));
if (cmd == VRRP_IPADDRESS_ADD) {
syslog(LOG_INFO, "try to delete eventual stalled ip");
- netlink_address_ipv4(ifindex, ntohl(vadd->addr), VRRP_IPADDRESS_DEL);
+ netlink_address_ipv4(ifindex, vadd->addr, vadd->mask, VRRP_IPADDRESS_DEL);
if (retry < 4) {
retry++;
goto retry;
/* fill protocol type --rfc2402.2 */
ip->protocol = (vrrp->auth_type == VRRP_AUTH_AH)?IPPROTO_IPSEC_AH:IPPROTO_VRRP;
- ip->saddr = IF_ADDR(vrrp->ifp);
+ ip->saddr = VRRP_PKT_SADDR(vrrp);
ip->daddr = htonl(INADDR_VRRP_GROUP);
/* checksum must be done last */
arph->ar_pln = 4;
arph->ar_op = htons(ARPOP_REQUEST);
memcpy(arph->__ar_sha, hwaddr, hwlen);
- addr = htonl(addr);
memcpy(arph->__ar_sip, &addr, sizeof(addr));
memcpy(arph->__ar_tip, &addr, sizeof(addr));
+
return vrrp_send_pkt(vrrp, buf, buflen);
}
for (j = 0; j < 5; j++) {
for (i = 0; i < vrrp->naddr; i++)
- send_gratuitous_arp(vrrp, ntohl(vrrp->vaddr[i].addr));
+ send_gratuitous_arp(vrrp, vrrp->vaddr[i].addr);
for (i = 0; i < vrrp->neaddr; i++)
- send_gratuitous_arp(vrrp, ntohl(vrrp->evaddr[i].addr));
+ send_gratuitous_arp(vrrp, vrrp->evaddr[i].addr);
}
}
vrrp_state_become_master(vrrp);
}
- if (prio == VRRP_PRIO_OWNER)
- vrrp_send_adv(vrrp, VRRP_PRIO_OWNER);
- else
- vrrp_send_adv(vrrp, vrrp->priority);
+ vrrp_send_adv(vrrp, (prio==VRRP_PRIO_OWNER)?VRRP_PRIO_OWNER:vrrp->priority);
}
int vrrp_state_master_rx(vrrp_rt *vrrp, char *buf, int buflen)
return 0;
} else if (hd->priority > vrrp->priority ||
(hd->priority == vrrp->priority &&
- ntohl(iph->saddr) > IF_ADDR(vrrp->ifp))) {
+ ntohl(iph->saddr) > VRRP_PKT_SADDR(vrrp))) {
syslog(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
, vrrp->iname);
vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
- * Based on the Jerome Etienne, <jetienne@arobas.net> code.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "vrrp_if.h"
#include "timer.h"
#include "utils.h"
+#include "vector.h"
typedef struct { /* rfc2338.5.1 */
uint8_t vers_type; /* 0-3=type, 4-7=version */
#define VRRP_ADVER_DFL 1 /* advert. interval (in sec) -- rfc2338.5.3.7 */
#define VRRP_PREEMPT_DFL 1 /* rfc2338.6.1.2.Preempt_Mode */
+
+/*
+ * parameters per vrrp sync group. A vrrp_sync_group is a set
+ * of VRRP instances that need to be state sync together.
+ */
+typedef struct _vrrp_sgroup {
+ char *gname; /* Group name */
+ vector iname; /* Set of VRRP instances in this group */
+ int state; /* current stable state */
+} vrrp_sgroup;
+
+
+/* parameters per virtual router -- rfc2338.6.1.2 */
typedef struct {
uint32_t addr; /* the ip address */
+ uint8_t mask; /* the ip address CIDR netmask */
int set; /* TRUE if addr is set */
} vip_addr;
-/* parameters per virtual router -- rfc2338.6.1.2 */
typedef struct _vrrp_rt {
char *iname; /* Instance Name */
- char *isync; /* Instance Name to be sync with */
+ vrrp_sgroup *sync;
interface *ifp; /* Interface we belong to */
+ uint32_t mcast_saddr; /* Src IP address to use in VRRP IP header */
char *lvs_syncd_if; /* handle LVS sync daemon state using this
* instance FSM & running on specific interface
* => eth0 for example.
*/
-
int vrid; /* virtual id. from 1(!) to 255 */
int priority; /* priority value */
int naddr; /* number of ip addresses */
#define VRRP_MIN(a, b) ((a) < (b)?(a):(b))
#define VRRP_MAX(a, b) ((a) > (b)?(a):(b))
+#define VRRP_PKT_SADDR(V) (((V)->mcast_saddr)?(V)->mcast_saddr:IF_ADDR((V)->ifp))
+
/* prototypes */
extern int open_vrrp_socket(const int proto, const int index);
extern void new_vrrp_socket(vrrp_rt *vrrp);
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
+ typedef __uint32_t u32;
+ typedef __uint16_t u16;
+ typedef __uint8_t u8;
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/ip.h>
#endif
#include <stdlib.h>
#include <stdio.h>
+#include <linux/ethtool.h>
/* local include */
#include "scheduler.h"
return status;
}
+static int if_ethtool_status(const int fd)
+{
+ struct ethtool_value edata;
+ int err = 0;
+
+ edata.cmd = ETHTOOL_GLINK;
+ ifr.ifr_data = (caddr_t)&edata;
+ err = ioctl(fd, SIOCETHTOOL, &ifr);
+ if (err == 0)
+ return (edata.data)?1:0;
+ else
+ return -1;
+}
+
+int if_ethtool_probe(const char *ifname)
+{
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+ int status = 0;
+
+ if (fd < 0) return -1;
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+ status = if_ethtool_status(fd);
+ close(fd);
+ return status;
+}
+
+void if_ioctl_flags(interface *ifp)
+{
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if (fd < 0) return;
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, ifp->ifname, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+ close (fd);
+ return;
+ }
+ ifp->flags = ifr.ifr_flags;
+ close(fd);
+}
+
/* Interfaces lookup */
static void free_if(void *data)
{
break;
}
- /* MII registers supported ? */
+ /* MII channel supported ? */
if (IF_MII_SUPPORTED(ifp))
syslog(LOG_INFO, " NIC support MII regs");
+ else if (IF_ETHTOOL_SUPPORTED(ifp))
+ syslog(LOG_INFO, " NIC support EHTTOOL GLINK interface");
+ else
+ syslog(LOG_INFO, " Enabling NIC ioctl refresh polling");
}
static void init_if_queue(void)
for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
ifp = ELEMENT_DATA(e);
+ ifp->lb_type = LB_IOCTL;
status = if_mii_probe(ifp->ifname);
- if (status < 0)
- ifp->mii = 0;
- else {
- ifp->mii = 1;
- ifp->mii_linkbeat = (status)?1:0;
+ if (status >= 0) {
+ ifp->lb_type = LB_MII;
+ ifp->linkbeat = (status)?1:0;
+ } else {
+ status = if_ethtool_probe(ifp->ifname);
+ if (status >= 0) {
+ ifp->lb_type = LB_ETHTOOL;
+ ifp->linkbeat = (status)?1:0;
+ }
}
}
}
-static void if_mii_refresh(void)
+static void if_linkbeat_refresh(void)
{
interface *ifp;
element e;
for (e = LIST_HEAD(if_queue); e; ELEMENT_NEXT(e)) {
ifp = ELEMENT_DATA(e);
- if (IF_MII_SUPPORTED(ifp)) {
- if (IF_LINK_ISUP(ifp->ifname))
- ifp->mii_linkbeat = 1;
- else
- ifp->mii_linkbeat = 0;
- }
+ if (IF_MII_SUPPORTED(ifp))
+ ifp->linkbeat = (if_mii_probe(ifp->ifname))?1:0;
+ else if (IF_ETHTOOL_SUPPORTED(ifp))
+ ifp->linkbeat = (if_ethtool_probe(ifp->ifname))?1:0;
+ else
+ if_ioctl_flags(ifp);
}
}
-int if_mii_linkbeat(const interface *ifp)
+int if_linkbeat(const interface *ifp)
{
- if (IF_MII_SUPPORTED(ifp))
- return IF_MII_LINKBEAT(ifp);
+ if (IF_MII_SUPPORTED(ifp) || IF_ETHTOOL_SUPPORTED(ifp))
+ return IF_LINKBEAT(ifp);
return 1;
}
int if_monitor_thread(thread *thread)
{
/* If present, refresh link beat status from MII BMSR */
- if_mii_refresh();
+ if_linkbeat_refresh();
/* Register new monitor thread */
thread_add_timer(master, if_monitor_thread
init_if_queue();
netlink_interface_lookup();
init_if_mii();
-// dump_list(if_queue);
}
void if_mii_poller_init(void)
{
+// dump_list(if_queue);
+
/* Register NIC Heartbeat monitoring thread */
thread_add_timer(master, if_monitor_thread
, NULL
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "list.h"
/* types definition */
+#ifndef SIOCETHTOOL
+ #define SIOCETHTOOL 0x8946
+#endif
#ifndef SIOCGMIIPHY
#define SIOCGMIIPHY (SIOCDEVPRIVATE) /* Get the PHY in use. */
#define SIOCGMIIREG (SIOCDEVPRIVATE+1) /* Read a PHY register. */
#define ARPHRD_LOOPBACK 772
#define POLLING_DELAY 1
+/* Interface Linkbeat code selection */
+#define LB_IOCTL 0x1
+#define LB_MII 0x2
+#define LB_ETHTOOL 0x4
+
/* Interface structure definition */
typedef struct _interface {
char ifname[IF_NAMESIZ + 1]; /* Interface name */
unsigned int ifindex; /* Interface index */
uint32_t address; /* Interface main primary IP address */
-// list primary;
-// list secondary;
unsigned long flags; /* flags */
unsigned int mtu; /* MTU for this interface */
unsigned short hw_type; /* Type of hardware address */
u_char hw_addr[IF_HWADDR_MAX]; /* MAC address */
int hw_addr_len; /* MAC addresss length */
- int mii; /* Interface support MII regs ? */
- int mii_linkbeat; /* LinkBeat from MII BMSR req */
+ int lb_type; /* Interface regs selection */
+ int linkbeat; /* LinkBeat from MII BMSR req */
} interface;
/* Global interface queue */
#define IF_INDEX(X) ((X)->ifindex)
#define IF_ADDR(X) ((X)->address)
#define IF_HWADDR(X) ((X)->hw_addr)
-#define IF_LINK_ISUP(X) (if_mii_probe(X))
-#define IF_MII_SUPPORTED(X) ((X)->mii)
-#define IF_MII_LINKBEAT(X) ((X)->mii_linkbeat)
+#define IF_MII_SUPPORTED(X) ((X)->lb_type & LB_MII)
+#define IF_ETHTOOL_SUPPORTED(X) ((X)->lb_type & LB_ETHTOOL)
+#define IF_LINKBEAT(X) ((X)->linkbeat)
#define IF_ISUP(X) (((X)->flags & IFF_UP) && \
((X)->flags & IFF_RUNNING) && \
- if_mii_linkbeat(X))
+ if_linkbeat(X))
/* prototypes */
extern interface *if_get_by_ifindex(const int ifindex);
extern interface *if_get_by_ifname(const char *ifname);
-extern int if_mii_linkbeat(const interface *ifp);
+extern int if_linkbeat(const interface *ifp);
extern int if_mii_probe(const char *ifname);
+extern int if_ethtool_probe(const char *ifname);
extern void if_mii_poller_init(void);
extern void if_add_queue(interface *ifp);
extern int if_monitor_thread(thread *thread);
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "utils.h"
/* Add/Delete IP address to a specific interface */
-int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd)
+int netlink_address_ipv4(int ifindex, uint32_t addr, uint8_t mask, int cmd)
{
struct nl_handle nlh;
int status = 1;
req.n.nlmsg_type = cmd ? RTM_NEWADDR:RTM_DELADDR;
req.ifa.ifa_family = AF_INET;
req.ifa.ifa_index = ifindex;
- req.ifa.ifa_prefixlen = 32;
-
- addr = htonl(addr);
+ req.ifa.ifa_prefixlen = mask;
addattr_l(&req.n, sizeof(req), IFA_LOCAL, &addr, sizeof(addr));
if (netlink_socket(&nlh, 0) < 0)
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define VRRP_IPADDRESS_ADD 1
/* prototypes */
-extern int netlink_address_ipv4(int ifindex, uint32_t addr, int cmd);
+extern int netlink_address_ipv4(int ifindex, uint32_t addr
+ , uint8_t mask
+ , int cmd);
#endif
* authentication data encryption using HMAC MD5 according to
* RFCs 2085 & 2104.
*
- * Version: $Id: vrrp_ipsecah.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include <sys/uio.h>
/* local include */
+#include "check_api.h"
#include "vrrp_netlink.h"
#include "vrrp_if.h"
#include "memory.h"
struct ifaddrmsg *ifa;
struct rtattr *tb[IFA_MAX + 1];
interface *ifp;
+ uint32_t address = 0;
int len;
ifa = NLMSG_DATA(h);
if (!ifp)
return 0;
- if (ifa->ifa_flags & IFA_F_SECONDARY)
- return 0;
-
if (tb[IFA_ADDRESS] == NULL)
tb[IFA_ADDRESS] = tb[IFA_LOCAL];
if (ifp->flags & IFF_POINTOPOINT) {
- if (tb[IFA_LOCAL]) {
- ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
- } else {
- if (tb[IFA_ADDRESS])
- ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
- }
+ if (tb[IFA_LOCAL])
+ address = *(uint32_t *)RTA_DATA(tb[IFA_LOCAL]);
} else {
if (tb[IFA_ADDRESS])
- ifp->address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]);
+ address = *(uint32_t *)RTA_DATA(tb[IFA_ADDRESS]);
}
+ /* If no address is set on interface then set the first time */
+ if (!ifp->address)
+ ifp->address = address;
+
+ /* Refresh checkers state */
+ update_checker_activity(address, (h->nlmsg_type == RTM_NEWADDR)?1:0);
return 0;
}
-/* Interface lookup bootstrap function */
+/* Interfaces lookup bootstrap function */
int netlink_interface_lookup(void)
{
struct nl_handle nlh;
/* Interface lookup */
if (netlink_request(&nlh, AF_PACKET, RTM_GETLINK) < 0) {
status = -1;
- goto end;
+ goto end_int;
}
status = netlink_parse_info(netlink_if_link_filter, &nlh);
+end_int:
+ netlink_close(&nlh);
+ return status;
+}
+
+/* Adresses lookup bootstrap function */
+static int netlink_address_lookup(void)
+{
+ struct nl_handle nlh;
+ int status = 0;
+
+ if (netlink_socket(&nlh, 0) < 0)
+ return -1;
+
/* Address lookup */
if (netlink_request(&nlh, AF_INET, RTM_GETADDR) < 0) {
status = -1;
- goto end;
+ goto end_addr;
}
status = netlink_parse_info(netlink_if_address_filter, &nlh);
-
-end:
+
+end_addr:
netlink_close(&nlh);
return status;
}
break;
case RTM_NEWADDR:
case RTM_DELADDR:
-// return netlink_if_address_filter(snl, h);
+ return netlink_if_address_filter(snl, h);
break;
default:
syslog(LOG_INFO, "Kernel is reflecting an unknown netlink nlmsg_type: %d"
{
unsigned long groups;
+ /* Start with a netlink address lookup */
+ netlink_address_lookup();
+
+ /*
+ * Prepare netlink kernel broadcast channel
+ * subscribtion. We subscribe to LINK and ADDR
+ * netlink broadcast messages.
+ */
groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
netlink_socket(&nl_kernel, groups);
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_scheduler.h"
#include "vrrp_ipsecah.h"
-#include "vrrp_netlink.h"
#include "vrrp_if.h"
#include "vrrp.h"
+#include "vrrp_sync.h"
#include "ipvswrapper.h"
#include "memory.h"
#include "list.h"
return 1;
}
-static vrrp_rt *vrrp_search_instance_isync(char *isync)
-{
- vrrp_rt *vrrp;
- list l = conf_data->vrrp;
- element e;
-
- for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
- vrrp = ELEMENT_DATA(e);
- if (strcmp(vrrp->iname, isync) == 0)
- return vrrp;
- }
- return NULL;
-}
-
static vrrp_rt *vrrp_search_instance(const int vrid)
{
vrrp_rt *vrrp;
, char *vrrp_buffer
, int len)
{
- vrrp_rt *vrrp_isync;
-
if (vrrp_state_fault_rx(vrrp, vrrp_buffer, len)) {
- if (vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state != VRRP_STATE_FAULT ||
- (vrrp_isync->state == VRRP_STATE_FAULT &&
- IF_ISUP(vrrp_isync->ifp))) {
+ if (vrrp->sync) {
+ if (vrrp_sync_leave_fault(vrrp)) {
syslog(LOG_INFO, "VRRP_Instance(%s) prio is higher than received advert"
, vrrp->iname);
vrrp_become_master(vrrp, vrrp_buffer, len);
, char *vrrp_buffer
, int len)
{
+/*
vrrp_rt *vrrp_isync;
if (vrrp->isync) {
}
}
}
+*/
}
static void vrrp_goto_master(vrrp_rt *vrrp)
static int vrrp_dispatcher_read_to(int fd)
{
vrrp_rt *vrrp;
- vrrp_rt *vrrp_isync;
int vrid = 0;
int prev_state = 0;
vrid = vrrp_timer_vrid_timeout(fd);
vrrp = vrrp_search_instance(vrid);
+ /* Run the FSM handler */
prev_state = vrrp->state;
VRRP_FSM_READ_TO(vrrp);
- /* handle master instance synchronization */
- if (prev_state == VRRP_STATE_BACK &&
- vrrp->state == VRRP_STATE_MAST &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_BACK) {
- syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
- , vrrp->iname
- , vrrp_isync->iname);
-
- /* Send the higher priority advert */
- syslog(LOG_INFO, "VRRP_Instance(%s) sending OWNER advert"
- , vrrp_isync->iname);
- vrrp_state_master_tx(vrrp_isync, VRRP_PRIO_OWNER);
- } else {
- /* Otherwise, we simply update remotes arp caches */
- vrrp_isync->state = VRRP_STATE_MAST;
- vrrp_send_gratuitous_arp(vrrp_isync);
- }
- }
-
- /* handle synchronization in FAULT state */
- if (prev_state == VRRP_STATE_MAST &&
- vrrp->state == VRRP_STATE_FAULT &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_MAST) {
- /*
- * We force sync instance to backup mode.
- * This reduce instance takeover to less than ms_down_timer.
- * => by default ms_down_timer is set to 3secs.
- * => Takeover will be less than 3secs !
- */
- //vrrp_isync->wantstate = VRRP_STATE_BACK;
- vrrp_isync->wantstate = VRRP_STATE_GOTO_FAULT;
- }
- }
-
- /*
- * 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 &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_FAULT) {
- syslog(LOG_INFO, "VRRP_Instance(%s) Transition to DUMMY MASTER"
- , vrrp->iname);
- vrrp->wantstate = VRRP_STATE_GOTO_DUMMY_MAST;
- }
- }
-
- /* previous state symetry */
- if (vrrp->state == VRRP_STATE_DUMMY_MAST &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_MAST)
- vrrp->state = VRRP_STATE_MAST;
- }
+ /* handle instance synchronization */
+ vrrp_sync_read_to(vrrp, prev_state);
/*
* We are sure the instance exist. So we can
static int vrrp_dispatcher_read(int fd)
{
vrrp_rt *vrrp;
- vrrp_rt *vrrp_isync;
char *vrrp_buffer;
struct iphdr *iph;
vrrp_pkt *hd;
return fd;
}
+ /* Run the FSM handler */
prev_state = vrrp->state;
VRRP_FSM_READ(vrrp, vrrp_buffer, len);
- /* handle backup instance synchronization */
- if (prev_state == VRRP_STATE_MAST &&
- vrrp->state == VRRP_STATE_BACK &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state == VRRP_STATE_MAST) {
- syslog(LOG_INFO, "VRRP_Instance(%s) must be sync with %s"
- , vrrp->iname
- , vrrp_isync->iname);
-
- /* Transition to BACKUP state */
- vrrp_isync->wantstate = VRRP_STATE_BACK;
- }
- }
-
- /*
- * Handle wanted transition to MASTER state.
- * When Instance not in FAULT state received a remote
- * lower priotity advert => For a new VRRP election.
- */
- if (vrrp->state == VRRP_STATE_BACK &&
- vrrp->wantstate == VRRP_STATE_GOTO_MASTER &&
- vrrp->isync) {
- vrrp_isync = vrrp_search_instance_isync(vrrp->isync);
-
- if (vrrp_isync->state != 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);
- }
- }
-
+ /* handle instance synchronization */
+ vrrp_sync_read(vrrp, prev_state);
/*
* Refresh sands only if found matching instance.
/* cleanup the room */
FREE(vrrp_buffer);
-
return fd;
}
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.5.9 2002/05/30 16:05:31 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include <string.h>
#include <stdint.h>
-/* local include */
+/* local includes */
#include "scheduler.h"
-#include "vrrp.h"
/*
* Our instance dispatcher use a socket pool.
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: VRRP synchronization framework.
+ *
+ * Version: $Id: vrrp_sync.c,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Author: Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "vrrp_sync.h"
+#include "vrrp_if.h"
+#include "data.h"
+
+/* extern global vars */
+extern data *conf_data;
+
+/* return the first group found for a specific instance */
+vrrp_sgroup *vrrp_get_sync_group(char *iname)
+{
+ int i;
+ char *str;
+ element e;
+ vrrp_sgroup *vgroup;
+ list l = conf_data->vrrp_sync_group;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vgroup = ELEMENT_DATA(e);
+ for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+ str = VECTOR_SLOT(vgroup->iname, i);
+ if (strcmp(str, iname) == 0)
+ return vgroup;
+ }
+ }
+ return NULL;
+}
+
+/* jointure between instance and group => iname */
+vrrp_rt *vrrp_get_instance(char *iname)
+{
+ vrrp_rt *vrrp;
+ list l = conf_data->vrrp;
+ element e;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vrrp = ELEMENT_DATA(e);
+ if (strcmp(vrrp->iname, iname) == 0)
+ return vrrp;
+ }
+ return NULL;
+}
+
+/* Leaving fault state */
+int vrrp_sync_leave_fault(vrrp_rt *vrrp)
+{
+ int i;
+ int not_fault = 0;
+ int is_up = 0;
+ 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 (IF_ISUP(isync->ifp))
+ is_up++;
+ if (isync != vrrp) {
+ if (isync->state != VRRP_STATE_FAULT)
+ not_fault++;
+ }
+ }
+
+ if (not_fault > 0 || is_up == VECTOR_SIZE(vgroup->iname)) {
+ syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state"
+ , GROUP_NAME(vrrp->sync));
+ vgroup->state = VRRP_STATE_MAST;
+ return 1;
+ }
+ return 0;
+}
+
+static void vrrp_sync_backup(vrrp_rt *vrrp)
+{
+ int i;
+ char *str;
+ vrrp_rt *isync;
+ vrrp_sgroup *vgroup = vrrp->sync;
+
+ 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)
+ isync->wantstate = VRRP_STATE_BACK;
+ }
+ vgroup->state = VRRP_STATE_BACK;
+}
+
+static void vrrp_sync_master_to(vrrp_rt *vrrp)
+{
+ int i;
+ char *str;
+ vrrp_rt *isync;
+ vrrp_sgroup *vgroup = vrrp->sync;
+
+ syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances 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);
+
+ /* 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;
+ }
+ }
+ vgroup->state = VRRP_STATE_MAST;
+}
+
+static void vrrp_sync_fault_to(vrrp_rt *vrrp)
+{
+ int i;
+ char *str;
+ vrrp_rt *isync;
+ vrrp_sgroup *vgroup = vrrp->sync;
+
+ syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to FAULT 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);
+
+ /*
+ * We force sync instance to backup mode.
+ * This reduce instance takeover to less than ms_down_timer.
+ * => by default ms_down_timer is set to 3secs.
+ * => Takeover will be less than 3secs !
+ */
+ if (isync != vrrp)
+ if (isync->state == VRRP_STATE_MAST)
+ isync->wantstate = VRRP_STATE_GOTO_FAULT;
+ }
+ vgroup->state = 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: vrrp_sync.c include file.
+ *
+ * Version: $Id: vrrp_sync.h,v 0.6.1 2002/06/13 15:12:26 acassen Exp $
+ *
+ * Author: Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _VRRP_SYNC_H
+#define _VRRP_SYNC_H
+
+/* system include */
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdint.h>
+
+/* local include */
+#include "vrrp.h"
+
+
+/* MACRO definition */
+#define GROUP_STATE(G) ((G)->state)
+#define GROUP_NAME(G) ((G)->gname)
+
+/* extern prototypes */
+extern vrrp_sgroup *vrrp_get_sync_group(char *iname);
+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);
+
+#endif