* keepalived-0.6.4 released.
* Rewrote the previous ip address utilities functions. Review the string
to ulong convertion function to support CIDR filtering and more simple
handling ("without all hexadecimal and shorthand"), pickted from Paul
Vixie code.
* VRRP : extended the notify framework to support scripts inside a
vrrp_sync_group. view the sample/keepalived.conf.vrrp.sync file.
* VRRP : Review the previous vrrp_sync_group block. New declaration
is : view the sample/keepalived.conf.vrrp.sync file.
* VRRP : fixed a FSM sync_group side effect in FAULT state.
* Fixed a Kernel 2.2 code selection issue (ETHTOOL).
* Added support to wensong libipvs.
* Fixed a sorry_server cleanup side effect.
* Alex Karamasov, <alex@incredimail.com> fine the keepalived.init script
to be compatible with redhat chkconfig.
are functional.
* Fixed some issue in the autoconf/automake scripts.
+2002-06-25 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-0.6.4 released.
+ * Rewrote the previous ip address utilities functions. Review the string
+ to ulong convertion function to support CIDR filtering and more simple
+ handling ("without all hexadecimal and shorthand"), pickted from Paul
+ Vixie code.
+ * VRRP : extended the notify framework to support scripts inside a
+ vrrp_sync_group. view the sample/keepalived.conf.vrrp.sync file.
+ * VRRP : Review the previous vrrp_sync_group block. New declaration
+ is : view the sample/keepalived.conf.vrrp.sync file.
+ * VRRP : fixed a FSM sync_group side effect in FAULT state.
+ * Fixed a Kernel 2.2 code selection issue (ETHTOOL).
+ * Added support to wensong libipvs.
+ * Fixed a sorry_server cleanup side effect.
+ * Alex Karamasov, <alex@incredimail.com> fine the keepalived.init script
+ to be compatible with redhat chkconfig.
+
2002-06-18 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.6.3 released.
* VRRP : Christian Motelet, <cmotelet@canal-plus.com> pointed out a
flapping issue when runing vrrp_sync_group on multiple NICs. This have
been fixed adding leave FAULT state transition on both FSM state (read
& read_to). The group leave fault state if all NIC of each VRRP Instance
- are working.
- * Fixed some issues in the autoconf/automake scripts.
+ are functional.
+ * Fixed some issue in the autoconf/automake scripts.
2002-06-16 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.6.2 released.
Kernel/User netlink socket
Network firewalls (for Kernel 2.2)
- Routing messages
LinuxVirtualServer
Keepalived support all LVS code : including IPVS code for kernel 2.2
and kernel 2.4
-Library needing
-===============
+Libraries dependency
+====================
In order to compile Keepalived needs the following libraries :
CFLAGS = @CFLAGS@ \
-Wall -Wunused -Wstrict-prototypes \
-D$(KERNEL) -D$(VRRP_FLAG) @DFLAGS@
-LDFLAGS = @LIBS@ @LDFLAGS@ @LIBFW@
+LDFLAGS = @LIBS@ @LDFLAGS@
IPVSFLAGS = -D$(IPVS_FLAG) -D@IPVS_SYNCD@
-CORE_OBJS = @LIBOBJS@ \
+CORE_OBJS = \
main.o \
memory.o \
daemon.o \
ifeq ($(VRRP_FLAG),_WITH_VRRP_)
VRRP_OBJS = \
vrrp.o \
+ vrrp_notify.o \
vrrp_scheduler.o \
vrrp_sync.o \
vrrp_netlink.o \
CIFLAGS = -D$(CI_LINUX)
endif
-OBJS = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS) $(CI_LINUX_OBJ)
+ifeq ($(KERNEL),_KRNL_2_2_)
+IPVS_OBJS := $(IPVS_OBJS) ipfwwrapper.o
+LIBIPFW = libipfwc/libipfwc.a
+else
+LIBIPVS = libipvs/libipvs.a
+endif
+
+
+OBJS = $(CORE_OBJS) $(IPVS_OBJS) $(VRRP_OBJS) $(CI_LINUX_OBJ) $(LIBIPVS) $(LIBIPFW)
.c.o:
$(CC) -o $@ $(CFLAGS) $(IPVSFLAGS) $(CIFLAGS) $(INCLUDE) -c $*.c
libipfwc/libipfwc.a:
cd libipfwc/ && $(MAKE) libipfwc.a
+libipvs/libipvs.a:
+ cd libipvs/ && $(MAKE) libipvs.a
subclean:
ifeq ($(KERNEL),_KRNL_2_2_)
cd libipfwc/ && $(MAKE) clean
+else
+ cd libipvs/ && $(MAKE) clean
endif
cd genhash/ && $(MAKE) clean
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_api.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
{
checker *checker = data;
syslog(LOG_INFO, " %s:%d"
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(CHECKER_RPORT(checker)));
(*checker->dump) (checker);
}
if (CHECKER_VIP(checker) == address) {
if (!CHECKER_ENABLED(checker) && enable) {
syslog(LOG_INFO, "Netlink reflector reports IP %s added"
- , ip_ntoa(address));
+ , inet_ntop2(address));
syslog(LOG_INFO, "Activating healtchecker for VIP %s"
- , ip_ntoa(address));
+ , inet_ntop2(address));
}
if (CHECKER_ENABLED(checker) && !enable) {
syslog(LOG_INFO, "Netlink reflector reports IP %s removed"
- , ip_ntoa(address));
+ , inet_ntop2(address));
syslog(LOG_INFO, "Suspending healtchecker for VIP %s"
- , ip_ntoa(address));
+ , inet_ntop2(address));
}
checker->enabled = enable;
}
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_api.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
*
- * Version: $Id: check_ci.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_ci.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
return -1;
}
- nodemap[node_number].addr_ip = inet_addr(buf);
+ inet_ston(buf, &nodemap[node_number].addr_ip);
if (fscanf(fp, "%[^\n]", buf) == EOF) {
syslog(LOG_ERR, "[CI-LINUX] %s File Format Error", CLUSTERTAB);
return -1;
*
* Part: check_ci.c include file.
*
- * Version: $Id: check_ci.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_ci.h,v 0.6.4 2002/06/25 20:18:34 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.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_http.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Retry %s server [%s:%d] after %d retry."
, debug_msg
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port)
, http_arg->retry_it - 1);
#endif
if (checker->rs)
syslog(LOG_DEBUG, "Timeout %s server [%s:%d]."
, debug_msg
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
/* check if server is currently alive */
#ifdef _DEBUG_
syslog(LOG_DEBUG, "MD5SUM to [%s:%d] url(%d) = [%s]."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port)
, http_arg->url_it + 1
, digest_tmp);
#ifdef _DEBUG_
syslog(LOG_DEBUG, "MD5 digest error to [%s:%d] url(%d)"
", expecting MD5SUM [%s]."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port)
, http_arg->url_it + 1
, fetched_url->digest);
} else {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "MD5 digest success to [%s:%d] url(%d)."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port)
, http_arg->url_it + 1);
#endif
/* We have encourred a real read error */
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Read error with server [%s:%d]: %s"
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port)
, strerror(errno));
#endif
snprintf(str_request, GET_REQUEST_BUFFER_LENGTH
, REQUEST_TEMPLATE
, fetched_url->path
- , (vhost)?vhost:ip_ntoa(CHECKER_RIP(checker))
+ , (vhost)?vhost:inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Processing url(%d) of [%s:%d]."
, http_arg->url_it + 1
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
if (!ret) {
syslog(LOG_INFO, "Cannot send get request to [%s:%d]."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
/* check if server is currently alive */
case connect_error:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Error connecting server [%s:%d]."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
/* check if server is currently alive */
*/
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Remote Web server [%s:%d] connected."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
thread_add_write(thread->master, http_request_thread
} else {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Connection trouble to: [%s:%d]."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
if (http_get_check->proto == PROTO_SSL)
ssl_printerr(SSL_get_error(req->ssl, ret));
perform_svr_state(UP, checker->vs, checker->rs);
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Remote Web server [%s:%d] succeed on service."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
}
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.4 2002/06/25 20:18:34 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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_misc.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
*
* Part: check_misc.c include file.
*
- * Version: $Id: check_misc.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_misc.h,v 0.6.4 2002/06/25 20:18:34 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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_ssl.c,v 0.6.4 2002/06/25 20:18:34 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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.4 2002/06/25 20:18:34 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.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_tcp.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection to [%s:%d] success."
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
close(thread->u.fd);
} else {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection to [%s:%d] failed !!!"
- , ip_ntoa(CHECKER_RIP(checker))
+ , inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
#endif
*
* Part: check_tcp.c include file.
*
- * Version: $Id: check_tcp.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: check_tcp.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
-if test "$KERN" = "_KRNL_2_2_"; then
- LIBFW="libipfwc/libipfwc.a"
- LIBOBJS="$LIBOBJS ipfwwrapper.o"
- fi
-
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1635: checking for working const" >&5
+echo "configure:1630: 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 1640 "configure"
+#line 1635 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:1689: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1684: \"$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:1710: checking for pid_t" >&5
+echo "configure:1705: 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 1715 "configure"
+#line 1710 "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:1743: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1738: 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 1748 "configure"
+#line 1743 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1757: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1752: \"$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:1780: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:1775: 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 1786 "configure"
+#line 1781 "configure"
#include "confdefs.h"
#include <sgtty.h>
Autoconf TIOCGETP
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <<EOF
-#line 1804 "configure"
+#line 1799 "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:1826: checking return type of signal handlers" >&5
+echo "configure:1821: 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 1831 "configure"
+#line 1826 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
int i;
; return 0; }
EOF
-if { (eval echo configure:1848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1843: \"$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:1869: checking for $ac_func" >&5
+echo "configure:1864: 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 1874 "configure"
+#line 1869 "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:1897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1892: \"$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%@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
CEOF
EOF
if test -n "$LIBOBJS"; then
echo "Lib objects : $LIBOBJS"
fi
-if test -n "$LIBFW"; then
- echo "Firewall Lib : $LIBFW"
-fi
if test "${IPVS_SUPPORT}" = "_WITH_LVS_"; then
echo "Use IPVS Framework : Yes"
AC_SUBST(IPVS_SYNCD)
-dnl ----[ Create object list ]----
-if test "$KERN" = "_KRNL_2_2_"; then
- LIBFW="libipfwc/libipfwc.a"
- LIBOBJS="$LIBOBJS ipfwwrapper.o"
- AC_SUBST(LIBFW)dnl
- AC_SUBST(LIBOBJS)dnl
-fi
-
dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
AC_C_CONST
AC_TYPE_PID_T
if test -n "$LIBOBJS"; then
echo "Lib objects : $LIBOBJS"
fi
-if test -n "$LIBFW"; then
- echo "Firewall Lib : $LIBFW"
-fi
if test "${IPVS_SUPPORT}" = "_WITH_LVS_"; then
echo "Use IPVS Framework : Yes"
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: main.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: daemon.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: data.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
FREE(vgroup->gname);
free_strvec(vgroup->iname);
+ FREE_PTR(vgroup->script_backup);
+ FREE_PTR(vgroup->script_master);
+ FREE_PTR(vgroup->script_fault);
FREE(vgroup);
}
static void dump_vgroup(void *data)
str = VECTOR_SLOT(vgroup->iname, i);
syslog(LOG_INFO, " monitor = %s", str);
}
+ if (vgroup->script_backup)
+ syslog(LOG_INFO, " Backup state transition script = %s"
+ , vgroup->script_backup);
+ if (vgroup->script_master)
+ syslog(LOG_INFO, " Master state transition script = %s"
+ , vgroup->script_master);
+ if (vgroup->script_fault)
+ syslog(LOG_INFO, " Fault state transition script = %s"
+ , vgroup->script_fault);
}
static void free_vrrp(void *data)
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));
+ , inet_ntop2(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/%d", i+1, ip_ntoa(vrrp->vaddr[i].addr)
+ syslog(LOG_INFO, " VIP%d = %s/%d", i+1, inet_ntop2(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/%d", i+1, ip_ntoa(vrrp->evaddr[i].addr)
+ syslog(LOG_INFO, " E-VIP%d = %s/%d", i+1, inet_ntop2(vrrp->evaddr[i].addr)
, vrrp->evaddr[i].mask);
}
if (vrrp->script_backup)
if (vrrp->smtp_alert)
syslog(LOG_INFO, " Using smtp notification");
}
-void alloc_vrrp_sync_group(char *gname, vector iname)
+void alloc_vrrp_sync_group(char *gname)
{
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);
+ new->state = VRRP_STATE_BACK;
memcpy(new->gname, gname, size);
- new->iname = iname;
list_add(conf_data->vrrp_sync_group, new);
}
void alloc_vrrp_vip(char *vip)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- uint32_t ipaddr = ip_ston(vip);
- uint8_t mask = ip_stom(vip);
+ uint32_t ipaddr = 0;
+ uint8_t mask = inet_stom(vip);
+ inet_ston(vip, &ipaddr);
vrrp->naddr++;
if (vrrp->vaddr)
void alloc_vrrp_evip(char *vip)
{
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
- uint32_t ipaddr = ip_ston(vip);
- uint8_t mask = ip_stom(vip);
+ uint32_t ipaddr = 0;
+ uint8_t mask = inet_stom(vip);
+ inet_ston(vip, &ipaddr);
vrrp->neaddr++;
if (vrrp->evaddr)
syslog(LOG_INFO, " VS FWMARK = %d", vs->vfwmark);
else
syslog(LOG_INFO, " VIP = %s, VPORT = %d"
- , ip_ntoa(SVR_IP(vs))
+ , inet_ntop2(SVR_IP(vs))
, ntohs(SVR_PORT(vs)));
if (vs->virtualhost)
syslog(LOG_INFO, " VirtualHost = %s", vs->virtualhost);
, vs->timeout_persistence);
if (vs->granularity_persistence)
syslog(LOG_INFO, " persistence granularity = %s"
- , ip_ntoa(vs->granularity_persistence));
+ , inet_ntop2(vs->granularity_persistence));
syslog(LOG_INFO, " protocol = %s"
, (vs->service_type == IPPROTO_TCP)?"TCP":"UDP");
#ifdef _KRNL_2_2_
case 0:
syslog(LOG_INFO, " lb_kind = NAT");
- syslog(LOG_INFO, " nat mask = %s", ip_ntoa(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");
if (vs->s_svr) {
syslog(LOG_INFO, " sorry server = %s:%d"
- , ip_ntoa(SVR_IP(vs->s_svr))
+ , inet_ntop2(SVR_IP(vs->s_svr))
, ntohs(SVR_PORT(vs->s_svr)));
}
if (!LIST_ISEMPTY(vs->rs))
if (!strcmp(ip, "fwmark")) {
new->vfwmark = atoi(port);
} else {
- new->addr_ip = inet_addr(ip);
+ inet_ston(ip, &new->addr_ip);
new->addr_port = htons(atoi(port));
}
new->delay_loop = KEEPALIVED_DEFAULT_DELAY;
vs->s_svr = (real_server *)MALLOC(sizeof(real_server));
vs->s_svr->weight = 1;
- vs->s_svr->addr_ip = inet_addr(ip);
+ inet_ston(ip, &vs->s_svr->addr_ip);
vs->s_svr->addr_port = htons(atoi(port));
}
{
real_server *rs = data;
syslog(LOG_INFO, " RIP = %s, RPORT = %d, WEIGHT = %d"
- , ip_ntoa(SVR_IP(rs))
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs))
, rs->weight);
}
new = (real_server *)MALLOC(sizeof(real_server));
- new->addr_ip = inet_addr(ip);
+ inet_ston(ip, &new->addr_ip);
new->addr_port = htons(atoi(port));
new->alive = 1;
new = (real_server *)MALLOC(sizeof(real_server));
- new->addr_ip = inet_addr(ip);
+ inet_ston(ip, &new->addr_ip);
new->addr_port = htons(atoi(port));
new->alive = 1;
if (conf_data->lvs_id)
syslog(LOG_INFO, " LVS ID = %s", conf_data->lvs_id);
if (conf_data->smtp_server)
- syslog(LOG_INFO, " Smtp server = %s", ip_ntoa(conf_data->smtp_server));
+ syslog(LOG_INFO, " Smtp server = %s", inet_ntop2(conf_data->smtp_server));
if (conf_data->smtp_connection_to)
syslog(LOG_INFO, " Smtp server connection timeout = %d"
, conf_data->smtp_connection_to);
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: data.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* 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_sync_group(char *gname);
extern void alloc_vrrp(char *iname);
extern void alloc_vrrp_vip(char *vip);
extern void alloc_vrrp_evip(char *vip);
# processname: keepalived
# pidfile: /var/run/keepalived.pid
# config: /etc/keepalived/keepalived.conf
+# chkconfig: 2345 92 40
+# description: Start and stop Keepalived
# Global definitions
PID_FILE="/var/run/keepalived.pid"
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
if (!(errno & EINVAL)) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "ipfw_cmd : MASQ firewall rule [%s:%d] already exist."
- , ip_ntoa(SVR_IP(rs))
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs)));
#endif
}
#ifdef _DEBUG_
syslog(LOG_DEBUG, "ipfw_cmd : firewall error (%s) processing [%s:%d] MASQ rule."
, strerror(errno)
- , ip_ntoa(SVR_IP(rs))
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs)));
#endif
return IPFW_ERROR;
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 0.6.4 2002/06/25 20:18:34 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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int ipvs_syncd_cmd(int cmd, char *ifname, int state)
{
- syslog(LOG_INFO, "IPVS WRAPPER : Sync daemon not supported on kernel v2.2");
+ syslog(LOG_INFO, "IPVS : Sync daemon not supported on kernel v2.2");
return IPVS_ERROR;
}
ctl.u.vs_user.protocol = vs->service_type;
if(!parse_timeout(vs->timeout_persistence, &ctl.u.vs_user.timeout))
- syslog(LOG_INFO, "IPVS WRAPPER : Virtual service [%s:%d] illegal timeout."
- , ip_ntoa(SVR_IP(vs))
+ syslog(LOG_INFO, "IPVS : Virtual service [%s:%d] illegal timeout."
+ , inet_ntop2(SVR_IP(vs))
, ntohs(SVR_PORT(vs)));
if (ctl.u.vs_user.timeout != 0 || vs->granularity_persistence)
ctl.u.vs_user.vs_flags = IP_VS_SVC_F_PERSISTENT;
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sockfd == -1) {
- syslog(LOG_INFO, "IPVS WRAPPER : Can not initialize SOCK_RAW descriptor.");
+ syslog(LOG_INFO, "IPVS : Can not initialize SOCK_RAW descriptor.");
return IPVS_ERROR;
}
result = setsockopt(sockfd, IPPROTO_IP, IP_FW_MASQ_CTL, (char *)&ctl, sizeof(ctl));
if (errno == ESRCH) {
- syslog(LOG_INFO, "IPVS WRAPPER : Virtual service [%s:%d] not defined."
- , ip_ntoa(SVR_IP(vs))
+ syslog(LOG_INFO, "IPVS : Virtual service [%s:%d] not defined."
+ , inet_ntop2(SVR_IP(vs))
, ntohs(SVR_PORT(vs)));
close(sockfd);
return IPVS_ERROR;
} else if (errno == EEXIST) {
if (rs)
- syslog(LOG_INFO, "IPVS WRAPPER : Destination already exists [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
+ syslog(LOG_INFO, "IPVS : Destination already exists [%s:%d]."
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs)));
} else if (errno == ENOENT) {
if (rs)
- syslog(LOG_INFO, "IPVS WRAPPER : No such destination [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
+ syslog(LOG_INFO, "IPVS : No such destination [%s:%d]."
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs)));
}
#else /* KERNEL 2.4 LVS handling */
+static int ipvs_talk(int cmd, struct ip_vs_rule_user *urule)
+{
+ int result;
+
+ /* Init IPVS kernel channel */
+ if (ipvs_init()) {
+ syslog(LOG_INFO, "IPVS : Can't initialize ipvs: %s"
+ , ipvs_strerror(errno));
+ return IPVS_ERROR;
+ }
+
+ result = ipvs_command(cmd, urule);
+ if (result) {
+ syslog(LOG_INFO, "IPVS : %s", ipvs_strerror(errno));
+ ipvs_close();
+ return IPVS_ERROR;
+ }
+ ipvs_close();
+ return IPVS_SUCCESS;
+}
+
int ipvs_syncd_cmd(int cmd, char *ifname, int state)
{
#ifdef _HAVE_IPVS_SYNCD_
struct ip_vs_rule_user urule;
- int result = 0;
- int sockfd;
memset(&urule, 0, sizeof(struct ip_vs_rule_user));
- sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if (sockfd == -1) {
- syslog(LOG_INFO, "IPVS WRAPPER : Can not initialize SOCK_RAW descriptor.");
- return IPVS_ERROR;
- }
-
/* prepare user rule */
urule.state = state;
if (ifname != NULL)
strncpy(urule.mcast_ifn, ifname, IP_VS_IFNAME_MAXLEN);
- result = setsockopt(sockfd, IPPROTO_IP, cmd, (char *)&urule, sizeof(urule));
-
- if (result) {
- syslog(LOG_INFO, "IPVS WRAPPER : setsockopt failed !!!");
-
- switch (cmd) {
- case IP_VS_SO_SET_STARTDAEMON:
- if (errno == EEXIST)
- syslog(LOG_INFO, "IPVS WRAPPER: Sync_daemon is already running");
- break;
- case IP_VS_SO_SET_STOPDAEMON:
- if (errno == ESRCH)
- syslog(LOG_INFO, "IPVS WRAPPER: Sync_daemon is not running");
- break;
- }
- }
-
- close(sockfd);
- return IPVS_SUCCESS;
+ /* Talk to the IPVS channel */
+ return ipvs_talk(cmd, &urule);
#else
- syslog(LOG_INFO, "IPVS WRAPPER : Sync daemon not supported on kernel v2.2");
+ syslog(LOG_INFO, "IPVS : Sync daemon not supported");
return IPVS_ERROR;
#endif
}
int ipvs_cmd(int cmd, virtual_server *vs, real_server *rs)
{
struct ip_vs_rule_user urule;
- int result=0;
- int sockfd;
memset(&urule, 0, sizeof(struct ip_vs_rule_user));
strncpy(urule.sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
urule.weight = 1;
urule.conn_flags = vs->loadbalancing_kind;
- urule.netmask = ((u_int32_t) 0xffffffff);
+ urule.netmask = ((u_int32_t) 0xffffffff);
urule.protocol = vs->service_type;
if (!parse_timeout(vs->timeout_persistence, &urule.timeout))
- syslog(LOG_INFO, "IPVS WRAPPER : Virtual service [%s:%d] illegal timeout."
- , ip_ntoa(SVR_IP(vs))
+ syslog(LOG_INFO, "IPVS : Virtual service [%s:%d] illegal timeout."
+ , inet_ntop2(SVR_IP(vs))
, ntohs(SVR_PORT(vs)));
if (urule.timeout != 0 || vs->granularity_persistence)
urule.vs_flags = IP_VS_SVC_F_PERSISTENT;
urule.dport = SVR_PORT(rs);
}
- sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if (sockfd == -1) {
- syslog(LOG_INFO, "IPVS WRAPPER : Can not initialize SOCK_RAW descriptor.");
- return IPVS_ERROR;
- }
-
- result = setsockopt(sockfd, IPPROTO_IP, cmd, (char *)&urule, sizeof(urule));
-
- /* kernel return error handling */
-
- if (result) {
- syslog(LOG_INFO, "IPVS WRAPPER : setsockopt failed !!!");
-
- switch (cmd) {
- case IP_VS_SO_SET_ADD:
- if (errno == EEXIST)
- syslog(LOG_INFO, "IPVS WRAPPER : Destination already exists [%s:%d]."
- , ip_ntoa(SVR_IP(vs))
- , ntohs(SVR_PORT(vs)));
- else if (errno == ENOENT) {
- syslog(LOG_INFO, "IPVS WRAPPER : Scheduler not found: ip_vs_%s.o !!!"
- , urule.sched_name);
- close(sockfd);
- return IPVS_ERROR;
- }
- break;
-
- case IP_VS_SO_SET_DEL:
- if (errno == ESRCH)
- syslog(LOG_INFO, "IPVS WRAPPER : No such service [%s:%d]."
- , ip_ntoa(SVR_IP(vs))
- , ntohs(SVR_PORT(vs)));
- close(sockfd);
- return IPVS_ERROR;
- break;
-
- case IP_VS_SO_SET_ADDDEST:
- if (errno == ESRCH)
- syslog(LOG_INFO, "IPVS WRAPPER : Service not defined [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
- , ntohs(SVR_PORT(rs)));
- else if (errno == EEXIST)
- syslog(LOG_INFO, "IPVS WRAPPER : Destination already exists [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
- , ntohs(SVR_PORT(rs)));
- break;
-
- case IP_VS_SO_SET_DELDEST:
- if (errno == ESRCH)
- syslog(LOG_INFO, "IPVS WRAPPER : Service not defined [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
- , ntohs(SVR_PORT(rs)));
- else if (errno == ENOENT)
- syslog(LOG_INFO, "IPVS WRAPPER : No such destination [%s:%d]."
- , ip_ntoa(SVR_IP(rs))
- , ntohs(SVR_PORT(rs)));
- break;
- }
- }
-
- close(sockfd);
- return IPVS_SUCCESS;
+ /* Talk to the IPVS channel */
+ return ipvs_talk(cmd, &urule);
}
#endif
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#ifdef _KRNL_2_2_
#include <linux/ip_fw.h>
#include <net/ip_masq.h>
+#else
+ #include "libipvs/libipvs.h"
#endif
#include <net/ip_vs.h>
#endif
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $id: ipwrapper.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
real_server_group *group;
/* Processing real server queue */
- if (!LIST_ISEMPTY(vs->rs))
- if (!clear_service_rs(vs, vs->rs))
+ if (!LIST_ISEMPTY(vs->rs)) {
+ if (vs->s_svr->alive) {
+ if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr))
+ return 0;
+ } else if (!clear_service_rs(vs, vs->rs))
return 0;
+ }
/* Processing real server group queue */
if (!LIST_ISEMPTY(vs->rs_group)) {
if (vs->s_svr) {
if (vs->s_svr->alive) {
syslog(LOG_INFO, "Removing sorry server [%s:%d] from VS [%s:%d]"
- , ip_ntoa2(SVR_IP(vs->s_svr), rsip)
+ , inet_ntoa2(SVR_IP(vs->s_svr), rsip)
, ntohs(SVR_PORT(vs->s_svr))
- , ip_ntoa2(SVR_IP(vs), vsip)
+ , inet_ntoa2(SVR_IP(vs), vsip)
, ntohs(SVR_PORT(vs)));
vs->s_svr->alive = 0;
rs->alive = alive;
syslog(LOG_INFO, "Adding service [%s:%d] to VS [%s:%d]"
- , ip_ntoa2(SVR_IP(rs), rsip)
+ , inet_ntoa2(SVR_IP(rs), rsip)
, ntohs(SVR_PORT(rs))
- , ip_ntoa2(SVR_IP(vs), vsip)
+ , inet_ntoa2(SVR_IP(vs), vsip)
, ntohs(SVR_PORT(vs)));
ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs);
rs->alive = alive;
syslog(LOG_INFO, "Removing service [%s:%d] from VS [%s:%d]"
- , ip_ntoa2(SVR_IP(rs), rsip)
+ , inet_ntoa2(SVR_IP(rs), rsip)
, ntohs(SVR_PORT(rs))
- , ip_ntoa2(SVR_IP(vs), vsip)
+ , inet_ntoa2(SVR_IP(vs), vsip)
, ntohs(SVR_PORT(vs)));
/* server is down, it is removed from the LVS realserver pool */
/* if all the realserver pool is down, we add sorry server */
if (vs->s_svr && all_realservers_down(vs)) {
syslog(LOG_INFO, "Adding sorry server [%s:%d] to VS [%s:%d]"
- , ip_ntoa2(SVR_IP(vs->s_svr), rsip)
+ , inet_ntoa2(SVR_IP(vs->s_svr), rsip)
, ntohs(SVR_PORT(vs->s_svr))
- , ip_ntoa2(SVR_IP(vs), vsip)
+ , inet_ntoa2(SVR_IP(vs), vsip)
, ntohs(SVR_PORT(vs)));
/* the sorry server is now up in the pool, we flag it alive */
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 0.6.4 2002/06/25 20:18:34 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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: layer4.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
if(thread->type == THREAD_WRITE_TIMEOUT) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection timeout to [%s:%d]."
- , ip_ntoa(addr_ip)
+ , inet_ntop2(addr_ip)
, ntohs(addr_port));
#endif
close(thread->u.fd);
if (ret) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection failed to [%s:%d]."
- , ip_ntoa(addr_ip)
+ , inet_ntop2(addr_ip)
, ntohs(addr_port));
#endif
close(thread->u.fd);
if (status != 0) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection to [%s:%d] still IN_PROGRESS."
- , ip_ntoa(addr_ip)
+ , inet_ntop2(addr_ip)
, ntohs(addr_port));
#endif
case connect_error:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection ERROR to [%s:%d]."
- , ip_ntoa(SVR_IP(checker->rs))
+ , inet_ntop2(SVR_IP(checker->rs))
, ntohs(SVR_PORT(checker->rs)));
#endif
close(fd);
case connect_success:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection SUCCESS to [%s:%d]."
- , ip_ntoa(SVR_IP(checker->rs))
+ , inet_ntop2(SVR_IP(checker->rs))
, ntohs(SVR_PORT(checker->rs)));
#endif
thread_add_write(thread->master, func, checker, fd, timeout);
case connect_in_progress:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "TCP connection to [%s:%d] now IN_PROGRESS."
- , ip_ntoa(SVR_IP(checker->rs))
+ , inet_ntop2(SVR_IP(checker->rs))
, ntohs(SVR_PORT(checker->rs)));
#endif
thread_add_write(thread->master, func, checker, fd, timeout);
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: layer4.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
--- /dev/null
+# Makefile to make libipvsc.
+
+CC = gcc
+COPTS = -g -O
+CFLAGS = -Wall -Wunused $(COPTS) -I/usr/src/linux/include
+
+libipvs.a: libipvs.a(libipvs.o)
+
+libipvsc.o: libipvs.h
+
+clean:
+ rm -f *.a *.o *~
--- /dev/null
+/*
+ * libipvs: Library for manipulating IPVS through [gs]etsockopt
+ *
+ * Version: $Id: libipvs.c,v 1.4 2001/11/23 14:34:17 wensong Exp $
+ *
+ * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "libipvs.h"
+
+#define SET_CMD(cmd) (cmd - IP_VS_BASE_CTL)
+#define GET_CMD(cmd) (cmd - IP_VS_BASE_CTL + 128)
+
+static int sockfd = -1;
+static int ipvs_cmd = 0;
+struct ip_vs_getinfo ipvs_info;
+
+
+int ipvs_init(void)
+{
+ socklen_t len;
+
+ len = sizeof(ipvs_info);
+ if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
+ return -1;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_INFO);
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO,
+ (char *)&ipvs_info, &len))
+ return -1;
+
+ return 0;
+}
+
+
+int ipvs_getinfo(void)
+{
+ socklen_t len;
+
+ len = sizeof(ipvs_info);
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_INFO);
+ return getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO,
+ (char *)&ipvs_info, &len);
+}
+
+
+unsigned int ipvs_version(void)
+{
+ return ipvs_info.version;
+}
+
+
+int ipvs_command(int cmd, struct ip_vs_rule_user *urule)
+{
+ ipvs_cmd = SET_CMD(cmd);
+ return setsockopt(sockfd, IPPROTO_IP,
+ cmd, (char *)urule, sizeof(*urule));
+}
+
+
+struct ip_vs_get_services *ipvs_get_services(void)
+{
+ struct ip_vs_get_services *get;
+ socklen_t len;
+
+ len = sizeof(*get) +
+ sizeof(struct ip_vs_service_user)*ipvs_info.num_services;
+ if (!(get = malloc(len)))
+ return NULL;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_SERVICES);
+ get->num_services = ipvs_info.num_services;
+ if (getsockopt(sockfd, IPPROTO_IP,
+ IP_VS_SO_GET_SERVICES, get, &len) < 0) {
+ free(get);
+ return NULL;
+ }
+ return get;
+}
+
+
+struct ip_vs_get_dests *ipvs_get_dests(struct ip_vs_service_user *svc)
+{
+ struct ip_vs_get_dests *d;
+ socklen_t len;
+
+ len = sizeof(*d) + sizeof(struct ip_vs_dest_user)*svc->num_dests;
+ if (!(d = malloc(len)))
+ return NULL;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_DESTS);
+ d->fwmark = svc->fwmark;
+ d->protocol = svc->protocol;
+ d->addr = svc->addr;
+ d->port = svc->port;
+ d->num_dests = svc->num_dests;
+
+ if (getsockopt(sockfd, IPPROTO_IP,
+ IP_VS_SO_GET_DESTS, d, &len) < 0) {
+ free(d);
+ return NULL;
+ }
+ return d;
+}
+
+struct ip_vs_service_user *
+ipvs_get_service(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport)
+{
+ struct ip_vs_service_user *svc;
+ socklen_t len;
+
+ len = sizeof(*svc);
+ if (!(svc = malloc(len)))
+ return NULL;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_SERVICE);
+ svc->fwmark = fwmark;
+ svc->protocol = protocol;
+ svc->addr = vaddr;
+ svc->port = vport;
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICE,
+ (char *)svc, &len)) {
+ free(svc);
+ return NULL;
+ }
+ return svc;
+}
+
+
+struct ip_vs_timeout_user *ipvs_get_timeouts(void)
+{
+ struct ip_vs_timeout_user *u;
+ socklen_t len;
+
+ len = sizeof(*u);
+ if (!(u = malloc(len)))
+ return NULL;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_TIMEOUTS);
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_TIMEOUTS,
+ (char *)u, &len)) {
+ free(u);
+ return NULL;
+ }
+ return u;
+}
+
+
+struct ip_vs_daemon_user *ipvs_get_daemon(void)
+{
+ struct ip_vs_daemon_user *u;
+ socklen_t len;
+
+ len = sizeof(*u);
+ if (!(u = malloc(len)))
+ return NULL;
+
+ ipvs_cmd = GET_CMD(IP_VS_SO_GET_DAEMON);
+ if (getsockopt(sockfd, IPPROTO_IP,
+ IP_VS_SO_GET_DAEMON, (char *)u, &len)) {
+ free(u);
+ return NULL;
+ }
+ return u;
+}
+
+
+void ipvs_close(void)
+{
+ close(sockfd);
+}
+
+
+const char *ipvs_strerror(int err)
+{
+ unsigned int i;
+ struct table_struct {
+ int cmd;
+ int err;
+ const char *message;
+ } table [] =
+ { { 0, EPERM, "Permission denied (you must be root)" },
+ { 0, EINVAL, "Module is wrong version" },
+ { 0, ENOPROTOOPT, "Protocol not available" },
+ { 0, ENOMEM, "Memory allocation problem" },
+ { SET_CMD(IP_VS_SO_SET_ADD), EEXIST, "Service already exists" },
+ { SET_CMD(IP_VS_SO_SET_ADD), ENOENT, "Scheduler not found" },
+ { SET_CMD(IP_VS_SO_SET_EDIT), ESRCH, "No such service" },
+ { SET_CMD(IP_VS_SO_SET_EDIT), ENOENT, "Scheduler not found" },
+ { SET_CMD(IP_VS_SO_SET_DEL), ESRCH, "No such service" },
+ { SET_CMD(IP_VS_SO_SET_ADDDEST), ESRCH, "Service not defined" },
+ { SET_CMD(IP_VS_SO_SET_ADDDEST), EEXIST,
+ "Destination already exists" },
+ { SET_CMD(IP_VS_SO_SET_EDITDEST), ESRCH, "Service not defined" },
+ { SET_CMD(IP_VS_SO_SET_EDITDEST), ENOENT, "No such destination" },
+ { SET_CMD(IP_VS_SO_SET_DELDEST), ESRCH, "Service not defined" },
+ { SET_CMD(IP_VS_SO_SET_DELDEST), ENOENT, "No such destination" },
+ { SET_CMD(IP_VS_SO_SET_STARTDAEMON), EEXIST,
+ "Daemon has already run" },
+ { SET_CMD(IP_VS_SO_SET_STOPDAEMON), ESRCH,
+ "No daemon is running" },
+ { SET_CMD(IP_VS_SO_SET_STOPDAEMON), ESRCH,
+ "No daemon is running" },
+ { SET_CMD(IP_VS_SO_SET_ZERO), ESRCH, "No such service" },
+ { GET_CMD(IP_VS_SO_GET_SERVICE), ESRCH, "No such service" },
+ { GET_CMD(IP_VS_SO_GET_DESTS), ESRCH, "No such service" },
+ };
+
+ for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
+ if ((!table[i].cmd || table[i].cmd == ipvs_cmd)
+ && table[i].err == err)
+ return table[i].message;
+ }
+
+ return strerror(err);
+}
--- /dev/null
+#ifndef _LIBIPVS_H
+#define _LIBIPVS_H
+
+#include <net/ip_vs.h>
+
+/* ipvs info variable */
+extern struct ip_vs_getinfo ipvs_info;
+
+/* init socket and get ipvs info */
+extern int ipvs_init(void);
+
+/* get ipvs info separately */
+extern int ipvs_getinfo(void);
+
+/* get the version number */
+extern unsigned int ipvs_version(void);
+
+/* set command */
+extern int ipvs_command(int cmd, struct ip_vs_rule_user *urule);
+
+/* get all the ipvs services */
+extern struct ip_vs_get_services *ipvs_get_services(void);
+
+/* get the destination array of the specified service */
+extern struct ip_vs_get_dests *ipvs_get_dests(struct ip_vs_service_user *svc);
+
+/* get ipvs service */
+extern struct ip_vs_service_user *
+ipvs_get_service(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport);
+
+/* get ipvs timeout */
+extern struct ip_vs_timeout_user *ipvs_get_timeouts(void);
+
+/* get ipvs daemon information */
+extern struct ip_vs_daemon_user *ipvs_get_daemon(void);
+
+/* close the socket */
+extern void ipvs_close(void);
+
+extern const char *ipvs_strerror(int err);
+
+#endif /* _LIBIPVS_H */
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: list.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: list.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: main.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: main.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x000603
-#define DATE_CODE 0x120602
+#define VERSION_CODE 0x000604
+#define DATE_CODE 0x190602
#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.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: memory.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: memory.h,v 0.6.4 2002/06/25 20:18:34 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.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: parser.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
}
static void smtpip_handler(vector strvec)
{
- conf_data->smtp_server = inet_addr(VECTOR_SLOT(strvec, 1));
+ inet_ston(VECTOR_SLOT(strvec, 1), &conf_data->smtp_server);
}
static void email_handler(vector strvec)
{
/* VRRP handlers */
static void vrrp_sync_group_handler(vector strvec)
{
- vector iname = read_value_block();
- alloc_vrrp_sync_group(VECTOR_SLOT(strvec, 1), iname);
+ alloc_vrrp_sync_group(VECTOR_SLOT(strvec, 1));
+}
+static void vrrp_group_handler(vector strvec)
+{
+ vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
+ vgroup->iname = read_value_block();
+}
+static void vrrp_gnotify_backup_handler(vector strvec)
+{
+ vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
+ vgroup->script_backup = set_value(strvec);
+ vgroup->notify_exec = 1;
+}
+static void vrrp_gnotify_master_handler(vector strvec)
+{
+ vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
+ vgroup->script_master = set_value(strvec);
+ vgroup->notify_exec = 1;
+}
+static void vrrp_gnotify_fault_handler(vector strvec)
+{
+ vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
+ vgroup->script_fault = set_value(strvec);
+ vgroup->notify_exec = 1;
}
static void vrrp_handler(vector strvec)
{
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));
+ inet_ston(VECTOR_SLOT(strvec, 1), &vrrp->mcast_saddr);
}
static void vrrp_vrid_handler(vector strvec)
{
static void natmask_handler(vector strvec)
{
virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
- vs->nat_mask = inet_addr(VECTOR_SLOT(strvec, 1));
+ inet_ston(VECTOR_SLOT(strvec, 1), &vs->nat_mask);
}
static void pto_handler(vector strvec)
{
static void pgr_handler(vector strvec)
{
virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
- vs->granularity_persistence = inet_addr(VECTOR_SLOT(strvec, 1));
+ inet_ston(VECTOR_SLOT(strvec, 1), &vs->granularity_persistence);
}
static void proto_handler(vector strvec)
{
process_stream(keywords);
}
-void init_keywords(void)
+static vector init_keywords(void)
{
keywords = vector_alloc();
/* VRRP Instance mapping */
install_keyword_root("vrrp_sync_group", &vrrp_sync_group_handler);
+ install_keyword("group", &vrrp_group_handler);
+ install_keyword("notify_backup", &vrrp_gnotify_backup_handler);
+ install_keyword("notify_master", &vrrp_gnotify_master_handler);
+ install_keyword("notify_fault", &vrrp_gnotify_fault_handler);
install_keyword_root("vrrp_instance", &vrrp_handler);
install_keyword("state", &vrrp_state_handler);
install_keyword("interface", &vrrp_int_handler);
install_checkers_keyword();
install_sublevel_end();
#endif
+
+ return keywords;
}
void init_data(char *conf_file)
}
/* Init Keywords structure */
- init_keywords();
- kw_root = keywords;
+ kw_root = init_keywords();
/* Dump configuration *
vector_dump(keywords);
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: parser.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* Prototypes */
-extern void init_keywords(void);
extern void init_data(char *conf_file);
extern void install_keyword(char *string, void (*handler)(vector));
extern void install_sublevel(void);
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: pidfile.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: pidfile.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
--- /dev/null
+! Configuration File for keepalived
+! CI-LINUX configuration sample
+
+global_defs {
+ notification_email {
+ lvs-alert@domain.com
+ }
+ notification_email_from email@domain.com
+ smtp_server 192.168.200.1
+ smtp_connect_timeout 30
+ lvs_id CI-LNX
+}
+
+virtual_server 192.168.200.10 80 {
+ delay_loop 10
+ lb_algo wrr
+ lb_kind NAT
+ protocol TCP
+
+ sorry_server 192.168.200.200 80
+
+ real_server 192.168.200.2 80 {
+ weight 1
+ CI-LINUX
+ }
+
+ real_server 192.168.200.3 80 {
+ weight 1
+ CI-LINUX
+ }
+ real_server 192.168.200.4 80 {
+ weight 1
+ CI-LINUX
+ }
+ real_server 192.168.200.5 80 {
+ weight 1
+ CI-LINUX
+ }
+}
! Configuration File for keepalived
! extra script call demonstration
+! scripts are supported in Instance and groupes
+! declarations.
+vrrp_sync_group G1 {
+ group {
+ VI_2
+ VI_3
+ }
+ notify_backup "/usr/local/bin/vrrp.back arg1 arg2"
+ notify_master "/usr/local/bin/vrrp.mast arg1 arg2"
+ notify_fault "/usr/local/bin/vrrp.fault arg1 arg2"
+}
vrrp_instance VI_1 {
state MASTER
192.168.200.17
192.168.200.18
}
-
notify_backup "/usr/local/bin/vrrp.sh BACKUP VI_1"
notify_master "/usr/local/bin/vrrp.sh MASTER VI_1"
notify_fault "/usr/local/bin/vrrp.sh FAULT VI_1"
+}
+
+vrrp_instance VI_2 {
+ interface eth0
+ state MASTER
+ virtual_router_id 52
+ priority 150
+ virtual_ipaddress {
+ 192.168.200.100/27
+ }
}
+
+vrrp_instance VI_3 {
+ interface eth0
+ state MASTER
+ virtual_router_id 53
+ priority 150
+ virtual_ipaddress {
+ 192.168.200.101/27
+ }
+}
+
! Configuration File for keepalived
vrrp_sync_group G1 {
- VI_1
- VI_2
- VI_5
- VI_6
- VI_7
- VI_8
- VI_9
+ group {
+ VI_1
+ VI_2
+ VI_5
+ VI_6
+ VI_7
+ VI_8
+ VI_9
+ }
+ notify_backup "/usr/local/bin/vrrp.back arg1 arg2"
+ notify_master "/usr/local/bin/vrrp.mast arg1 arg2"
+ notify_fault "/usr/local/bin/vrrp.fault arg1 arg2"
}
vrrp_sync_group G2 {
- VI_3
- VI_4
+ group {
+ VI_3
+ VI_4
+ }
}
vrrp_instance VI_1 {
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: scheduler.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: scheduler.h,v 0.6.4 2002/06/25 20:18:34 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.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: smtp.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
if (thread->type == THREAD_READ_TIMEOUT) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Timeout reading data to remote SMTP server [%s:%d].",
- ip_ntoa(conf_data->smtp_server),
+ inet_ntop2(conf_data->smtp_server),
SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
if (errno == EAGAIN) goto end;
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Error reading data to remote SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Received buffer from remote SMTP server [%s:%d]"
" overflow our get read buffer length."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
if (thread->type == THREAD_WRITE_TIMEOUT) {
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Timeout sending data to remote SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
case ERROR:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Can not send data to remote SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
/* we just cleanup the room */
case connect_error:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Error connecting SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
case connect_timeout:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Timeout writing data to SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
*/
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Remote SMTP server [%s:%d] connected."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
thread_add_write(thread->master, smtp_send_cmd_thread
case connect_error:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "SMTP connection ERROR to [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
case connect_timeout:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "Timeout connecting SMTP server [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
free_smtp_all(smtp_arg);
case connect_success:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "SMTP connection SUCCESS to [%s:%d]."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
break;
case connect_in_progress:
#ifdef _DEBUG_
syslog(LOG_DEBUG, "SMTP connection to [%s:%d] now IN_PROGRESS."
- , ip_ntoa(conf_data->smtp_server)
+ , inet_ntop2(conf_data->smtp_server)
, SMTP_PORT);
#endif
break;
snprintf(smtp_arg->subject, MAX_HEADERS_LENGTH
, "[%s] Realserver %s:%d - %s"
, conf_data->lvs_id
- , ip_ntoa(SVR_IP(rs))
+ , inet_ntop2(SVR_IP(rs))
, ntohs(SVR_PORT(rs))
, subject);
else if (vrrp)
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: smtp.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: timer.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: timer.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: utils.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
}
/* IP network to ascii representation */
-char *ip_ntoa(uint32_t ip)
+char *inet_ntop2(uint32_t ip)
{
static char buf[16];
unsigned char *bytep;
sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
return buf;
}
-char *ip_ntoa2(uint32_t ip, char *buf)
+
+/*
+ * IP network to ascii representation. To use
+ * for multiple IP address convertion into the same call.
+ */
+char *inet_ntoa2(uint32_t ip, char *buf)
{
unsigned char *bytep;
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 inet_stom(char *addr)
{
uint8_t mask = 32;
char *cp = addr;
+ if (!strstr(addr, "/"))
+ return mask;
while (*cp != '/' && *cp != '\0')
cp++;
if (*cp == '/')
return atoi(++cp);
return mask;
}
+
+/*
+ * IP string to network representation
+ * Highly inspired from Paul Vixie code.
+ */
+int inet_ston(const char *addr, uint32_t *dst)
+{
+ static char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+
+ while ((ch = *addr++) != '\0' && ch != '/') {
+ const char *pch;
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+ if (new > 255)
+ return 0;
+ *tp = new;
+ if (!saw_digit) {
+ if (++octets > 4)
+ return 0;
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return 0;
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return 0;
+ }
+
+ if (octets < 4)
+ return 0;
+
+ memcpy(dst, tmp, INADDRSZ);
+ return 1;
+}
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: utils.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>
+#include <arpa/nameser.h>
/* Prototypes defs */
extern void print_buffer(int count, char *buff);
-extern char *ip_ntoa(uint32_t ip);
-extern char *ip_ntoa2(uint32_t ip, char *buf);
-extern uint32_t ip_ston(char *addr);
-extern uint8_t ip_stom(char *addr);
+extern char *inet_ntop2(uint32_t ip);
+extern char *inet_ntoa2(uint32_t ip, char *buf);
+extern uint8_t inet_stom(char *addr);
+extern int inet_ston(const char* addr, uint32_t *dst);
#endif
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vector.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vector.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* local include */
#include <ctype.h>
#include "vrrp_scheduler.h"
+#include "vrrp_notify.h"
#include "ipvswrapper.h"
#include "vrrp.h"
#include "memory.h"
extern data *conf_data;
-/* Close all FDs >= a specified value */
-void closeall(int fd)
-{
- int fdlimit = sysconf(_SC_OPEN_MAX);
-
- while (fd < fdlimit)
- close(fd++);
-}
-
-static char *notify_get_script(vrrp_rt *vrrp, int state)
-{
- if (!vrrp->notify_exec)
- return NULL;
- if (state == VRRP_STATE_BACK)
- return vrrp->script_backup;
- if (state == VRRP_STATE_MAST)
- return vrrp->script_master;
- if (state == VRRP_STATE_FAULT)
- return vrrp->script_fault;
- return NULL;
-}
-static char *notify_script_name(char *cmdline)
-{
- char *cp = cmdline;
- char *script;
- int strlen;
-
- if (!cmdline)
- return NULL;
- while (!isspace((int) *cp) && *cp != '\0')
- cp++;
- strlen = cp - cmdline;
- script = MALLOC(strlen + 1);
- memcpy(script, cmdline, strlen);
- *(script + strlen) = '\0';
-
- return script;
-}
-/* Execute extern script/program */
-static int notify_exec(vrrp_rt *vrrp, int state)
-{
- char *script = notify_get_script(vrrp, state);
- char *script_name = notify_script_name(script);
- FILE *fOut;
- int err;
- pid_t pid;
-
- if (!script) return 0;
-
- fOut = fopen(script_name, "r");;
- if (!fOut) {
- syslog(LOG_INFO, "Can't open %s (errno %d %s)"
- , script_name
- , errno
- , strerror(errno));
- return -1;
- }
- FREE(script_name);
- fclose(fOut);
-
- pid = fork();
-
- /* In case of fork is error. */
- if (pid < 0) {
- syslog(LOG_INFO, "Failed fork process");
- return -1;
- }
-
- /* In case of this is parent process. */
- if (pid)
- return (0);
-
- closeall(0);
-
- open("/dev/null", O_RDWR);
- dup(0);
- dup(0);
-
- if (vrrp->debug > 0)
- syslog(LOG_INFO, "Trying to exec [%s]", script);
-
- err = system(script);
-
- if (err != 0) {
- if (err == 127)
- syslog(LOG_ALERT, "Failed to exec [%s]", script);
- else
- syslog(LOG_ALERT, "Error running [%s], error: %d", script, err);
- } else
- syslog(LOG_INFO, "Success executing [%s]", script);
-
- exit(0);
-}
-
/* compute checksum */
static u_short in_csum( u_short *addr, int len, u_short csum)
{
vadd->set = 0;
syslog(LOG_INFO, "cant %s the address %s to %s\n"
, cmd ? "set" : "remove"
- , ip_ntoa(vadd->addr)
+ , inet_ntop2(vadd->addr)
, IF_NAME(vrrp->ifp));
if (cmd == VRRP_IPADDRESS_ADD) {
syslog(LOG_INFO, "try to delete eventual stalled ip");
vrrp_send_gratuitous_arp(vrrp);
/* Check if notify is needed */
- notify_exec(vrrp, VRRP_STATE_MAST);
+ notify_instance_exec(vrrp, VRRP_STATE_MAST);
#ifdef _HAVE_IPVS_SYNCD_
/* Check if sync daemon handling is needed */
, vrrp->iname);
vrrp_restore_interface(vrrp, 0);
vrrp->state = vrrp->wantstate;
- notify_exec(vrrp, VRRP_STATE_BACK);
+ notify_instance_exec(vrrp, VRRP_STATE_BACK);
break;
case VRRP_STATE_GOTO_FAULT:
syslog(LOG_INFO, "VRRP_Instance(%s) Entering FAULT STATE"
, vrrp->iname);
vrrp_restore_interface(vrrp, 0);
vrrp->state = VRRP_STATE_FAULT;
- notify_exec(vrrp, VRRP_STATE_FAULT);
+ notify_instance_exec(vrrp, VRRP_STATE_FAULT);
break;
}
}
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* 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 */
+ char *gname; /* Group name */
+ vector iname; /* Set of VRRP instances in this group */
+ int state; /* current stable state */
+
+ /* State transition notification */
+ int notify_exec;
+ char *script_backup;
+ char *script_master;
+ char *script_fault;
} vrrp_sgroup;
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#endif
#include <stdlib.h>
#include <stdio.h>
+#ifdef _KRNL_2_4_
#include <linux/ethtool.h>
+#endif
/* local include */
#include "scheduler.h"
static int if_ethtool_status(const int fd)
{
+#ifdef _KRNL_2_4_
struct ethtool_value edata;
int err = 0;
if (err == 0)
return (edata.data)?1:0;
else
+#endif
return -1;
}
syslog(LOG_INFO, "------< NIC >------");
syslog(LOG_INFO, " Name = %s", ifp->ifname);
syslog(LOG_INFO, " index = %d", ifp->ifindex);
- syslog(LOG_INFO, " address = %s", ip_ntoa(ifp->address));
+ syslog(LOG_INFO, " address = %s", inet_ntop2(ifp->address));
/* FIXME: Harcoded for ethernet */
if (ifp->hw_type == ARPHRD_ETHER)
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 0.6.4 2002/06/25 20:18:34 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.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
--- /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 state transition notification scripts handling.
+ *
+ * Version: $Id: vrrp_notify.c,v 0.6.4 2002/06/25 20:18:34 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.
+ */
+
+/* system include */
+#include <ctype.h>
+
+/* local include */
+#include "vrrp_notify.h"
+#include "memory.h"
+
+/* Close all FDs >= a specified value */
+void closeall(int fd)
+{
+ int fdlimit = sysconf(_SC_OPEN_MAX);
+ while (fd < fdlimit)
+ close(fd++);
+}
+
+static char *get_iscript(vrrp_rt *vrrp, int state)
+{
+ if (!vrrp->notify_exec)
+ return NULL;
+ if (state == VRRP_STATE_BACK)
+ return vrrp->script_backup;
+ if (state == VRRP_STATE_MAST)
+ return vrrp->script_master;
+ if (state == VRRP_STATE_FAULT)
+ return vrrp->script_fault;
+ return NULL;
+}
+
+static char *get_gscript(vrrp_sgroup *vgroup, int state)
+{
+ if (!vgroup->notify_exec)
+ return NULL;
+ if (state == VRRP_STATE_BACK)
+ return vgroup->script_backup;
+ if (state == VRRP_STATE_MAST)
+ return vgroup->script_master;
+ if (state == VRRP_STATE_FAULT)
+ return vgroup->script_fault;
+ return NULL;
+}
+
+static char *notify_script_name(char *cmdline)
+{
+ char *cp = cmdline;
+ char *script;
+ int strlen;
+
+ if (!cmdline)
+ return NULL;
+ while (!isspace((int) *cp) && *cp != '\0')
+ cp++;
+ strlen = cp - cmdline;
+ script = MALLOC(strlen + 1);
+ memcpy(script, cmdline, strlen);
+ *(script + strlen) = '\0';
+
+ return script;
+}
+
+/* Execute extern script/program */
+static int notify_exec(const char *cmd)
+{
+ int err;
+ pid_t pid;
+
+ pid = fork();
+
+ /* In case of fork is error. */
+ if (pid < 0) {
+ syslog(LOG_INFO, "Failed fork process");
+ return -1;
+ }
+
+ /* In case of this is parent process. */
+ if (pid)
+ return (0);
+
+ closeall(0);
+
+ open("/dev/null", O_RDWR);
+ dup(0);
+ dup(0);
+
+ err = system(cmd);
+ if (err != 0) {
+ if (err == 127)
+ syslog(LOG_ALERT, "Failed to exec [%s]", cmd);
+ else
+ syslog(LOG_ALERT, "Error running [%s], error: %d", cmd, err);
+ } else
+ syslog(LOG_INFO, "Success executing [%s]", cmd);
+
+ exit(0);
+}
+
+static int script_open(char *script)
+{
+ char *script_name = notify_script_name(script);
+ FILE *fOut;
+
+ fOut = fopen(script_name, "r");;
+ if (!fOut) {
+ syslog(LOG_INFO, "Can't open %s (errno %d %s)"
+ , script_name
+ , errno
+ , strerror(errno));
+ return 0;
+ }
+ FREE(script_name);
+ fclose(fOut);
+ return 1;
+}
+
+int notify_instance_exec(vrrp_rt *vrrp, int state)
+{
+ char *script = get_iscript(vrrp, state);
+
+ if (!script || !script_open(script)) return 0;
+
+ /* Launch the script */
+ notify_exec(script);
+ return 1;
+}
+
+int notify_group_exec(vrrp_sgroup *vgroup, int state)
+{
+ char *script = get_gscript(vgroup, state);
+
+ if (!script || !script_open(script)) return 0;
+
+ /* Launch the script */
+ notify_exec(script);
+ return 1;
+}
--- /dev/null
+/*
+ * Soft: Vrrpd is an implementation of VRRPv2 as specified in rfc2338.
+ * VRRP is a protocol which elect a master server on a LAN. If the
+ * master fails, a backup server takes over.
+ * The original implementation has been made by jerome etienne.
+ *
+ * Part: vrrp_notify.c include file.
+ *
+ * Version: $Id: vrrp_notify.h,v 0.6.4 2002/06/25 20:18:34 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_NOTIFY_H
+#define _VRRP_NOTIFY_H
+
+/* local include */
+#include "vrrp.h"
+
+extern int notify_instance_exec(vrrp_rt *vrrp, int state);
+extern int notify_group_exec(vrrp_sgroup *vgroup, int state);
+
+#endif
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_if.h"
#include "vrrp.h"
#include "vrrp_sync.h"
+#include "vrrp_notify.h"
#include "ipvswrapper.h"
#include "memory.h"
#include "list.h"
static void vrrp_fault(vrrp_rt *vrrp)
{
- if (vrrp->sync) {
- if (vrrp_sync_group_up(vrrp->sync))
- syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state"
- , GROUP_NAME(vrrp->sync));
- else return;
+ vrrp_sgroup *vgroup = vrrp->sync;
+
+ if (vgroup) {
+ if (vrrp_sync_group_up(vgroup)) {
+ if (vgroup->state == VRRP_STATE_FAULT) {
+ syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state"
+ , GROUP_NAME(vgroup));
+ notify_group_exec(vgroup, vrrp->init_state);
+ vgroup->state = vrrp->init_state;
+ }
+ } else return;
} else if (IF_ISUP(vrrp->ifp))
syslog(LOG_INFO, "Kernel is reporting: interface %s UP"
, IF_NAME(vrrp->ifp));
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: VRRP synchronization framework.
*
- * Version: $Id: vrrp_sync.c,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_sync.c,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_sync.h"
#include "vrrp_if.h"
+#include "vrrp_notify.h"
#include "data.h"
/* extern global vars */
syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state"
, GROUP_NAME(vgroup));
vgroup->state = VRRP_STATE_MAST;
+ notify_group_exec(vgroup, VRRP_STATE_MAST);
return 1;
}
return 0;
isync->wantstate = VRRP_STATE_BACK;
}
vgroup->state = VRRP_STATE_BACK;
+ notify_group_exec(vgroup, VRRP_STATE_BACK);
}
static void vrrp_sync_master_to(vrrp_rt *vrrp)
}
}
vgroup->state = VRRP_STATE_MAST;
+ notify_group_exec(vgroup, VRRP_STATE_MAST);
}
static void vrrp_sync_fault_to(vrrp_rt *vrrp)
isync->wantstate = VRRP_STATE_GOTO_FAULT;
}
vgroup->state = VRRP_STATE_FAULT;
+ notify_group_exec(vgroup, VRRP_STATE_FAULT);
}
static void vrrp_sync_dmaster_to(vrrp_rt *vrrp)
/* 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)
+ if (GROUP_STATE(vrrp->sync) == VRRP_STATE_BACK)
vrrp_sync_master_to(vrrp);
/* sync the group instance to FAULT state */
*
* Part: vrrp_sync.c include file.
*
- * Version: $Id: vrrp_sync.h,v 0.6.3 2002/06/18 21:39:17 acassen Exp $
+ * Version: $Id: vrrp_sync.h,v 0.6.4 2002/06/25 20:18:34 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*